Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » [SOLVED] Type resolver replies null
[SOLVED] Type resolver replies null [message #1771725] Tue, 29 August 2017 22:25 Go to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 11:55]

Report message to a moderator

Re: Type resolver replies null [message #1771735 is a reply to message #1771725] Wed, 30 August 2017 04:43 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
how does your type computer look like? and/or inferrer?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de

[Updated on: Wed, 30 August 2017 04:53]

Report message to a moderator

Re: Type resolver replies null [message #1771756 is a reply to message #1771735] Wed, 30 August 2017 08:10 Go to previous messageGo to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 08:20 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
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
								]
							}


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Type resolver replies null [message #1771770 is a reply to message #1771758] Wed, 30 August 2017 09:46 Go to previous messageGo to next message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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 10:15 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14661
Registered: July 2009
Senior Member
Simply use Node model?

Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Type resolver replies null [message #1771786 is a reply to message #1771776] Wed, 30 August 2017 11:52 Go to previous message
Stéphane Galland is currently offline Stéphane GallandFriend
Messages: 123
Registered: July 2014
Location: Belfort, France
Senior Member
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: Tue Mar 19 06:40:07 GMT 2024

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

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

Back to the top