I appreciate the features of Jvm-Generation in the final 2.3.0-Version even compared to the 2.3.0-M6 Pre-Release. Great job!
Even in the 5 simple steps you show how nice it is, to produce Generics:
In the DSL it looks like
the DSL rule is
Property: name=ValidID ':' type=JvmTypeReference;
and the generation in the DomainmodelJvmModelInferer looks like
members += feature.toField(feature.name, feature.type)
In this case the generic comes as JvmTypeReference.
My question is: How I can explicitly generate such a type reference within the ModelInferrer? I tried different ways, but did not find one that works. Most times it results in a NullPointer-Exceptions.
1. My first trial:
val myTypeStr = "java.util.EnumSet<" + myEnumSimpleName + ">"
val myType = typeReferences.createTypeRef(typeReferences.findDeclaredType(myTypeStr, e))
var field = e.toField(myFieldName, myType)
members += field
giving in java
JvmType _findDeclaredType = DomainmodelJvmModelInferrer.this.typeReferences.findDeclaredType(myTypeStr, e);
final JvmParameterizedTypeReference myType = DomainmodelJvmModelInferrer.this.typeReferences.createTypeRef(_findDeclaredType);
The second line throws
java.lang.NullPointerException: type
at org.eclipse.xtext.common.types.util.TypeReferences.createTypeRef(TypeReferences.java:100)
2. Then I tried a solution using "typeof" , that can be formulated in xtend
val myType = typesFactory.newTypeRef(typeof(java.lang.Integer))
var field = e.toField(myFieldName, myType)
members += field
This results in error
10 [Worker-4] WARN org.eclipse.xtext.xbase.compiler.JvmModelGenerator - type was null
java.lang.NullPointerException
at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.serialize(JvmModelGenerator.java:1422)
at org.eclipse.xtext.xbase.compiler.JvmModelGenerator._generateMember(JvmModelGenerator.java:529)
at org.eclipse.xtext.xbase.compiler.JvmModelGenerator.generateMember(JvmModelGenerator.java:1531)
A first idea saying with "typeof"
val myType = typesFactory.newTypeRef(typeof(java.util.List<java.lang.Integer>))
var field = e.toField(myFieldName, myType)
members += field
already throws errors in the xtend-Editor.
=> It seems to me, that typesFactory.newTypeRef does not do, what I expect it to do.
3. Creating types workes fine, when using the typesFactory.createJvm... -methods.
But for this task I do not know which one to choose. When looking at JmvModelGenerator it
seems to me that I should come to
generateTypeParameterDeclaration(JvmTypeParameterDeclarator, ITreeAppendable)
that meens, that I have to use
createJvmParameterizedTypeReference().
There are two special variables "arguments" and "types".
=> How to fill them?
(=> And more: How to use them with type constraints?)
There are two different situations, I need a solution for:
A.
I get a "type parameter" as a JvmTypeReference (e.g. Person) from my DSL and want
to apply it to a "generics type" (e.g. List<T>) getting the new "invoked" type
(e.g. List<Person>)
B.
I want to create methods or fields with invoked generics as part of a class or
enumeration. So in the ModelInferrer I act inside
acceptor.accept( e.toClass( e.fullyQualifiedName ) ).initializeLater [
or
acceptor.accept( e.toEnumerationType(enumQualName, null) ).initializeLater [
I wonder, wether the "type parameter" in that moment could be bound to a variable at all,
because everything should be initialized later.
=> If it is possible, how can I do it?
Thanks in advance for your help. Jens