JVM Inferrer -- Possible to generate two declared types that reference each other? [message #1834249] |
Thu, 05 November 2020 14:00  |
Eclipse User |
|
|
|
I need to generate a type with a JVM Inferrer that references another generated type. Apologies in advance for the somewhat contrived example.
Entity E1 has E2,E3 {
field E2 e2;
field E3 e3;
operation void foo() {
e2.bar();
}
}
Entity E2 {
field E1 parent;
operation void bar() {
parent.e3.baz();
}
}
Entity E3 {
field E1 parent;
operation void baz() {
System.out.println("test");
}
}
The corresponding Java code would be something like:
public class E1 {
public E2 e2;
public E3 e3;
pubic E1(){ initialize(); }
private void initialize(){
this.e2 = new E2(this);
this.e3 = new E3(this);
}
public void foo(){
e2.bar();
}
}
public class E2 {
public E1 parent;
public E2(E1 parent){
this.parent = parent;
}
public void bar(){
parent.e3.baz();
}
}
public class E3 {
public E1 parent;
public E3(E1 parent){
this.parent = parent;
}
public void baz(){
System.out.println("test");
}
}
Is this possible? It seems that no matter which order I generate the types (top down or bottom up) I run into issues. It's like a type is a snapshot of an earlier incomplete definition of the referenced type. When I add an XExpression for the operation the "parent" reference resolves fine, but the "e3" reference from parent stops compilation because e3 is missing. However if I comment the expression the classes generate and then the field is present and I can add the expression back and it will compile (although a full clean/build does not succeed).
The JVM Language tutorial sort of hints at this with "Every JvmDeclaredType you create in the model inference needs to be passed to the acceptor in order to get recognized. ... It is important to understand that the creation and assignment of a qualified name is done in an early phase where the compiler collects all global symbols. You cannot resolve type references at this point."
|
|
|
|
|
Re: JVM Inferrer -- Possible to generate two declared types that reference each other? [message #1834254 is a reply to message #1834253] |
Thu, 05 November 2020 16:16   |
Eclipse User |
|
|
|
I'm actually somewhat confused now. I see that I can inject the IQualifiedNameProvider instance like in the JVM Language example, but it looks like the toClass method just calls toString on the QualifiedName. So if I create my own string own string or use the QualifiedName provider the result should be the same right?
public JvmGenericType toClass(/* @Nullable */ EObject sourceElement, /* @Nullable */ QualifiedName name, /* @Nullable */ Procedure1<? super JvmGenericType> initializer) {
return toClass(sourceElement, name != null ? name.toString() : null, initializer);
}
public JvmGenericType toClass(/* @Nullable */ EObject sourceElement, /* @Nullable */ String name, /* @Nullable */ Procedure1<? super JvmGenericType> initializer) {
final JvmGenericType result = createJvmGenericType(sourceElement, name);
if (result == null)
return null;
associate(sourceElement, result);
return initializeSafely(result, initializer);
}
|
|
|
|
|
Re: JVM Inferrer -- Possible to generate two declared types that reference each other? [message #1834827 is a reply to message #1834261] |
Wed, 18 November 2020 11:29  |
Eclipse User |
|
|
|
Thank you all. I just wanted to follow up with what I observed. I worked to simplify my issue I was seeing to the representative example that I showed above. When I went to create a concrete version of the example I used the QualifiedNameProvider (instead of resolving my own type strings) and everything worked. I spent a long time poking around in the XText code around resource sets and noticed that after a type reference was resolved it would fail to find the the type reference and instead would create a new type and then everything would fall apart from there. One thing I did realize was that originally I was not being very careful about what EObject I was mapping to a JVM type and because I was manually resolving crossreferences in the grammar I got a situation where two different EObject instances mapped to one type. Anyway reworking my DSL with QualifiedNameProvider and XText CrossReferences and being careful about each EObject I map to a JVM type fixed my issue.
|
|
|
Powered by
FUDForum. Page generated in 0.05616 seconds