Bug 452517 - [Xtext] Linker re-clears resolved references if they do have eopposite references
Summary: [Xtext] Linker re-clears resolved references if they do have eopposite refere...
Status: NEW
Alias: None
Product: TMF
Classification: Modeling
Component: Xtext (show other bugs)
Version: 2.7.0   Edit
Hardware: All All
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Project Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-11-20 10:05 EST by Christian Schneider CLA
Modified: 2014-11-24 09:29 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Christian Schneider CLA 2014-11-20 10:05:40 EST
The method 'ensureModelLinked(...)' in 'Linker' clears all references of an EObject
regardless the fact that those reference represent eOpposite of others.
This way reference of already linked EObjects may be cleared again, since those eOpposites are usually not mentioned in the grammar.

Instead of:

protected void ensureModelLinked(EObject model, final IDiagnosticProducer producer) {
  boolean clearAllReferencesRequired = isClearAllReferencesRequired(model.eResource());
  TreeIterator<EObject> iterator = getAllLinkableContents(model);
  while(iterator.hasNext()) {
    EObject next = iterator.next();
    if (clearAllReferencesRequired) {
      clearReferences(next);
    }
    ensureLinked(next, producer);
  }
}

we suggest:

protected void ensureModelLinked(EObject model, final IDiagnosticProducer producer) {
    boolean clearAllReferencesRequired = isClearAllReferencesRequired(model.eResource());
    TreeIterator<EObject> iterator = getAllLinkableContents(model);

    // first clear all (possibly invalid) references
    if (clearAllReferencesRequired) {
        while (iterator.hasNext()) {
            clearReferences(iterator.next());
        }
    }

    // re-link
    iterator = getAllLinkableContents(model);
    while (iterator.hasNext()) {
        ensureLinked(iterator.next(), producer);
    }
}
Comment 1 Sven Efftinge CLA 2014-11-21 03:30:10 EST
That would mean iterate over the tree twice for everyone although eOpposites are 
rarely used with Xtext (as it is problematic anyway).
Can't you just subclass and override ensureModelLinked for your specific language?
Comment 2 Christian Schneider CLA 2014-11-21 08:39:10 EST
Of course we could do that, right now we've overriden 'isClearAllReferencesRequired(...)'
like you did for the Xtext language.

However, in order to improve this situation in general,
what do you think about adding a further check in
'AbstractCleaningLinker#cleareReference(EObject, EReference)' like

'(ref.getEOpposite == null || !<<isAssignedInGrammar>>(ref.getEOpposite))'

<<isAssignedInGrammar>> denotes a function that checks the assignment of
the given EReference in the current grammar.

Btw. you can discuss this with Miro as some of
his main artifacts are affected by this change ;-)
Comment 3 Sven Efftinge CLA 2014-11-24 09:29:46 EST
Reducing the severity as subclassing the linking solves your problem.
I don't like adding specific code to make bi-directional references work a "bit better", as there seem to be other issues anyway. At least when they go across two resources. Also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=282486

What is the reason you are having bi-directional references? Do you reuse an existing ecore model?