On a previous page we discussed the code generator for a general grammar, on this page we discuss how code is generated for xbase.
Here is a quick overview from the language implementers point of view. The Model Inferrer maps the grammar to the generated java code.
In the example below it is the code on the bottom right.
Lets look, in more detail, at how we generate code from our model. In a non-xbase situation the code is generated directly by the user source code. With xbase there is much more indirection and we don't specify the code directly. It can be much more difficult to see whats going on so lets try to investigate.
In our project, in subdirectory 'jvmmodel', we create a class called say: MyJvmModelInferrer which extends AbstractModelInferrer. I have put my full code on github here but for now lets loot at the bit that generates the class:
I have hi-lighted the 'toClass' method in red. How does this get all the information about the class and put it all together to generate the code? The code, inside the closure (in the square brackets - which extends JvmGenericType), sets various variables such as:
Are there more variables needed to specify options of the class? Where are these options defined? How are they used? |
/** * pck = package name (qualified name) */ def void buildClass(IJvmDeclaredTypeAcceptor acceptor, EuclidClass ec,String pck){ var String qualifiedName = ec.name //ec.fullyQualifiedName.lastSegment if (pck != null){ qualifiedName = pck + "." + ec.name //ec.fullyQualifiedName.lastSegment } acceptor.accept(ec.toClass(qualifiedName)).initializeLater [ documentation = ec.documentation var JvmParameterizedTypeReference ext = ec.getExtends() if (ext!=null && superTypes!=null) { superTypes += ext.cloneWithProxies } var EList |
In order to attempt to understand these issues lets look at the toClass method below (on the left). We still have not got to the part that actually generates the code. There is yet another indirection to the JvmModelGenerator.xtend method before any code is generated (below right).
The code for 'class' is declared by 'toClass' which is in 'jvmmodel/JvmTypesBuilder' . | The code for 'class' is generated by 'generateBody' which is in 'compiler/JvmModelGenerator.xtend' . |
/** * Creates a public class declaration, associated to the given sourceElement. It sets the given name, which might be * fully qualified using the standard Java notation. * * @param sourceElement * the sourceElement the resulting element is associated with. * @param name * the qualified name of the resulting class. * @param initializer * the initializer to apply on the created class element. If |
So how does all this indirection work?
Where do parameters like the following come from?
Need to understand openScope and closeScope.
I think the reason for all this complexity is that we want this to fit into an ecore model of the JVM which is in : org.eclipse.xtext.common.types.
So it appears that a 'class' is represented in the model by JvmGenericType which has elements:
It also inherits from JvmDeclaredType which has elements:
We might also have:
inherited from JvmMember. So now we know where these elements in our 'toClass' closure come from but it is still far from clear to me how all these things are linked up? It all appears very messy to me. |
|
We extend AbstractModelInferrer which has one method: infer
see this page
see this page
Below is an attempt to redraw the above common.types model in a more readable format, but it is only a start.
Here are some methods of JvmTypesBuilder that generate code.
method | returns | elements | |
---|---|---|---|
toClass | JvmGenericType |
The following are inherited from JvmDeclaredType
The following are inherited from JvmTypeParameterDeclarator
|
|
toInterface | |||
toAnnotationType | JvmAnnotationType | extends JvmDeclaredType
|
|
toEnumerationType | JvmEnumerationType |
plus JvmDeclaredType (see above) |
|
toEnumerationLiteral | JvmEnumerationLiteral |
plus JvmField (see below) |
|
toField | JvmField |
Plus JvmFeature
|
|
toSetter | JvmOperation |
|
|
toGetter | |||
toMethod | |||
toToStringMethod | |||
toHashCodeMethod | |||
toEqualsMethod | |||
toParameter | JvmFormalParameter |
|
|
toConstructor | JvmConstructor | extends JvmExecutable
|
|
toAnnotation | JvmAnnotationReference |
|
|
cloneAndAssociate | <T extends EObject>T | ||
cloneWithProxies | JvmTypeReference |
|
|
newObjectReference | |||
newTypeRef | |||
addArrayTypeDimension |
parametrers of JvmTypesBuilder
get and set:
set only:
set/get parameters:
EList
EList
boolean isAbstract();
void setAbstract(boolean value);
boolean isStatic();
void setStatic(boolean value);
boolean isFinal();
void setFinal(boolean value);
String getPackageName();
void setPackageName(String value);
Iterable
Iterable
Iterable
Iterable
metadata block |
|
see also: |
|
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.