Reuse Java Code of Inferred Xbase in Another IGenerator [message #1781662] |
Sun, 11 February 2018 09:19  |
Eclipse User |
|
|
|
Dear all,
I integrated XClosure into my DSL to allow Java-like Expressions and Java Method Invocations. However, the desired result of the generation process is not Java but another DSL.
Therefore, I created and bound a IGenerator2 implementation which first delegates to the Xbase JvmModelGenerator and afterwards delegates to the actual MyDslGenerator. Based on the MyDslJvmModelInferrer, the JvmModelGenerator generates Java files into src-gen.
I'm wondering if and how I can access these Java files in the second generation of MyDslGenerator?
I would like to access them via reflection but I'm struggling with the creation of an instance.
Can I somehow load those classes with a ClassLoader and invoke Class.newInstance()? Or do I have to use something like InMemoryJavaCompiler to create the Class objects first?
Thank you!
|
|
|
|
|
|
Re: Reuse Java Code of Inferred Xbase in Another IGenerator [message #1782065 is a reply to message #1781667] |
Fri, 16 February 2018 12:11   |
Eclipse User |
|
|
|
It's going well so far, thanks again for the support. There's only 1 thing where I'm probably missing something.
For debugging purposes, I wanted to serialize the Model after it was inferred and interpreted. However, it turns out that attempting to save the inferred model leads to a runtime exception: The root of the exception is generateFile / resource.save(null).
java.lang.RuntimeException: No EObjectDescription could be found in Scope JvmParameterizedTypeReference.type for JvmGenericType
Semantic Object: Model.features[0]->Feature'v'.type->JvmParameterizedTypeReference
Using the same generateFile method with a Non-Xbase-Model works fine. What am I missing here?
Below you can find a minimal example:
Model:
importSection=XImportSection?
('Enums' ':' customEnums+=CustomEnum*)?
'Features' ':' features+=Feature*;
CustomEnum:
'enum' name=ID
;
Feature:
'val' name=ID ':' type=JvmTypeReference;
public class DomainDslRuntimeModule extends AbstractDomainDslRuntimeModule {
public Class<? extends IGenerator2> bindIGenerator2() {
return DomainDslGenerator.class;
}
}
class DomainDslGenerator implements IGenerator2 {
@Inject Provider<XtextResourceSet> resourceSetProvider
@Inject JvmModelGenerator modelGenerator
override afterGenerate ...
override beforeGenerate ...
override doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
modelGenerator.doGenerate(input, fsa)
val head = input.allContents.filter(Model).head
generateFile(fsa.getURI("transformed-" + input.getURI().lastSegment()), head)
}
def generateFile(URI uri, Model entity) {
val resourceSet = resourceSetProvider.get
val resource = resourceSet.createResource(uri) as XtextResource
resource.contents.add(entity)
resource.save(null)
val outputStream = new ByteArrayOutputStream
resource.doSave(outputStream, null)
}
}
class DomainDslJvmModelInferrer extends AbstractModelInferrer {
@Inject extension JvmTypesBuilder
def dispatch void infer(Model element, IJvmDeclaredTypeAcceptor acceptor, boolean isPreIndexingPhase) {
element.customEnums.forEach [ customEnum |
acceptor.accept( customEnum.toEnumerationType(customEnum.name) )
]
acceptor.accept(element.toClass("MyProgram")) [
element.features.forEach [ feature |
members += feature.toMethod(feature.name, feature.type.cloneWithProxies) [
body = ''' return null;'''
]
]
]
}
}
|
|
|
|
Powered by
FUDForum. Page generated in 0.04411 seconds