LiveScope and new Resources [message #1828391] |
Tue, 09 June 2020 02:36  |
Eclipse User |
|
|
|
Hi,
My DSL generates new DSL files when building. These files must be able to refer to already existing DSL-files. For example, if A.dsl compiles, it should generate B.dsl, which has a cross reference to A.dsl.
I should mention, I am talking about building under Eclipse, so not standalone.
I currently do it this way:
- I use the MyDslGenerator generated by Xtext
- XText calls doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) . Let's call the provided resource resource "A".
- My implementation constructs the new EObjects using the EMF factories. Let's call the created EObject "B".
- The new EObjects are added to the ResourceSet of resource A, like this:
//val A a;
//val B b;
val bPath = getPath(b)
val uri = fsa.getURI(bPath, MyOutputConfigurationProvider.OUTPUT_FOLDER)
val rset = a.eResource.resourceSet
res = rset.createResource(uri)
res.contents.add(b)
- then, I serialize B by using the XText Serializer:
//val B b;
val Serializer ser = gsp.findService(b, Serializer)
val content = ser.serialize(b)
fsa.generateFile(bPath, MyOutputConfigurationProvider.OUTPUT_FOLDER, content)
Unfortunately, this does not work, as B does not see A and the serializer can thus not generate the cross-reference from B to A. The Serializer throws a RunTimeException:
java.lang.RuntimeException: No EObjectDescription could be found in Scope <SoAndSo>
EStructuralFeature: commonmetamodel::Import.member
at org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic$ExceptionThrowingAcceptor.accept(ISerializationDiagnostic.java:132)
at org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer.getCrossReferenceNameFromScope(CrossReferenceSerializer.java:139)
at org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer.serializeCrossRef(CrossReferenceSerializer.java:112)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.getToken(SequenceFeeder.java:483)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:240)
Now, what I learned is that I should use LiveScopeResourceSetInitializer in order to allow the target resourceSet (which in my case is the same as the source resourceSet) "see" dirty resources. How is this properly done?
What I tried so far:
1. Just using the A-resourceSet and initializing it using the LiveScopeResourceSetInitializer. This does not work as I get the following exception when running a full build:
java.lang.IllegalStateException: Ambiguous scope for the resource set. Can't combine org.eclipse.xtext.scoping.namespaces.DefaultGlobalScopeProvider.BUILDER_SCOPE and org.eclipse.xtext.scoping.LIVE_SCOPE
2. Creating a new resourceSet (using an IResourceSetProvider) each time my generator is called, initializing the newly created rset (just using the XtextLiveScopeResourceSetProvider works fine, too), and adding all resources from the A-resourceSet to the B-resourceSet.
This approach kinda works, but the performance is really bad. The performance is bad, because in a full build, a new resourceSet is created for every single compiled EObject and the JavaProjectResourceSetInitializer calls EcorePlugin.computePlatformPluginToPlatformResourceMap every time. I can provide the call tree of my profiler, if helpful.
I imagine I am missing something fundamentally. What is the correct way construct my own EObjects in a generator (with incremental and full build)? Do I add add the EObjects to the incoming resourceSet, create a new resourceSet for each built resource (how to tackle the performance issue then?), or do I use a completey different approach?
|
|
|
|
|
|
Re: LiveScope and new Resources [message #1828410 is a reply to message #1828407] |
Tue, 09 June 2020 06:37   |
Eclipse User |
|
|
|
Hi Christian,
That was my second approach (see post above). I basically created a fresh resourceSet every time the generator got called and added the required resources. This worked, but (as it turned out) is incredibly slow when running a FULL_BUILD, as a new resourceSet gets created for every file parsed. Is that a known problem ? Maybe I just use a bad setting?
My DSL Project (that contains the user files, i.e., A and B, not my xtend-sourcecode) has the JavaNature and a plugin dependency to one of my plugins, as I provide some static, "well known" DSL-files through this mechanic. Not sure if this might affect performance.
I uploaded an image of my profiler run here:
https://ibb.co/Lv478w3
As you can see, the performance issue mainly arises as EcorePlugin keeps calculating its computePlatformPluginToPlatformResourceMap , triggered by JavaProjectResourceSetInitializer .
I am trying to resolve this performance issue, as this way a full build takes ~8 min when it should be way under 1 min.
|
|
|
|
|
|
|
Re: LiveScope and new Resources [message #1828449 is a reply to message #1828436] |
Wed, 10 June 2020 02:47   |
Eclipse User |
|
|
|
Hi Christian,
For documentation purposes, I understand there at least the following approaches:
- Creating a new ResourceSet on each Generator Call (so multiple resourceSets on a single full build)
- Creating a new ResourceSet on each Generator Call, but deviate on full builds: create only one resourceSet in this case (not sure how I would achive that)
- <I don't understand your n:1 proposal> Edit: Create a new Generator-Interface that allows to compile multiple Resources at once, as described here:
https://kthoms.wordpress.com/2011/07/12/xtend-generating-from-multiple-input-models/
- Avoid the serializer all together and create text (I chose this approach in a former project, which worked well, but was a bit redundant to the grammar)
- Adapt the serializer (not to check the Scope) -> I guess this will become a bit dirty quickly
Thank you very much for this insight. I thought mayby one of these solution was the clearly prefered way to do it. I think I will first try to stick to option 1 first while trying to tackle the mentioned performance issue. If that fails, I will try to get option 2 working. If that also fails I will use option 4 (text generation), as I know this will work properly.
Many thanks!
[Updated on: Wed, 10 June 2020 07:44] by Moderator
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.06529 seconds