Eclipse Xtext - Cross Linking

On the last page we looked at calling native java code from a DSL. On this page we look at calling the DSL from the java code and other interactions between a DSL and native java code, such as:

Linking within the current DSL file.

As an example lets take the example from the xtext documentation.

I chose this example because it has internal (non-containment) links such as:

  • From 'Feature' to 'Type'
  • From 'Entity' to itself.
    grammar org.example.domainmodel.Domainmodel with
    org.eclipse.xtext.common.Terminals
     
    generate domainmodel
      "http://www.example.org/domainmodel/Domainmodel"
     
    Domainmodel :
       elements += Type*
    ;
    Type:
       DataType | Entity
    ;
    DataType:
      'datatype' name = ID
    ;
    Entity:
      'entity' name = ID ('extends' superType = [Entity])? '{'
      features += Feature*
      '}'
    ;
    Feature:
      many?='many'? name = ID ':' type = [Type]
    ;

This generates the ECore model on the right:

We can see that the two links mentioned are shown as arrows (without a dimond at the start of the arrow).

These represent EReferences in the model.

crosslink

The destination of these EReferences is represented by a name (see naming page).

The source end uses the name (String) to link to the destination.

The runtime code calls getScope(EObject,EReference) (see scoping page) To resolve the connection.

For a complete explanation of how the links are resolved using scoping see example1 on the scoping page.

Calling a DSL from Java Code.

Here is some simple code for my DSL.
// my DSL code
package example2
import java.lang.String

class HelloWorld2 {
	def String getString(String s) {
		(new String("hello ")).concat(s)
	}
}
It is called by this native java code
// user written java code
package example2;
class myJavaCode {
  public static void main(String[] args) {
      HelloWorld2 hw =new HelloWorld2();
      System.out.println(hw.getString("me"));
  }
}

This works fine, provided that we add 'src-gen' to the java build path:

crosslinking

Note 1. I would have liked to replaces the line: (new String("hello ")).concat(s)
with the line: return "hello "+s
but it gave the error:
Couldn't resolve reference to JvmIdentifiableElement '+'.

DSL and User Written Java Code with Circular References

Here the java code depends on (calls) the DSL and the DSL code depends on the java code, like this:

Here is some simple code for my DSL.
// my DSL code
package example3
import example3
import java.lang.String

class HelloWorld3 {
	def String getString(String s) {
		return getString2(s)
	}
}
It is called by this native java code
// user written java code
package example3;
class myJavaCode {
  public static void main(String[] args) {
      HelloWorld3 hw =new HelloWorld3();
      System.out.println(hw.getString("me"));
  }

  public String getString2(String s) {
		return "hello"+s;
	}
}

There is a problem here since the DSL won't generate any java when it has errors and it will have errors because the java code can't link to it. How can we break this loop? One way would be to comment out the link to the java code to allow some java to be generated form the DSL, then remove the comment so that the java code is then correct. However this is messy and not what we would expect users to have to do.

cross linking

Further Reading

Other related pages:

This itemis blog has more information about this topic.


metadata block
see also: itemis blog
Correspondence about this page

This site may have errors. Don't use for critical systems.

Copyright (c) 1998-2023 Martin John Baker - All rights reserved - privacy policy.