I have a hard time figuring out, what am I doing wrong. A simplified example, of what I'm trying to do:
The DSL:
Model: elements += ModelElement*;
ModelElement: Greeting | Person;
Person: 'person' name = ID;
Greeting: 'hello' person = [Person];
The code to serialize a model:
val factory = MyDslFactory.eINSTANCE
val model = factory.createModel
val bob = factory.createPerson
bob.name = "Bob"
val greetBob = factory.createGreeting
greetBob.person = bob
model.elements += bob
model.elements += greetBob
val injector = Guice.createInjector(new MyDslRuntimeModule)
val serializer = injector.getInstance(ISerializer)
// Error happens here:
val result = serializer.serialize(model)
Now when this code runs, the ImportedNamespaceAwareLocalScopeProvider
kicks in, and throws the following exception:
java.lang.NullPointerException
at org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.getResourceScope(ImportedNamespaceAwareLocalScopeProvider.java:95)
at org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.getScope(ImportedNamespaceAwareLocalScopeProvider.java:89)
at org.eclipse.xtext.scoping.impl.ImportedNamespaceAwareLocalScopeProvider.getScope(ImportedNamespaceAwareLocalScopeProvider.java:87)
at org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.delegateGetScope(AbstractDeclarativeScopeProvider.java:72)
at org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider.getScope(AbstractDeclarativeScopeProvider.java:102)
at org.eclipse.xtext.serializer.tokens.CrossReferenceSerializer.serializeCrossRef(CrossReferenceSerializer.java:84)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.getToken(SequenceFeeder.java:454)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:214)
at test.serializer.MyDslSemanticSequencer.sequence_Greeting(MyDslSemanticSequencer.java:65)
at test.serializer.MyDslSemanticSequencer.createSequence(MyDslSemanticSequencer.java:33)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptEObjectRuleCall(SequenceFeeder.java:299)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.acceptRuleCall(SequenceFeeder.java:325)
at org.eclipse.xtext.serializer.acceptor.SequenceFeeder.accept(SequenceFeeder.java:239)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.accept(BacktrackingSemanticSequencer.java:400)
at org.eclipse.xtext.serializer.sequencer.BacktrackingSemanticSequencer.createSequence(BacktrackingSemanticSequencer.java:449)
at test.serializer.MyDslSemanticSequencer.sequence_Model(MyDslSemanticSequencer.java:75)
at test.serializer.MyDslSemanticSequencer.createSequence(MyDslSemanticSequencer.java:39)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:85)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:108)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:122)
at org.eclipse.xtext.serializer.impl.Serializer.serialize(Serializer.java:51)
at test.generator.MyDslGenerator.doGenerate(MyDslGenerator.java:42)
at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:515)
at org.eclipse.xtext.builder.BuilderParticipant.handleChangedContents(BuilderParticipant.java:505)
at org.eclipse.xtext.builder.BuilderParticipant.doGenerate(BuilderParticipant.java:490)
at org.eclipse.xtext.builder.BuilderParticipant.doBuild(BuilderParticipant.java:259)
at org.eclipse.xtext.builder.BuilderParticipant.build(BuilderParticipant.java:217)
at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant$DeferredBuilderParticipant.build(RegistryBuilderParticipant.java:158)
at org.eclipse.xtext.builder.impl.RegistryBuilderParticipant.build(RegistryBuilderParticipant.java:68)
at org.eclipse.xtext.builder.impl.XtextBuilder.doBuild(XtextBuilder.java:189)
at org.eclipse.xtext.builder.impl.XtextBuilder.incrementalBuild(XtextBuilder.java:167)
at org.eclipse.xtext.builder.impl.XtextBuilder.build(XtextBuilder.java:95)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:734)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:206)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:246)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:299)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:302)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:358)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:381)
at org.eclipse.core.internal.events.AutoBuildJob.doBuild(AutoBuildJob.java:143)
at org.eclipse.core.internal.events.AutoBuildJob.run(AutoBuildJob.java:241)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:54)
Meaning, (i think), that it can't resolve a scope, and the only place, where this could happen is the Greeting
rule's person
reference.
Now if I'm writing a scope provider manually, the reference gets resolved without a problem, and it serializes fine.
class MyDslScopeProvider extends AbstractDeclarativeScopeProvider {
//A dummy scope provider
def scope_Greeting_person(Greeting g, EReference ref) {
val model = g.eContainer as Model
return Scopes.scopeFor(model.elements.filter(Person))
}
}
So my question is:
In an obviously much more complex grammar, do I need to write all the individual scope-providers, to make the serialization work? Or is there some configuration option, that I'm missing?
what about adding the model to a dummy resource