Merge pull request #791 from eclipse/sz/findActualNodeRegression

[NodeModel] Wrong result from findActualNode with actions and fragments
This commit is contained in:
Sebastian Zarnekow 2015-11-09 18:19:32 +01:00
commit e79cfc39e5
4 changed files with 95 additions and 2 deletions

View file

@ -234,8 +234,13 @@ public class NodeModelUtils extends InternalNodeModelUtils {
public static ICompositeNode findActualNodeFor(/* @Nullable */ EObject semanticObject) {
ICompositeNode node = getNode(semanticObject);
if (node != null) {
while (GrammarUtil.containingAssignment(node.getGrammarElement()) == null && node.getParent() != null && !node.getParent().hasDirectSemanticElement()) {
node = node.getParent();
while(GrammarUtil.containingAssignment(node.getGrammarElement()) == null) {
ICompositeNode parent = node.getParent();
if (parent != null && !parent.hasDirectSemanticElement() && !GrammarUtil.isEObjectFragmentRuleCall(parent.getGrammarElement())) {
node = parent;
} else {
break;
}
}
}
return node;

View file

@ -17,6 +17,7 @@ import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.Assignment;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.Parameter;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.XtextPackage;
@ -198,6 +199,23 @@ public class NodeModelUtilsTest extends AbstractXtextTests {
assertTrue(object instanceof ParserRule);
}
@Test public void testFindActualNode_01() throws Exception {
String grammarString = "grammar foo.Bar with org.eclipse.xtext.common.Terminals generate foo 'bar' Model<Param>:name=ID;";
Grammar grammar = (Grammar) getModel(grammarString);
ParserRule rule = (ParserRule) grammar.getRules().get(0);
Parameter parameter = rule.getParameters().get(0);
ICompositeNode node = NodeModelUtils.findActualNodeFor(parameter);
assertEquals("Param", node.getText());
}
@Test public void testFindActualNode_02() throws Exception {
String grammarString = "grammar foo.Bar with org.eclipse.xtext.common.Terminals generate foo 'bar' Model<Param>:name=ID;";
Grammar grammar = (Grammar) getModel(grammarString);
ParserRule rule = (ParserRule) grammar.getRules().get(0);
ICompositeNode node = NodeModelUtils.findActualNodeFor(rule);
assertEquals(" Model<Param>:name=ID;", node.getText());
}
@Test public void testCompactDump_1() throws Exception {
String grammarString = "grammar foo.Bar with org.eclipse.xtext.common.Terminals generate foo 'bar' Model:name=ID;";
Grammar grammar = (Grammar) getModel(grammarString);

View file

@ -18,6 +18,7 @@ import org.eclipse.xtext.parser.fragments.fragmentTestLanguage.ParserRuleFragmen
import org.eclipse.xtext.resource.XtextResource
import org.junit.Test
import org.junit.Ignore
import org.eclipse.xtext.nodemodel.util.NodeModelUtils
/**
* @author Sebastian Zarnekow - Initial contribution and API
@ -193,6 +194,50 @@ abstract class AbstractFragmentsTest extends AbstractXtextTests {
assertEquals(fragments.element, fragments.element.ref)
}
@Test
def void testFragmentRecursive_01() {
val fragments = '#10 myName myPrev'.parseAndValidate
assertNotNull(fragments)
assertEquals('myName', fragments.element.name)
val prev = (fragments.element as PRFNamedWithAction).prev
assertEquals('myPrev', prev.name)
val node = NodeModelUtils.findActualNodeFor(prev)
assertEquals(' myPrev', node.text)
}
@Test
def void testFragmentRecursive_02() {
val fragments = '#10 myName ((myPrev))'.parseAndValidate
assertNotNull(fragments)
assertEquals('myName', fragments.element.name)
val prev = (fragments.element as PRFNamedWithAction).prev
assertEquals('myPrev', prev.name)
val node = NodeModelUtils.findActualNodeFor(prev)
assertEquals(' ((myPrev))', node.text)
}
@Test
def void testFragmentRecursive_03() {
val fragments = '#11 myName myPrev'.parseAndValidate
assertNotNull(fragments)
assertEquals('myName', fragments.element.name)
val prev = (fragments.element as PRFNamedWithAction).prev
assertEquals('myPrev', prev.name)
val node = NodeModelUtils.findActualNodeFor(prev)
assertEquals(' myPrev', node.text)
}
@Test
def void testFragmentRecursive_04() {
val fragments = '#11 myName ((myPrev))'.parseAndValidate
assertNotNull(fragments)
assertEquals('myName', fragments.element.name)
val prev = (fragments.element as PRFNamedWithAction).prev
assertEquals('myPrev', prev.name)
val node = NodeModelUtils.findActualNodeFor(prev)
assertEquals('myPrev', node.text)
}
protected def parseAndValidate(CharSequence s) {
val result = s.parse
result.assertNoIssues

View file

@ -19,6 +19,8 @@ ParserRuleFragments: {ParserRuleFragments}
// | '#7' element=PRFNamedWithActionInFragment3
| '#8' element=PRFNamedWithFQN
| '#9' element=PRFWithPredicate
| '#10' element=PRFNamedRecursive
| '#11' element=PRFNamedRecursiveFragment
)
;
@ -28,6 +30,14 @@ PRFNamed: PRFNamedFragment (
)?
;
PRFNamedRecursive returns PRFNamedWithAction:
name=ID RecursiveFromFragment
;
PRFNamedRecursiveFragment returns PRFNamedWithAction:
name=ID RecursiveFragment
;
PRFNamedRefFirst returns PRFNamed:
ref=[PRFNamed] '<-' PRFNamedFragment
;
@ -91,3 +101,18 @@ fragment PRFNamedFragment returns PRFNamed:
fragment PRFNamedRef returns PRFNamed:
ref=[PRFNamed]
;
fragment RecursiveFromFragment returns PRFNamedWithAction:
prev=NamedInParentheses
;
NamedInParentheses returns PRFNamed:
'(' NamedInParentheses ')' | {PRFNamed} name=ID
;
fragment RecursiveFragment returns PRFNamedWithAction:
'(' RecursiveFragment ')' | prev=NamedByAction
;
NamedByAction returns PRFNamed:
{PRFNamed} name=ID
;