Creating Serializer for different DSL [message #1817248] |
Tue, 19 November 2019 09:15 |
Konrad Jünemann Messages: 93 Registered: December 2018 |
Member |
|
|
Hi,
I have 2 DSLs, A and B. (A models business entities, B models database tables).
B elements link to A elements but not the other way around. However, when compiling A elements, B elements should be created.
My approach:
- 1. the A generator creates B elements in memory
- 2. then, the B elements should be serialized (I wrote a custom formatter)
My problem: When I try to serialize the B elements (so step 1 is done), the serializer crashes with the message
java.lang.NullPointerException: Invalid context: A_element returns B_element
I suppose, the wrong serializer is used (which makes sense, cause the Generator is run from the A context, which does not know B, as such the A Injector ist used).
Any idea how I could tackle this problem? Is there a way to create a B-serializer from within the A DSL?
For my Unit-Test, I wrote a special InjectorProvider in order to use both language contexts', something like this:
class MultiDslInjectorProvider extends ADslInjectorProvider {
override protected internalCreateInjector() {
new ADslStandaloneSetup().createInjectorAndDoEMFRegistration
return new BDslStandaloneSetup().createInjectorAndDoEMFRegistration
}
}
Maybe I have to use an injector like this in my non-test code as well?
Bests,
Konrad
|
|
|
|
Re: Creating Serializer for different DSL [message #1817258 is a reply to message #1817249] |
Tue, 19 November 2019 13:18 |
Konrad Jünemann Messages: 93 Registered: December 2018 |
Member |
|
|
Thank you, this works fine. :)
However, I now face a more fundamental problem in my approach:
In order to build my B instances, I ...
1. compile an EMF B model out of my A model. The B elements are linkes with each other.
2. then I serialize the B elements using the default serializer.
This works fine in my unit tests without Eclipse support (so outside the .ui-projects).
However, in Eclipse, I receiver errors when the Serializer tries to serialize cross-references from one B element to another, which might not have been serialized, yet. The problem is, that the referenced object cannot be found in the scope and thus cannot be serialized.
Do you have any hints how I could tackle this problem? I do not fully understand why this happens with Eclipse Support (although I understand that the underlying containers / classpath concept is different), but not when running in standalone, i.e., test.
Any help would be appreciated.
|
|
|
|
|
|
Re: Creating Serializer for different DSL [message #1817273 is a reply to message #1817269] |
Tue, 19 November 2019 17:34 |
Konrad Jünemann Messages: 93 Registered: December 2018 |
Member |
|
|
Yeah, I already checked that. The freshly generated B elements are all present in the rset, with entries like this:
uri='platform:/resource/myProject/tdm/gen/<package>/myBfile.bdsl', org.eclipse.xtext.linking.lazy.LazyLinkingResource@6e85bd12
However, they are not found in the global scope I create for those.
Deeper debugging shows, that a ContainerState is used which refers to an inner JavaProjectsState, as I use the library approach promoted in your book (i.e., the project is a java project and my plugin also provides a libary of well-known B-items).
I guess, from the URI I created for the "virtual" (i.e., not yet serialized) resources, in particular the part platform:/resource/myProject/tdm/gen/ the global scope assumes, that the resources must be contained in the JavaProjectState, which then looks into the mentioned folder, only to find nothing. So the scope does not contain those items.
Is my assumption right? How should the URIs of such "virtual", i.e., not yet generated, resources look like to make them visible under Eclipse?
Best regards!
|
|
|
|
Re: Creating Serializer for different DSL [message #1817275 is a reply to message #1817274] |
Tue, 19 November 2019 18:03 |
Konrad Jünemann Messages: 93 Registered: December 2018 |
Member |
|
|
- I first get an rset which contains all A items
- from these, I create new B items
- for each of these B items, I create a new resource and add it to the rset mentioned above. The code looks as follows:
private def createFile(ResourceSet rset, BItem item) {
val itemPath = item.expectedPath
val res = rset.createResource(URI.createURI("platform:/resource/myProject/tdm/gen/"+itemPath))
res.contents.add(doc)
return res
}
The error message is as follows:
1 [Worker-0: Building workspace] ERROR org.eclipse.xtext.builder.BuilderParticipant - Error during compilation of 'platform:/resource/myProject/AItems/<path>.adsl'.
java.lang.RuntimeException: No EObjectDescription could be found in Scope BItem1.ref for BItem2'<package>'.members[0]->BItem3'<name>'
Semantic Object: BItem2'<package>'.members[0]->BItem3'<name>'.connections[0]->BItem1
URI: platform:/resource/myProject/tdm/gen/<path>/<filename>.bdsl
EStructuralFeature: bmetamodel::BItem1.ref
at org.eclipse.xtext.serializer.diagnostic.ISerializationDiagnostic$ExceptionThrowingAcceptor.accept(ISerializationDiagnostic.java:131)
at org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer.getCrossReferenceNameFromScope(CrossReferenceSerializer.java:138)
at org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer.serializeCrossRef(CrossReferenceSerializer.java:111)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.getToken(SequenceFeeder.java:482)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:245)
[Updated on: Tue, 19 November 2019 18:05] Report message to a moderator
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03876 seconds