mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 16:58:56 +00:00
Merge pull request #791 from eclipse/sz/findActualNodeRegression
[NodeModel] Wrong result from findActualNode with actions and fragments
This commit is contained in:
commit
e79cfc39e5
4 changed files with 95 additions and 2 deletions
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
;
|
||||
|
|
Loading…
Reference in a new issue