eclipse-xtext / eclipse-xtext/xtext

GrammarConstraintProvider seems to provide incorrect constraints

Open
#2,018 16 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug confirmed help_wanted
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.