# Referring to Java Types

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 DSLs. 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 depending on where the client 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 transparently for the clients behind the scenes via different implementations that are bound to specific interfaces by means of Google Guice.

## How to Use Java Types

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 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 (src) 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 (src) will be configured. Don't forget to refer to the genmodel of the Java VM types.

fragment = ecore.EcoreGeneratorFragment { referencedGenModels="classpath:/model/JavaVMTypes.genmodel" } fragment = types.TypesGeneratorFragment {}

After regenerating your language, it will be allowed to define a type Date that maps to the 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.

## Customization Points

There are several customization hooks in the runtime layer and on the editor side as well:

The AbstractTypeScopeProvider (src) can be used to create scopes for members with respect to the override semantics of the Java language. Of course it is possible to use this implementation to create scopes for types as well.

As the Java VM types expose a lot of information about visibility, parameter- and return types, generics, available annotations or enumeration literals, it is very easy to define constraints for the referred types.

The ITypesProposalProvider (src) can be used to provide optimized proposals based on various filter criteria. The most common selector can be used directly via createSubTypeProposals(..). The implementation is optimized and uses the JDT Index directly to minimize the effort for object instantiation. The class TypeMatchFilters (src) provides a comprehensive set of reusable filters that can be easily combined to reduce the list of proposals to a smaller number of valid entries.

import static org.eclipse.xtext.common.types.xtext.ui.TypeMatchFilters; // .. proposalProvider.createSubTypeProposals( superType, factory, context, MyDslPackage.Literals.TYPE__MAPPED_TO, TypeMatchFilters.and( TypeMatchFilters.not( TypeMatchFilters.canInstantiate() ), TypeMatchFilters.isPublic() ), acceptor);