mirror of
https://github.com/sigmasternchen/xtext-core
synced 2025-03-16 08:48:55 +00:00
[263773] Fixed bug related to fragments in OverriddenValueInspector
This commit is contained in:
parent
98ee036c02
commit
602e351922
2 changed files with 99 additions and 3 deletions
|
@ -19,6 +19,7 @@ import org.eclipse.xtext.Assignment;
|
|||
import org.eclipse.xtext.CompoundElement;
|
||||
import org.eclipse.xtext.EnumRule;
|
||||
import org.eclipse.xtext.GrammarUtil;
|
||||
import org.eclipse.xtext.Keyword;
|
||||
import org.eclipse.xtext.ParserRule;
|
||||
import org.eclipse.xtext.RuleCall;
|
||||
import org.eclipse.xtext.TerminalRule;
|
||||
|
@ -91,6 +92,9 @@ public class OverriddenValueInspector extends XtextRuleInspector<Boolean, Parser
|
|||
|
||||
@Override
|
||||
public Boolean caseAction(Action object) {
|
||||
if (!fragmentStack.isEmpty()) {
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
assignedFeatures = newMultimap();
|
||||
if (GrammarUtil.isMultipleAssignment(object))
|
||||
return null;
|
||||
|
@ -187,10 +191,13 @@ public class OverriddenValueInspector extends XtextRuleInspector<Boolean, Parser
|
|||
Multimap<String, AbstractElement> mergedAssignedFeatures = LinkedHashMultimap.create();
|
||||
Set<AbstractRule> prevPermanentlyVisited = permanentlyVisited;
|
||||
Set<AbstractRule> mergedPermanentlyVisited = Sets.newHashSet();
|
||||
boolean allAborted = true;
|
||||
for (AbstractElement element : object.getElements()) {
|
||||
assignedFeatures = newMultimap(prevAssignedFeatures);
|
||||
permanentlyVisited = Sets.newHashSet(prevPermanentlyVisited);
|
||||
doSwitch(element);
|
||||
if (!doSwitch(element)) {
|
||||
allAborted = false;
|
||||
}
|
||||
mergedAssignedFeatures.putAll(assignedFeatures);
|
||||
mergedPermanentlyVisited.addAll(prevPermanentlyVisited);
|
||||
}
|
||||
|
@ -198,7 +205,7 @@ public class OverriddenValueInspector extends XtextRuleInspector<Boolean, Parser
|
|||
mergedAssignedFeatures.putAll(prevAssignedFeatures);
|
||||
}
|
||||
assignedFeatures = mergedAssignedFeatures;
|
||||
if (GrammarUtil.isMultipleCardinality(object)) {
|
||||
if (!allAborted && GrammarUtil.isMultipleCardinality(object)) {
|
||||
prevAssignedFeatures = assignedFeatures;
|
||||
for (AbstractElement element : object.getElements()) {
|
||||
assignedFeatures = newMultimap(prevAssignedFeatures);
|
||||
|
@ -215,12 +222,21 @@ public class OverriddenValueInspector extends XtextRuleInspector<Boolean, Parser
|
|||
private Multimap<String, AbstractElement> newMultimap(Multimap<String, AbstractElement> from) {
|
||||
return LinkedHashMultimap.create(from);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean caseAbstractElement(AbstractElement object) {
|
||||
return Boolean.FALSE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean caseCompoundElement(CompoundElement object) {
|
||||
Multimap<String, AbstractElement> prevAssignedFeatures = newMultimap(assignedFeatures);
|
||||
for (AbstractElement element : object.getElements()) {
|
||||
doSwitch(element);
|
||||
if (doSwitch(element)) {
|
||||
if (GrammarUtil.isOptionalCardinality(object))
|
||||
assignedFeatures.putAll(prevAssignedFeatures);
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
}
|
||||
if (GrammarUtil.isMultipleCardinality(object)) {
|
||||
for (AbstractElement element : object.getElements()) {
|
||||
|
|
|
@ -119,6 +119,86 @@ class OverriddenValueInspectorTest extends AbstractXtextRuleInspectorTest<Boolea
|
|||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
}
|
||||
|
||||
@Test def void testFragment_07() throws Exception {
|
||||
var String grammarAsString = '''
|
||||
grammar org.foo with org.eclipse.xtext.common.Terminals
|
||||
generate metamodel 'foo.sample'
|
||||
EntryRule:
|
||||
name=ID FragmentWithAction
|
||||
;
|
||||
fragment FragmentWithAction returns EntryRule:
|
||||
{EntryRule.prev=current} name=ID
|
||||
;
|
||||
'''
|
||||
val grammar = getGrammar(grammarAsString)
|
||||
val rule = GrammarUtil.findRuleForName(grammar, "EntryRule") as ParserRule
|
||||
rule.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
val fragment = GrammarUtil.findRuleForName(grammar, "FragmentWithAction") as ParserRule
|
||||
fragment.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
}
|
||||
|
||||
@Test def void testFragment_08() throws Exception {
|
||||
var String grammarAsString = '''
|
||||
grammar org.foo with org.eclipse.xtext.common.Terminals
|
||||
generate metamodel 'foo.sample'
|
||||
EntryRule:
|
||||
name=ID FragmentWithAction
|
||||
;
|
||||
fragment FragmentWithAction returns EntryRule:
|
||||
name=ID {EntryRule.prev=current} name=ID
|
||||
;
|
||||
'''
|
||||
val grammar = getGrammar(grammarAsString)
|
||||
val rule = GrammarUtil.findRuleForName(grammar, "EntryRule") as ParserRule
|
||||
rule.validateRule
|
||||
assertEquals(warnings.toString(), 2, warnings.size())
|
||||
val fragment = GrammarUtil.findRuleForName(grammar, "FragmentWithAction") as ParserRule
|
||||
fragment.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
}
|
||||
|
||||
@Test def void testFragment_09() throws Exception {
|
||||
var String grammarAsString = '''
|
||||
grammar org.foo with org.eclipse.xtext.common.Terminals
|
||||
generate metamodel 'foo.sample'
|
||||
EntryRule:
|
||||
name=ID FragmentWithAction
|
||||
;
|
||||
fragment FragmentWithAction returns EntryRule:
|
||||
name=ID {EntryRule.prev=current}
|
||||
;
|
||||
'''
|
||||
val grammar = getGrammar(grammarAsString)
|
||||
val rule = GrammarUtil.findRuleForName(grammar, "EntryRule") as ParserRule
|
||||
rule.validateRule
|
||||
assertEquals(warnings.toString(), 2, warnings.size())
|
||||
val fragment = GrammarUtil.findRuleForName(grammar, "FragmentWithAction") as ParserRule
|
||||
fragment.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
}
|
||||
|
||||
@Test def void testFragment_10() throws Exception {
|
||||
var String grammarAsString = '''
|
||||
grammar org.foo with org.eclipse.xtext.common.Terminals
|
||||
generate metamodel 'foo.sample'
|
||||
EntryRule:
|
||||
name=ID FragmentWithAction*
|
||||
;
|
||||
fragment FragmentWithAction returns EntryRule:
|
||||
({EntryRule.prev=current} name=ID)*
|
||||
;
|
||||
'''
|
||||
val grammar = getGrammar(grammarAsString)
|
||||
val rule = GrammarUtil.findRuleForName(grammar, "EntryRule") as ParserRule
|
||||
rule.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
val fragment = GrammarUtil.findRuleForName(grammar, "FragmentWithAction") as ParserRule
|
||||
fragment.validateRule
|
||||
assertEquals(warnings.toString(), 0, warnings.size())
|
||||
}
|
||||
|
||||
@Test def void testBug280011_01() throws Exception {
|
||||
var String grammarAsString = '''
|
||||
grammar org.foo with org.eclipse.xtext.common.Terminals
|
||||
|
|
Loading…
Reference in a new issue