Serialization and concrete syntax validation [message #1738006] |
Thu, 14 July 2016 22:02 |
Ernesto Posse Messages: 438 Registered: March 2011 |
Senior Member |
|
|
Hello. I have a problem with concrete syntax validation during serialization.
I have a grammar based on an existing EMF model which has the following meta-classes:
* AbstractAction
* ActionCode with superType = AbstractAction
* EntryAction with superType = ActionCode
* ExitAction with superType = ActionCode
* TransitionAction with superType = ActionCode
* GuardAction with superType = ActionCode
* ActionReference with superType = AbstractAction
My grammar has the following rules:
AbstractEntryAction returns AbstractAction:
EntryAction | ActionReference
;
AbstractExitAction returns AbstractAction:
ExitAction | ActionReference
;
AbstractGuardAction returns AbstractAction:
GuardAction | ActionReference
;
AbstractTransitionAction returns AbstractAction:
TransitionAction | ActionReference
;
ActionReference returns ActionReference:
{ActionReference}
'actionref' (target=[AbstractAction|QualifiedName])?
;
EntryAction returns EntryAction:
{EntryAction}
source=EString
;
ExitAction returns ExitAction:
{ExitAction}
source=EString
;
GuardAction returns GuardAction:
{GuardAction}
source=EString
;
TransitionAction returns TransitionAction:
{TransitionAction}
source=EString
;
OperationCode returns ActionCode:
{ActionCode}
source=EString
;
which are called from other rules.
Now I have a model which was not created by parsing but I'm trying to serialize with this grammar, but serialization fails with the errors below:
org.eclipse.e4.core.di.InjectionException: org.eclipse.xtext.validation.IConcreteSyntaxValidator$InvalidConcreteSyntaxException: These errors need to be fixed before the model can be serialized.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionCode is needed instead of EntryAction for serialization with rule OperationCode.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionReference or ExitAction is needed instead of EntryAction for serialization with rule AbstractExitAction.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type ActionReference or TransitionAction is needed instead of EntryAction for serialization with rule AbstractTransitionAction.
RTModel'PingPong'.entities[1]->Capsule'Pinger'.behaviour->StateMachine'Pinger_SM'.top->CompositeState'top'.substates[0]->SimpleState'Running'.entryAction->EntryAction'onEntry': An object of type GuardAction or ActionReference is needed instead of EntryAction for serialization with rule AbstractGuardAction.
I stepped through the validator, and found that in ConcreteSyntaxValidator.validateObject, one of the first things is to obtain the constraints for the relevant EClass (calling constraintProvider.getConstraints(obj.eClass())), and this method does the following:
for (ParserRule r : getValidRules()) {
if (((EClass) r.getType().getClassifier()).isSuperTypeOf(cls)) {
ISyntaxConstraint e = getConstraint(r);
if (e != null)
eles.add(e);
else {
eles.clear();
break;
}
}
}
type2Elements.put(cls, eles);
So it will associate a given EClass cls, to the list of *all* rules whose type is a superType of cls.
In my case, this means that for an EObject of type EntryAction, that table will contain all rules whose type is a superType of EntryAction, including, for example, the 'OperationCode' rule. Then, when this rule is being validated (#validateRule) it fails, because
'collectUnfulfilledSemanticElements(obj.eClass(), rule);' returns more than one element, and this is because the ISyntaxConstraint for that rule has 'ActionCode' as the semantic type and it does not include 'EntryAction' as a semantic type.
So, a couple of questions:
1) why does 'getConstraints' add the constraints for *all* the rules whose type is a super-type of the EClass?
2) how can this error be addressed? defining a custom IConcreteSyntaxValidator or a custom IConcreteSyntaxConstraintProvider? or is there a simpler way?
Thanks
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.03633 seconds