eclipse-xtext / eclipse-xtext/xtext
GrammarConstraintProvider seems to provide incorrect constraints
Nobody has claimed this yet.
- Dominant language
- Java
- Stars
- 831
- Forks
- 330
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 12
Description
I have a somewhat strange situation. Assuming a meta-model where Elements can have any number of Comments and Annotations contained in them, e.g. :
abstract class Element {
property comment : Comment[*] { ordered composes };
property annotation : Annotation[*] { ordered composes };
}
Other elements inherit these properties e.g. SimpleDataType extends Element and StructuredDataType extends Element { ... } where StructuredDataType has additional properties.
The grammar utilises fragments to reuse the rules for the inherited properties, e.g.
fragment AnnotationCommentFragment returns Element:
(comment+=Comment)*
(annotation+=Annotation)*
;
which are then used in the respective rules:
SimpleDataType_Impl returns tdl::SimpleDataType:
AnnotationCommentFragment
'Type' name=Identifier
;
//...
StructuredDataType returns tdl::StructuredDataType:
AnnotationCommentFragment
'Type' name=Identifier
LParen (member+=Member (',' member+=Member)*)? RParen
;
The editor works as expected. The problem occurs when trying to serialise a model, loaded from XMI for example, into the textual representation defined by the grammar.
Looking into the constraints within createSequence(ISerializationContext context, EObject obj) in BacktrackingSemanticSequencer, for some reason some of the constraints, e.g. for SimpleDataType are correct:
with the many property set to true, whereas others, e.g. for StructuredDataType for some reason are incorrect:
AnnotationCommentFragment_ConstraintFragment_StructuredDataType_StructuredDataType returns StructuredDataType: (
comment+=Comment*
annotation+=Annotation?
...
with the many property set to false. That is particularly strange as the rules are also linked in the constraints and there the cardinalities are correct. To make things even more interesting, it turns out that there is a second constraint
AnnotationCommentFragment_ConstraintFragment_StructuredDataType_StructuredDataType returns StructuredDataType: (
comment+=Comment*
annotation+=Annotation*
...
which is correct, the difference being the context - in the former case, the parent is the super class, where as in the latter (and correct) case, it is StructuredDataType. During the serialisation, apparently the former is used. Instead for SimpleDataType, both contexts (super class and subclass) are assigned to the same constraint.
Digging a bit deeper, suggests that different NDAs and potentially also corresponding PDAs are produced instead of a single one unifying the contexts for the super and subclasses.
Any ideas how that comes about and what could be done about it? I will try to put together an isolated replication kit, but there are quite a few moving parts that may be tricky to separate in a neat way..
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at createSequence(ISerializationContext context, EObject obj) in BacktrackingSemanticSequencer and inspect how constraints are selected for SimpleDataType and StructuredDataType. Compare the super-class and subclass contexts, including their many cardinalities and the reported NDA/PDA behavior. Done means identifying the cause and ensuring serialization uses the correct constraints for inherited grammar fragments.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100