mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
[formatter/textRegions] fixed some IllegalStateExceptions
see https://bugs.eclipse.org/bugs/show_bug.cgi?id=485118 Signed-off-by: Moritz Eysholdt <moritz.eysholdt@typefox.io>
This commit is contained in:
parent
2560e8f3f7
commit
1cdd0ab042
3 changed files with 132 additions and 4 deletions
|
@ -96,8 +96,7 @@ public class NodeModelBasedRegionAccessBuilder {
|
|||
return true;
|
||||
} else if (node instanceof ICompositeNode) {
|
||||
EObject element = node.getGrammarElement();
|
||||
return GrammarUtil.isDatatypeRuleCall(element) || element instanceof CrossReference
|
||||
|| GrammarUtil.isEnumRuleCall(element);
|
||||
return GrammarUtil.isDatatypeRuleCall(element) || element instanceof CrossReference || GrammarUtil.isEnumRuleCall(element);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -113,6 +112,8 @@ public class NodeModelBasedRegionAccessBuilder {
|
|||
protected boolean isEObjectRoot(INode node) {
|
||||
if (node instanceof ICompositeNode) {
|
||||
ICompositeNode parent = node.getParent();
|
||||
while (parent != null && GrammarUtil.isEObjectFragmentRuleCall(parent.getGrammarElement()))
|
||||
parent = parent.getParent();
|
||||
if (parent == null)
|
||||
return true;
|
||||
INode root = parent;
|
||||
|
@ -121,7 +122,7 @@ public class NodeModelBasedRegionAccessBuilder {
|
|||
if (root == null)
|
||||
return false;
|
||||
EObject element = node.getGrammarElement();
|
||||
if (GrammarUtil.isEObjectRuleCall(element)) {
|
||||
if (GrammarUtil.isEObjectRuleCall(element) && !GrammarUtil.isEObjectFragmentRuleCall(element)) {
|
||||
if (!parent.hasDirectSemanticElement())
|
||||
return false;
|
||||
BidiTreeIterator<INode> iterator = node.getAsTreeIterable().iterator();
|
||||
|
|
|
@ -491,6 +491,130 @@ class RegionAccessBuilderTest {
|
|||
18 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
@Test def void testFragmentID() {
|
||||
'''
|
||||
6 (fragment foo)
|
||||
'''.toString.trim === '''
|
||||
0 0 H
|
||||
B Action Root
|
||||
0 1 S "6" Root:'6'
|
||||
1 1 H " " Whitespace:TerminalRule'WS'
|
||||
2 1 S "(" Mixed:'('
|
||||
3 0 H
|
||||
3 8 S "fragment" Mixed:'fragment'
|
||||
11 1 H " " Whitespace:TerminalRule'WS'
|
||||
12 3 S "foo" Fragment:fragName=ID
|
||||
15 0 H
|
||||
15 1 S ")" Mixed:')'
|
||||
E Action Root
|
||||
16 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
@Test def void testFragmentRecursionID() {
|
||||
'''
|
||||
6 (fragment recursion foo)
|
||||
'''.toString.trim === '''
|
||||
0 0 H
|
||||
B Action Root
|
||||
0 1 S "6" Root:'6'
|
||||
1 1 H " " Whitespace:TerminalRule'WS'
|
||||
2 1 S "(" Mixed:'('
|
||||
3 0 H
|
||||
3 8 S "fragment" Mixed:'fragment'
|
||||
11 1 H " " Whitespace:TerminalRule'WS'
|
||||
12 9 S "recur..." Fragment:'recursion'
|
||||
21 1 H " " Whitespace:TerminalRule'WS'
|
||||
22 3 S "foo" Fragment:fragName=ID
|
||||
25 0 H
|
||||
25 1 S ")" Mixed:')'
|
||||
E Action Root
|
||||
26 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
@Test def void testFragmentChildAction() {
|
||||
'''
|
||||
6 (fragment child ())
|
||||
'''.toString.trim === '''
|
||||
0 0 H
|
||||
B Action Root
|
||||
0 1 S "6" Root:'6'
|
||||
1 1 H " " Whitespace:TerminalRule'WS'
|
||||
2 1 S "(" Mixed:'('
|
||||
3 0 H
|
||||
3 8 S "fragment" Mixed:'fragment'
|
||||
11 1 H " " Whitespace:TerminalRule'WS'
|
||||
12 5 S "child" Fragment:'child'
|
||||
17 1 H " " Whitespace:TerminalRule'WS'
|
||||
B Action Fragment:mixed=Mixed path:Action/mixed
|
||||
18 1 S "(" Mixed:'('
|
||||
19 0 H
|
||||
19 1 S ")" Mixed:')'
|
||||
E Action Fragment:mixed=Mixed path:Action/mixed
|
||||
20 0 H
|
||||
20 1 S ")" Mixed:')'
|
||||
E Action Root
|
||||
21 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
@Test def void testFragmentChildID() {
|
||||
'''
|
||||
6 (fragment child (foo))
|
||||
'''.toString.trim === '''
|
||||
0 0 H
|
||||
B Action Root
|
||||
0 1 S "6" Root:'6'
|
||||
1 1 H " " Whitespace:TerminalRule'WS'
|
||||
2 1 S "(" Mixed:'('
|
||||
3 0 H
|
||||
3 8 S "fragment" Mixed:'fragment'
|
||||
11 1 H " " Whitespace:TerminalRule'WS'
|
||||
12 5 S "child" Fragment:'child'
|
||||
17 1 H " " Whitespace:TerminalRule'WS'
|
||||
B Mixed'foo' Fragment:mixed=Mixed path:Action/mixed
|
||||
18 1 S "(" Mixed:'('
|
||||
19 0 H
|
||||
19 3 S "foo" Mixed:name=ID
|
||||
22 0 H
|
||||
22 1 S ")" Mixed:')'
|
||||
E Mixed'foo' Fragment:mixed=Mixed path:Action/mixed
|
||||
23 0 H
|
||||
23 1 S ")" Mixed:')'
|
||||
E Action Root
|
||||
24 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
@Test def void testFragmentRecursionChild() {
|
||||
'''
|
||||
6 (fragment recursion child ())
|
||||
'''.toString.trim === '''
|
||||
0 0 H
|
||||
B Action Root
|
||||
0 1 S "6" Root:'6'
|
||||
1 1 H " " Whitespace:TerminalRule'WS'
|
||||
2 1 S "(" Mixed:'('
|
||||
3 0 H
|
||||
3 8 S "fragment" Mixed:'fragment'
|
||||
11 1 H " " Whitespace:TerminalRule'WS'
|
||||
12 9 S "recur..." Fragment:'recursion'
|
||||
21 1 H " " Whitespace:TerminalRule'WS'
|
||||
22 5 S "child" Fragment:'child'
|
||||
27 1 H " " Whitespace:TerminalRule'WS'
|
||||
B Action Fragment:mixed=Mixed path:Action/mixed
|
||||
28 1 S "(" Mixed:'('
|
||||
29 0 H
|
||||
29 1 S ")" Mixed:')'
|
||||
E Action Fragment:mixed=Mixed path:Action/mixed
|
||||
30 0 H
|
||||
30 1 S ")" Mixed:')'
|
||||
E Action Root
|
||||
31 0 H
|
||||
'''
|
||||
}
|
||||
|
||||
private def ===(CharSequence file, CharSequence expectation) {
|
||||
val exp = expectation.toString
|
||||
|
|
|
@ -44,7 +44,7 @@ Parenthesized returns Expression:
|
|||
Mixed:
|
||||
"("
|
||||
("unassigned" (ID | Datatype))?
|
||||
({Action} |
|
||||
({Action} ("fragment" Fragment)? |
|
||||
Mixed |
|
||||
(name=ID | "child" eobj=Mixed | datatype=Datatype | "ref" ref=[Mixed|ID] | lit=Enum))
|
||||
")"
|
||||
|
@ -52,6 +52,9 @@ Mixed:
|
|||
|
||||
Datatype:
|
||||
"datatype" (Datatype | ID);
|
||||
|
||||
fragment Fragment returns Mixed:
|
||||
fragName=ID | "child" mixed=Mixed | "recursion" Fragment;
|
||||
|
||||
enum Enum:
|
||||
lit1 | lit2;
|
Loading…
Reference in a new issue