Skip to main content



      Home
Home » Modeling » TMF (Xtext) » [SOLVED] Type resolver replies null
[SOLVED] Type resolver replies null [message #1771725] Tue, 29 August 2017 18:25 Go to next message
Eclipse UserFriend
Dear all.

I have defined a default value for my formal parameters. My grammar extends Xtend's grammar with:
@Override 
Parameter returns xtend::XtendParameter:
	{SarlFormalParameter} annotations+=XAnnotation*
	(extension?='extension' annotations+=XAnnotation*)?
	name=ValidID ':' parameterType=JvmTypeReference 
	(   (varArg?='*')
	  | ('=' defaultValue=XExpression))?
;


Let the following DSL code:
interface Example {
  def fct1(param1 : Object = Collections.emptyList)
  def fct2(param2 : boolean = true)
}


In my validator, I checks if the types of the formal parameter and the default value expression are compatible. To do so, I get the type of the default value expression.
LightweightTypeReference fromType = getExpectedType(defaultValue);
if (fromType == null) {
    fromType = getActualType(defaultValue);
}


For the first function fct1, fromType==Object, as expected. But, when the validator is called on the second function fct2, fromType==null.

If I put any feature call to a static function into the default value of param1, the type of the param2 default value is always null. See that the expression in fct1 have an impact on the validation of the expression into fct2 (strange behavior).

If I changed the default value of param1 to a simple expression (as illustrated below), the type of param2's default value becomes fromType=boolean, as expected.
interface Example {
  def fct1(param1 : Object = new Object)
  def fct2(param2 : boolean = true)
}


What is missed in my approach?

Thank you by advance.
Stéphane.

[Updated on: Wed, 30 August 2017 07:55] by Moderator

Re: Type resolver replies null [message #1771735 is a reply to message #1771725] Wed, 30 August 2017 00:43 Go to previous messageGo to next message
Eclipse UserFriend
how does your type computer look like? and/or inferrer?

[Updated on: Wed, 30 August 2017 00:53] by Moderator

Re: Type resolver replies null [message #1771756 is a reply to message #1771735] Wed, 30 August 2017 04:10 Go to previous messageGo to next message
Eclipse UserFriend
Type computer does not contain any specific definition related to the parameter's default value (see https://github.com/sarl/sarl/blob/master/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compilation/typesystem/SARLTypeComputer.java)

The JVM model inferrer generates a field that is initialized with the default value. Then two functions are generated: one with the parameter, and one without.
For example:
def fct(a : int, b : Object = Collections::emptyList) {}

generates to:
private static final Object $DEFAULT_VALUE = Collections.emptyList();
public void fct(int a, Object b) {
}
public final void fct(int a) {
  fct(a, $DEFAULT_VALUE);
}


The generated Java code is always correct.
Nevertheless, the code of the JVM model inferrer is too big to be copied here. In https://github.com/sarl/sarl/blob/master/main/coreplugins/io.sarl.lang/src/io/sarl/lang/compilation/jvmmodel/SARLJvmModelInferrer.java, see lines:
* 2911: the function which generates the list of formal parameters, and the hidden fields.
* 1580: the function that transforms the DSL functions to Java.
* Inside the previous function, between lines 1813 and 1939, the additional function is generated.
Re: Type resolver replies null [message #1771758 is a reply to message #1771756] Wed, 30 August 2017 04:20 Go to previous messageGo to next message
Eclipse UserFriend
hmm i tried to reproduce this with the domain model example but i had no luck.
are you sure you inferr different fields with different names foreach optional param

e.g.

		Operation : {
						for (p : f.params.filter(FullJvmFormalParameter)) {
								members += p.toField(f.name+"_" + p.name+ "_default", p.parameterType) [
									initializer = p.defaultValue
								]
							}
Re: Type resolver replies null [message #1771770 is a reply to message #1771758] Wed, 30 August 2017 05:46 Go to previous messageGo to next message
Eclipse UserFriend
I found that the problem is not related to the field's creation.

Indeed, in order to enable quick fixes, I attach to the field an annotation that contains the DSL code of the default value. This DSL code is used by the quick fix for generating the missed elements.

Let the DSL code:
interface Example {
   def fct1(a : Object = Collections::emptyList)
   def fct2(a : boolean = true)
}


The generated code is:
public interface Example {
   public abstract void fct1(Object a);

   @SarlSourceCode("Collections::emptyList")
   public static final Object $DEFAULTVALUE$FCT1_0 = Collections.emptyList();

   public default void fct1() {
      fct1($DEFAULTVALUE$FCT1_0);
   }

   public abstract void fct2(boolan a);

   @SarlSourceCode("true")
   public static final boolean $DEFAULTVALUE$FCT2_0 = true;

   public default void fct2() {
      fct2($DEFAULTVALUE$FCT2_0);
   }
}


For generating the string value given to the @SarlSourceCode, I uses the following code into my JvmInferrer:
final String rawCode = reentrantSerialize(defaultValue);
appendSarlSourceCodeAnnotation(field, rawCode);


This code tries to generates the SARL code from the XExpression:
	private def String reentrantSerialize(EObject object) {
		var contexts = this.contextFinder.findByContentsAndContainer(object, null);
		// This is a bug fix for a bug that I cannot explain.
		// I some cases, the context of the given expression cannot be retreive directly.
		// A second call to the finding function solves the problem.
		while (contexts == null || contexts.isEmpty()) {
			Thread.yield();
			contexts = this.contextFinder.findByContentsAndContainer(object, null);
		}
		var code = this.sarlSerializer.serialize(object);
		if (code != null) {
			return code.trim();
		}
		return code;
	}


If i do not call the reentrantSerialize function, everything is working at the expected way.

What could be the best solution to obtain the DSL code from the XExpression into the JVM inferrer?

S.
Re: Type resolver replies null [message #1771776 is a reply to message #1771770] Wed, 30 August 2017 06:15 Go to previous messageGo to next message
Eclipse UserFriend
Simply use Node model?
Re: Type resolver replies null [message #1771786 is a reply to message #1771776] Wed, 30 August 2017 07:52 Go to previous message
Eclipse UserFriend
Nice guideline. Thank you.
I have learnt the Xtext node model a long time after I have written this serialization function. And, I did not improve this code. Now, it's done :)

For who want to "serialize" an EObject for obtaining the DSL code:
private def String reentrantSerialize(EObject object) {
	var node = NodeModelUtils::getNode(object)
	if (node !== null) {
		var text = node.text
		if (text !== null) {
			text = text.trim
		}
		return Strings::emptyToNull(text)
	}
	return null
}
Previous Topic:Custom scope for only one Resource [solved]
Next Topic:No GenPackage for NsURI http://www.eclipse.org/emf/2002/Ecore
Goto Forum:
  


Current Time: Wed Jul 23 14:24:23 EDT 2025

Powered by FUDForum. Page generated in 0.05122 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top