diff --git a/plugins/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/grammarAccess/GrammarAccessFragment2.xtend b/plugins/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/grammarAccess/GrammarAccessFragment2.xtend index a3e2d2fec..9c391e48e 100644 --- a/plugins/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/grammarAccess/GrammarAccessFragment2.xtend +++ b/plugins/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/grammarAccess/GrammarAccessFragment2.xtend @@ -191,16 +191,16 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { «ENDFOR» private final «Grammar» grammar; - «FOR g : language.grammar.usedGrammars» + «FOR g : language.grammar.effectivelyUsedGrammars» private final «g.grammarAccess» «g.gaGrammarAccessLocalVarName»; «ENDFOR» @«Inject» - public «language.grammar.grammarAccess.simpleName»(«GrammarProvider» grammarProvider«FOR g : language.grammar.usedGrammars», + public «language.grammar.grammarAccess.simpleName»(«GrammarProvider» grammarProvider«FOR g : language.grammar.effectivelyUsedGrammars», «g.grammarAccess» «g.gaGrammarAccessLocalVarName»«ENDFOR») { this.grammar = internalFindGrammar(grammarProvider); - «FOR g : language.grammar.usedGrammars» + «FOR g : language.grammar.effectivelyUsedGrammars» this.«g.gaGrammarAccessLocalVarName» = «g.gaGrammarAccessLocalVarName»; «ENDFOR» «FOR r : language.grammar.rules» @@ -229,7 +229,7 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { return grammar; } - «FOR g : language.grammar.usedGrammars» + «FOR g : language.grammar.effectivelyUsedGrammars» public «g.grammarAccess» get«g.grammarAccess.simpleName»() { return «g.gaGrammarAccessLocalVarName»; @@ -311,7 +311,7 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { } «ELSE» public «it.grammar.grammarAccess».«gaBaseRuleAccessorClassName» «gaElementsAccessor» { - return «usedGrammar(original).gaGrammarAccessLocalVarName».«gaBaseElementsAccessor»; + return «it.grammar.gaGrammarAccessLocalVarName».«gaBaseElementsAccessor»; } «ENDIF» @@ -328,7 +328,7 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { } «ELSE» public «it.grammar.grammarAccess».«gaRuleAccessorClassName» «gaElementsAccessor» { - return «usedGrammar(original).gaGrammarAccessLocalVarName».«gaElementsAccessor»; + return «it.grammar.gaGrammarAccessLocalVarName».«gaElementsAccessor»; } «ENDIF» @@ -343,7 +343,7 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { «IF it.grammar === original» return «gaRuleAccessorLocalVarName»; «ELSE» - return «usedGrammar(original).gaGrammarAccessLocalVarName».«gaBaseRuleAccessor»; + return «it.grammar.gaGrammarAccessLocalVarName».«gaBaseRuleAccessor»; «ENDIF» } ''' @@ -379,8 +379,11 @@ class GrammarAccessFragment2 extends AbstractXtextGeneratorFragment { "rule" } - protected def Grammar usedGrammar(AbstractRule rule, Grammar parent) { - parent.usedGrammars.findFirst[allRules.contains(rule)] + /** + * Returns all grammars from the hierarchy that are used from rules of this grammar. + */ + protected def getEffectivelyUsedGrammars(Grammar grammar) { + grammar.allRules.map[ GrammarUtil.getGrammar(it) ].filter[ it !== grammar ].toSet.toList } } \ No newline at end of file diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/AnotherInheritanceTest.java b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/AnotherInheritanceTest.java index 6b575d17e..d85d504cb 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/AnotherInheritanceTest.java +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/AnotherInheritanceTest.java @@ -9,6 +9,8 @@ package org.eclipse.xtext.grammarinheritance; import org.eclipse.emf.ecore.EPackage; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.grammarinheritance.ametamodel.AmetamodelPackage; import org.eclipse.xtext.grammarinheritance.services.InheritanceTest2LanguageGrammarAccess; import org.eclipse.xtext.junit4.AbstractXtextTests; @@ -27,6 +29,14 @@ public class AnotherInheritanceTest extends AbstractXtextTests { @Test public void testSimple() throws Exception { InheritanceTest2LanguageGrammarAccess g = (InheritanceTest2LanguageGrammarAccess) getGrammarAccess(); assertNotNull(g.getFQNAccess()); + AbstractRule fromFQN = g.getFQNAccess().getIDTerminalRuleCall_0().getRule(); + assertEquals(fromFQN, g.getIDRule()); assertNotNull(g.getModelAccess()); } + + @Test public void testFQNWithNumbers() throws Exception { + Resource resource = getModelAndExpect("model a { ab.ab01 }", 1).eResource(); + String msg = resource.getErrors().get(0).getMessage(); + assertEquals("extraneous input '01' expecting '}'", msg); + } } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/GenerateInheritanceLanguages.mwe2 b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/GenerateInheritanceLanguages.mwe2 index 54b333ed4..586b3cfc4 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/GenerateInheritanceLanguages.mwe2 +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/GenerateInheritanceLanguages.mwe2 @@ -15,6 +15,7 @@ import org.eclipse.xtext.generator.* var projectName = "org.eclipse.xtext.tests" var runtimeProject = "../${projectName}" var lineDelimiter = '\n' +var encoding = 'ISO-8859-1' Workflow { bean = StandaloneSetup { @@ -44,31 +45,31 @@ Workflow { component = Generator auto-inject { pathRtProject = runtimeProject projectNameRt = projectName - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/AbstractTestLanguage.xtext" fragment = @TestLanguagesFragments { srcGenOnly = false } } - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/BaseInheritanceTestLanguage.xtext" fragment = @TestLanguagesFragments {} } - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/ConcreteTestLanguage.xtext" fragment = @TestLanguagesFragments {} } - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext" fragment = @TestLanguagesFragments { srcGenOnly = false } } - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/InheritanceTest2Language.xtext" fragment = @TestLanguagesFragments {} } - language = { + language = auto-inject { uri = "classpath:/org/eclipse/xtext/grammarinheritance/InheritanceTest3Language.xtext" fragment = @TestLanguagesFragments {} } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTest3Language.xtext b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTest3Language.xtext index d45288d3b..8029eb798 100755 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTest3Language.xtext +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTest3Language.xtext @@ -17,6 +17,7 @@ Model: Element : super::Element | {Element} "element" name=super::ID + | {Element} "element" name=Terminals::ID | {Element} "element" name=super::STRING ; diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext index 91f800af1..9ddd185b0 100755 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext @@ -18,4 +18,6 @@ Model : Element : "element" name=ID -; \ No newline at end of file +; + +terminal ID: ('a'..'z')+; \ No newline at end of file diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/ParserTest.java b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/ParserTest.java index 61c520251..fe433ec65 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/ParserTest.java +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/grammarinheritance/ParserTest.java @@ -67,4 +67,14 @@ public class ParserTest extends AbstractXtextTests { assertTrue(nodesForFeature.size() == 1); assertEquals("'with spaces'", nodesForFeature.get(0).getText()); } + + @Test public void test_05() throws Exception { + Model model = (Model) getModel("model id { element withNumbers01 }"); + assertEquals("id", model.getName()); + Element element = model.getElements().get(0); + assertEquals("withNumbers01", element.getName()); + List nodesForFeature = NodeModelUtils.findNodesForFeature(element, InheritanceTestPackage.Literals.ELEMENT__NAME); + assertTrue(nodesForFeature.size() == 1); + assertEquals("withNumbers01", nodesForFeature.get(0).getText()); + } } diff --git a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/serializer/XtextSerializerTest.java b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/serializer/XtextSerializerTest.java index 82ed2701f..37847d8e0 100644 --- a/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/serializer/XtextSerializerTest.java +++ b/tests/org.eclipse.xtext.tests/src/org/eclipse/xtext/serializer/XtextSerializerTest.java @@ -8,17 +8,27 @@ package org.eclipse.xtext.serializer; import org.eclipse.emf.common.util.URI; +import org.eclipse.xtext.AbstractRule; import org.eclipse.xtext.Grammar; +import org.eclipse.xtext.GrammarUtil; +import org.eclipse.xtext.Group; +import org.eclipse.xtext.RuleCall; +import org.eclipse.xtext.TerminalRule; import org.eclipse.xtext.XtextStandaloneSetup; +import org.eclipse.xtext.common.services.TerminalsGrammarAccess; +import org.eclipse.xtext.grammarinheritance.services.BaseInheritanceTestLanguageGrammarAccess; +import org.eclipse.xtext.grammarinheritance.services.InheritanceTestLanguageGrammarAccess; import org.eclipse.xtext.junit4.AbstractXtextTests; import org.eclipse.xtext.junit4.serializer.SerializerTester; import org.eclipse.xtext.resource.XtextResourceSet; +import org.eclipse.xtext.service.GrammarProvider; import org.eclipse.xtext.services.XtextGrammarAccess; import org.junit.Assert; import org.junit.Ignore; import org.junit.Test; import com.google.inject.Inject; +import com.google.inject.Provider; /** * @author Moritz Eysholdt - Initial contribution and API @@ -62,4 +72,35 @@ public class XtextSerializerTest extends AbstractXtextTests { String string = get(ISerializer.class).serialize(grammarAccess.getGrammarAccess().getGroup_2()); Assert.assertEquals("(\"with\" usedGrammars+=[Grammar|GrammarID] (\",\" usedGrammars+=[Grammar|GrammarID])*)?", string); } + + @Test + public void testFQNInSuper_01() { + GrammarProvider grammarProvider = new GrammarProvider("org.eclipse.xtext.grammarinheritance.InheritanceTestLanguage", new Provider() { + @Override + public XtextResourceSet get() { + return XtextSerializerTest.this.get(XtextResourceSet.class); + } + }); + TerminalsGrammarAccess gaTerminals = new TerminalsGrammarAccess(grammarProvider); + BaseInheritanceTestLanguageGrammarAccess gaBaseInheritanceTestLanguage = new BaseInheritanceTestLanguageGrammarAccess(grammarProvider, gaTerminals); + InheritanceTestLanguageGrammarAccess grammarAccess = new InheritanceTestLanguageGrammarAccess(grammarProvider, gaBaseInheritanceTestLanguage, gaTerminals); + String string = get(ISerializer.class).serialize(grammarAccess.getFQNRule().getAlternatives()); + Assert.assertEquals("ID (\".\" ID)*", string); + } + + @Ignore("Serialization does not have the correct context information") + @Test + public void testFQNInSuper_02() { + Grammar grammar = load(URI.createURI("classpath:/org/eclipse/xtext/grammarinheritance/InheritanceTestLanguage.xtext")); + AbstractRule rule = GrammarUtil.findRuleForName(grammar, "FQN"); + Assert.assertNotNull(rule); + Group group = (Group) rule.getAlternatives(); + RuleCall ruleCall = (RuleCall) group.getElements().get(0); + TerminalRule id = (TerminalRule) ruleCall.getRule(); + Assert.assertSame(grammar, GrammarUtil.getGrammar(id)); + String string = get(ISerializer.class).serialize(rule.getAlternatives()); + Assert.assertEquals("ID (\".\" ID)*", string); + // currently wrong result is + Assert.assertEquals("super::ID (\".\" super::ID)*", string); + } }