diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextLinker.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextLinker.java index 4f9fb39fa..aff633549 100644 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextLinker.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/XtextLinker.java @@ -33,6 +33,7 @@ import org.eclipse.xtext.GeneratedMetamodel; import org.eclipse.xtext.Grammar; import org.eclipse.xtext.GrammarUtil; import org.eclipse.xtext.NamedArgument; +import org.eclipse.xtext.Parameter; import org.eclipse.xtext.ParserRule; import org.eclipse.xtext.ReferencedMetamodel; import org.eclipse.xtext.RuleCall; @@ -409,10 +410,32 @@ public class XtextLinker extends Linker { } final List allRuleCalls = EcoreUtil2.getAllContentsOfType(grammar, RuleCall.class); for (RuleCall call : allRuleCalls) { - if (call.getRule() != null && !call.isExplicitlyCalled()) { - AbstractRule rule = rulePerName.get(call.getRule().getName()); - if (rule != null) + AbstractRule calledRule = call.getRule(); + if (calledRule != null && !call.isExplicitlyCalled()) { + AbstractRule rule = rulePerName.get(calledRule.getName()); + if (rule != null) { call.setRule(rule); + if (!call.getArguments().isEmpty()) { + if (calledRule instanceof ParserRule && rule instanceof ParserRule) { + updateNamedArguments( + call, + ((ParserRule) calledRule).getParameters(), + ((ParserRule) rule).getParameters()); + } + } + } + } + } + } + + private void updateNamedArguments(RuleCall call, List superParams, + List overridingParameters) { + for(NamedArgument argument: call.getArguments()) { + Parameter superParameter = argument.getParameter(); + for(int i = 0, max = Math.min(superParams.size(), overridingParameters.size()); i < max ; i++) { + if (superParams.get(i) == superParameter) { + argument.setParameter(overridingParameters.get(i)); + } } } } diff --git a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformer.java b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformer.java index 3c40372ea..b6b173b17 100755 --- a/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformer.java +++ b/plugins/org.eclipse.xtext/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformer.java @@ -774,14 +774,14 @@ public class Xtext2EcoreTransformer { "Overridden rule " + rule.getName() + " does not declare any parameters", rule); } StringBuilder message = new StringBuilder("Parameter list is incompatible with inherited "); - message.append(rule.getName()).append("["); + message.append(rule.getName()).append("<"); for(int i = 0; i < overridden.getParameters().size(); i++) { if (i != 0) { message.append(", "); } message.append(overridden.getParameters().get(i).getName()); } - message.append("]"); + message.append(">"); throw new TransformationException(TransformationErrorCode.InvalidRuleOverride, message.toString(), rule); } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextLinkerTest.xtend b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextLinkerTest.xtend index c4bea3a6e..c74cc6b06 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextLinkerTest.xtend +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/XtextLinkerTest.xtend @@ -22,6 +22,8 @@ import org.eclipse.xtext.Alternatives import org.eclipse.xtext.Negation import org.eclipse.xtext.ParameterReference import org.eclipse.xtext.LiteralCondition +import org.eclipse.emf.common.util.URI +import org.eclipse.xtext.util.LazyStringInputStream /** * @author Sven Efftinge - Initial contribution and API @@ -98,6 +100,31 @@ class XtextLinkerTest extends AbstractXtextTests { assertFalse((argument.value as LiteralCondition).isTrue) } + @Test def void testNamedParameterAdjustment() throws Exception { + val grammarAsString = ''' + grammar test.Lang with org.eclipse.xtext.common.Terminals + generate test 'http://test' + Root: rule=Rule; + Rule: name=ID child=Root?; + ''' + val grammar = grammarAsString.model as Grammar + val resourceSet = grammar.eResource.resourceSet + val otherResource = resourceSet.createResource(URI.createURI('other.xtext')) + otherResource.load(new LazyStringInputStream(''' + grammar test.SubLang with test.Lang + import 'http://test' + Root: rule=super::Rule; + '''), null) + val subGrammar = otherResource.contents.head as Grammar + val rootRule = subGrammar.rules.head as ParserRule + val parentRule = grammar.rules.last as ParserRule + val lastAssignment = (parentRule.alternatives as Group).elements.last as Assignment + val ruleCall = lastAssignment.terminal as RuleCall + val argument = ruleCall.arguments.head + assertEquals(rootRule.parameters.head, argument.parameter) + assertFalse((argument.value as LiteralCondition).isTrue) + } + @Test def void testExplicitRuleCallsAreTracked() throws Exception { val grammarAsString = ''' grammar test.Lang with org.eclipse.xtext.common.Terminals diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend index 28588ad3a..fd92a9b67 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/ecoreInference/Xtext2EcoreTransformerTest.xtend @@ -1817,12 +1817,10 @@ class Xtext2EcoreTransformerTest extends AbstractXtextTests { var typeD = ePackage.type("TypeD") as EClass assertNotNull(typeD) assertNotNull(typeD.feature("x")) - assertEquals(1, - typeD.features. - size) - } + assertEquals(1, typeD.features.size) + } - @Test def void testBug346685_a05() throws Exception { + @Test def void testBug346685_a05() throws Exception { var String grammar = '''grammar test with org.eclipse.xtext.common.Terminals generate test 'http://test'«»''' grammar += " RuleA returns TypeA: RuleB? ({TypeC.x=current} 'x' | {TypeD.x=current} 'y')? name+=STRING;" grammar += " RuleB returns TypeB: {TypeB} 'ignore';"