Skip to main content



      Home
Home » Modeling » TMF (Xtext) » Reuse Java Code of Inferred Xbase in Another IGenerator
Reuse Java Code of Inferred Xbase in Another IGenerator [message #1781662] Sun, 11 February 2018 09:19 Go to next message
Eclipse UserFriend
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 #1781664 is a reply to message #1781662] Sun, 11 February 2018 09:22 Go to previous messageGo to next message
Eclipse UserFriend
hi, can you please explain what exactly you want to achieve. at the point where the generator runs there are no class files. just text.
jdt will run and create the class files afterwards so no chance to access them during compilation

of course you could do something like InMemoryJavaCompiler does but that is a different usecase
Re: Reuse Java Code of Inferred Xbase in Another IGenerator [message #1781666 is a reply to message #1781664] Sun, 11 February 2018 12:12 Go to previous messageGo to next message
Eclipse UserFriend
Hi Christian,

thanks for your reply - that's what I thought.

Well, the DSL is basically a list of key-value assignments. The idea was to use Xbase expressions in order to integrate "dynamic" values. At the beginning of doGenerate(), all Xbase expressions should be replaced by its computed values. Afterwards, the transformation continues with only static values.

name = "John"
today = [ LocalDate.now.toString ] // Should be replaced by "2018-02-..."
name2 = [ name.toLowerCase ]       // = "john"


Is this a case for XbaseInterpreter then?
Re: Reuse Java Code of Inferred Xbase in Another IGenerator [message #1781667 is a reply to message #1781666] Sun, 11 February 2018 12:16 Go to previous messageGo to next message
Eclipse UserFriend
possibly.
Re: Reuse Java Code of Inferred Xbase in Another IGenerator [message #1782065 is a reply to message #1781667] Fri, 16 February 2018 12:11 Go to previous messageGo to next message
Eclipse UserFriend
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;'''
				]
			]
		]
	}
}
Re: Reuse Java Code of Inferred Xbase in Another IGenerator [message #1782075 is a reply to message #1782065] Fri, 16 February 2018 13:50 Go to previous message
Eclipse UserFriend
(1) this means the scoping is broken to save
(2) inside eclipse yo should use IResourceSetProvider to obtain a resourceset
(3) moving stuff from one resourceset to another breaks scoping

=> maybe you can use resource.save(outputstream,map) on the original resource
Previous Topic:XReturnExpression type deduction in inferrer
Next Topic:Maven generate-sources for two grammars
Goto Forum:
  


Current Time: Wed Jul 23 06:34:43 EDT 2025

Powered by FUDForum. Page generated in 0.06384 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top