A common use case when developing languages is the requirement to refer to existing concepts of other languages. Xtext makes this very easy for other self defined languages. However, it is often very useful to have access to the available types of the Java Virtual Machine. The JVM types Ecore model enables clients to do exactly this. It is possible to create cross-references to classes, interfaces, and their fields and methods. Basically every information about the structural concepts of the Java type system is available via the JVM types. This includes annotations and their specific values and enumeration literals as well.
The implementation will be selected transparently to the client code depending on where the code is executed. If the environment is a plain stand-alone Java or OSGi environment, the java.lang.reflect API will be used to deduce the necessary data. On the contrary, the type-model will be created from the live data of the JDT in an interactive Eclipse environment. All this happens behind the scenes via different implementations that are bound to specific interfaces with Google Guice.
Using the JVM types model is very simple. First of all, the grammar has to import the JavaVMTypes Ecore model. Thanks to content assist this is easy to spot in the list of proposals.
import "http://www.eclipse.org/xtext/common/JavaVMTypes" as types
The next step is to actually refer to an imported concept. Let’s define a mapping to actually available Java types for the simple data types in the self defined language. By means of cross-references this works as one got already used to when dealing with references in Xtext.
Type:
'type' name=ID 'mapped-to' javaType=[types::JvmType|FQN];
Last but not least, the TypesGeneratorFragment has to be added to the workflow. The safest way is to add it after the actually used scoping fragments as a specialized version of the IGlobalScopeProvider will be configured. Don’t forget to refer to the genmodel of the Java VM types. The shortest possible URI is a classpath-URI.
fragment = ecore.EcoreGeneratorFragment {
referencedGenModels="classpath:/model/JavaVMTypes.genmodel"
}
...
// scoping and exporting API
...
fragment = types.TypesGeneratorFragment {}
After regenerating your language, it will be allowed to define a type Date that maps to the java.util.Date like this:
type Date mapped-to java.util.Date
These two steps will provide a nice integration into the Eclipse JDT. There is Find References on Java methods, fields and types that will reveal results in your language files. Go To Declaration works as expected and content assist will propose the list of available types.