[263773] Fixed bug related to fragments in OverriddenValueInspector

This commit is contained in:
Sebastian Zarnekow 2015-08-14 16:05:43 +02:00
parent 98ee036c02
commit 602e351922
2 changed files with 99 additions and 3 deletions

View file

@ -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()) {

View file

@ -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