From 00ff0407b0ad12e200bc52ab198a7c65a14271b4 Mon Sep 17 00:00:00 2001 From: overflowerror Date: Thu, 27 Jan 2022 20:37:07 +0100 Subject: [PATCH] added tests for hoisting specific renders tests predicate rendering in alternatives, in non-trivial cardinalities, and setup block rendering. in both the production grammar and content assist grammar. added debug grammar generators for production grammar and content assist grammar which use DebugGrammarNaming to avoid null-ptr because of missing adapters in ecore objects. (existing AntlrDebugGrammarGenerator can't be used because setup blocks are handled by AntlrGrammarGenerator and AntlrContentAssistGrammarGenerator respectively, not AbstractAntlrGrammarGenerator.) fixed small details in rendered output (removed guard of rule comment and trimmed setup block). --- .../hoisting/HoistingGeneratorTest.xtend | 750 ++++++++ .../hoisting/HoistingGeneratorTest.java | 1612 +++++++++++++++++ .../antlr/AbstractAntlrGrammarGenerator.xtend | 2 +- ...tlrDebugContentAssistGrammarGenerator.java | 28 + .../AntlrDebugProductionGrammarGenerator.java | 28 + .../generator/parser/antlr/JavaCodeUtils.java | 2 +- .../antlr/hoisting/guards/PredicateGuard.java | 4 +- .../antlr/AbstractAntlrGrammarGenerator.java | 2 +- 8 files changed, 2423 insertions(+), 5 deletions(-) create mode 100644 org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.xtend create mode 100644 org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.java create mode 100644 org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugContentAssistGrammarGenerator.java create mode 100644 org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugProductionGrammarGenerator.java diff --git a/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.xtend b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.xtend new file mode 100644 index 000000000..1f58ba950 --- /dev/null +++ b/org.eclipse.xtext.tests/src/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.xtend @@ -0,0 +1,750 @@ +/******************************************************************************* + * Copyright (c) 2022 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + *******************************************************************************/ +package org.eclipse.xtext.xtext.generator.hoisting + +import org.eclipse.xtext.tests.AbstractXtextTests +import org.eclipse.xtext.XtextStandaloneSetup +import org.junit.Test +import org.eclipse.xtext.Grammar +import org.eclipse.xtext.xtext.generator.DefaultGeneratorModule +import com.google.inject.Guice +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrOptions +import org.eclipse.xtext.generator.InMemoryFileSystemAccess +import org.eclipse.xtext.xtext.generator.model.IXtextGeneratorFileSystemAccess +import com.google.inject.Injector +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrDebugProductionGrammarGenerator +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrDebugContentAssistGrammarGenerator + +/** + * @author overflow - Initial contribution and API + */ +class HoistingGeneratorTest extends AbstractXtextTests { + + override void setUp() throws Exception { + super.setUp() + with(XtextStandaloneSetup) + } + + @Test + def void testRenderingOfGuardConditionInAlternativesInProductionGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + S: $$ p0 $$?=> 'a' + | $$ p1 $$?=> 'b'; + '''.assertTranslatesToProductionGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + + @parser::members { + + private barGrammarAccess grammarAccess; + + public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) { + this(input); + this.grammarAccess = grammarAccess; + registerRules(grammarAccess.getGrammar()); + } + + @Override + protected String getFirstRuleName() { + return "S"; + } + + @Override + protected barGrammarAccess getGrammarAccess() { + return grammarAccess; + } + + // no init block + + } + + @rulecatch { + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + } + + // Entry rule entryRuleS + entryRuleS returns [EObject current=null]: + { newCompositeNode(grammarAccess.getSRule()); } + iv_ruleS=ruleS + { $current=$iv_ruleS.current; } + EOF; + + // Rule S + ruleS returns [EObject current=null] + @init { + enterRule(); + } + @after { + leaveRule(); + }: + ( + {(p0)}?=> + ( + ( + ) + otherlv_1='a' + { + newLeafNode(otherlv_1, grammarAccess.getSAccess().getAKeyword_0_1()); + } + ) + | + {(p1)}?=> + ( + ( + ) + otherlv_3='b' + { + newLeafNode(otherlv_3, grammarAccess.getSAccess().getBKeyword_1_1()); + } + ) + ) + ; + ''') + } + + @Test + def void testRenderingOfGuardConditionInNonTrivialCardinalitityInProductionGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + S: ($$ p0 $$?=> 'a')*; + '''.assertTranslatesToProductionGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + + @parser::members { + + private barGrammarAccess grammarAccess; + + public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) { + this(input); + this.grammarAccess = grammarAccess; + registerRules(grammarAccess.getGrammar()); + } + + @Override + protected String getFirstRuleName() { + return "S"; + } + + @Override + protected barGrammarAccess getGrammarAccess() { + return grammarAccess; + } + + // no init block + + } + + @rulecatch { + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + } + + // Entry rule entryRuleS + entryRuleS returns [EObject current=null]: + { newCompositeNode(grammarAccess.getSRule()); } + iv_ruleS=ruleS + { $current=$iv_ruleS.current; } + EOF; + + // Rule S + ruleS returns [EObject current=null] + @init { + enterRule(); + } + @after { + leaveRule(); + }: + ( + {(p0)}?=> + ( + ) + otherlv_1='a' + { + newLeafNode(otherlv_1, grammarAccess.getSAccess().getAKeyword_1()); + } + )* + ; + ''') + } + + @Test + def void testRenderingOfSetupBlockInProductionGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + setup $$ s0 $$ + + S: 'a'; + '''.assertTranslatesToProductionGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + + @parser::members { + + private barGrammarAccess grammarAccess; + + public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) { + this(input); + this.grammarAccess = grammarAccess; + registerRules(grammarAccess.getGrammar()); + } + + @Override + protected String getFirstRuleName() { + return "S"; + } + + @Override + protected barGrammarAccess getGrammarAccess() { + return grammarAccess; + } + + // init block + s0 + + } + + @rulecatch { + catch (RecognitionException re) { + recover(input,re); + appendSkippedTokens(); + } + } + + // Entry rule entryRuleS + entryRuleS returns [String current=null]: + { newCompositeNode(grammarAccess.getSRule()); } + iv_ruleS=ruleS + { $current=$iv_ruleS.current.getText(); } + EOF; + + // Rule S + ruleS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()] + @init { + enterRule(); + } + @after { + leaveRule(); + }: + kw='a' + { + $current.merge(kw); + newLeafNode(kw, grammarAccess.getSAccess().getAKeyword()); + } + ; + ''') + } + + @Test + def void testRenderingOfGuardConditionInAlternativesInContentAssistGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + S: $$ p0 $$?=> 'a' + | $$ p1 $$?=> 'b'; + '''.assertTranslatesToContentAssistGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + @parser::members { + private barGrammarAccess grammarAccess; + + public void setGrammarAccess(barGrammarAccess grammarAccess) { + this.grammarAccess = grammarAccess; + } + + @Override + protected Grammar getGrammar() { + return grammarAccess.getGrammar(); + } + + @Override + protected String getValueForTokenName(String tokenName) { + return tokenName; + } + + // no init block + } + + // Entry rule entryRuleS + entryRuleS + : + { before(grammarAccess.getSRule()); } + ruleS + { after(grammarAccess.getSRule()); } + EOF + ; + + // Rule S + ruleS + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getAlternatives()); } + ( + rule__S__Alternatives + ) + { after(grammarAccess.getSAccess().getAlternatives()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Alternatives + @init { + int stackSize = keepStackSize(); + } + : + {(p0)}?=>( + { before(grammarAccess.getSAccess().getGroup_0()); } + ( + rule__S__Group_0__0 + ) + { after(grammarAccess.getSAccess().getGroup_0()); } + ) + | + {(p1)}?=>( + { before(grammarAccess.getSAccess().getGroup_1()); } + ( + rule__S__Group_1__0 + ) + { after(grammarAccess.getSAccess().getGroup_1()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_0__0 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group_0__0__Impl + rule__S__Group_0__1 + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_0__0__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getGatedSemanticPredicate_0_0()); } + ( + ) + { after(grammarAccess.getSAccess().getGatedSemanticPredicate_0_0()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_0__1 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group_0__1__Impl + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_0__1__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getAKeyword_0_1()); } + 'a' + { after(grammarAccess.getSAccess().getAKeyword_0_1()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + + rule__S__Group_1__0 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group_1__0__Impl + rule__S__Group_1__1 + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_1__0__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getGatedSemanticPredicate_1_0()); } + ( + ) + { after(grammarAccess.getSAccess().getGatedSemanticPredicate_1_0()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_1__1 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group_1__1__Impl + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group_1__1__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getBKeyword_1_1()); } + 'b' + { after(grammarAccess.getSAccess().getBKeyword_1_1()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + ''') + } + + @Test + def void testRenderingOfGuardConditionInNonTrivialCardinalitityInContentAssistGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + S: ($$ p0 $$?=> 'a')*; + '''.assertTranslatesToContentAssistGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + @parser::members { + private barGrammarAccess grammarAccess; + + public void setGrammarAccess(barGrammarAccess grammarAccess) { + this.grammarAccess = grammarAccess; + } + + @Override + protected Grammar getGrammar() { + return grammarAccess.getGrammar(); + } + + @Override + protected String getValueForTokenName(String tokenName) { + return tokenName; + } + + // no init block + } + + // Entry rule entryRuleS + entryRuleS + : + { before(grammarAccess.getSRule()); } + ruleS + { after(grammarAccess.getSRule()); } + EOF + ; + + // Rule S + ruleS + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getGroup()); } + ( + {(p0)}?=> + rule__S__Group__0 + ) + * + { after(grammarAccess.getSAccess().getGroup()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group__0 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group__0__Impl + rule__S__Group__1 + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group__0__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getGatedSemanticPredicate_0()); } + ( + ) + { after(grammarAccess.getSAccess().getGatedSemanticPredicate_0()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group__1 + @init { + int stackSize = keepStackSize(); + } + : + rule__S__Group__1__Impl + ; + finally { + restoreStackSize(stackSize); + } + + rule__S__Group__1__Impl + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getAKeyword_1()); } + 'a' + { after(grammarAccess.getSAccess().getAKeyword_1()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + + ''') + } + + @Test + def void testRenderingOfSetupBlockInContentAssistGrammar() { + ''' + grammar com.foo.bar + import "http://www.eclipse.org/emf/2002/Ecore" as ecore + generate myPack 'http://mypack' + + setup $$ s0 $$ + + S: 'a'; + '''.assertTranslatesToContentAssistGrammar(''' + grammar DebugInternalbar; + + options { + } + + @lexer::header { + package com.foo.parser.antlr.internal; + + // Hack: Use our own Lexer superclass by means of import. + // Currently there is no other way to specify the superclass for the lexer. + import org.eclipse.xtext.parser.antlr.Lexer; + } + + @parser::header { + package com.foo.parser.antlr.internal; + } + @parser::members { + private barGrammarAccess grammarAccess; + + public void setGrammarAccess(barGrammarAccess grammarAccess) { + this.grammarAccess = grammarAccess; + } + + @Override + protected Grammar getGrammar() { + return grammarAccess.getGrammar(); + } + + @Override + protected String getValueForTokenName(String tokenName) { + return tokenName; + } + + // init block + s0 + } + + // Entry rule entryRuleS + entryRuleS + : + { before(grammarAccess.getSRule()); } + ruleS + { after(grammarAccess.getSRule()); } + EOF + ; + + // Rule S + ruleS + @init { + int stackSize = keepStackSize(); + } + : + ( + { before(grammarAccess.getSAccess().getAKeyword()); } + 'a' + { after(grammarAccess.getSAccess().getAKeyword()); } + ) + ; + finally { + restoreStackSize(stackSize); + } + ''') + } + + protected def void assertTranslatesToProductionGrammar(CharSequence xtextGrammar, String expectedDebugGrammar) { + val grammar = super.getModel(xtextGrammar.toString) as Grammar + val injector = Guice.createInjector(new DefaultGeneratorModule) + val inMem = new InMemFSA + val options = new AntlrOptions + injector.getInstance(AntlrDebugProductionGrammarGenerator).generate(grammar, options, inMem) + assertEquals(expectedDebugGrammar, inMem.allFiles.values.head.toString) + } + + protected def void assertTranslatesToContentAssistGrammar(CharSequence xtextGrammar, String expectedDebugGrammar) { + val grammar = super.getModel(xtextGrammar.toString) as Grammar + val injector = Guice.createInjector(new DefaultGeneratorModule) + val inMem = new InMemFSA + val options = new AntlrOptions + injector.getInstance(AntlrDebugContentAssistGrammarGenerator).generate(grammar, options, inMem) + assertEquals(expectedDebugGrammar, inMem.allFiles.values.head.toString) + } + + static class InMemFSA extends InMemoryFileSystemAccess implements IXtextGeneratorFileSystemAccess { + + override getPath() { + "./" + } + + override isOverwrite() { + true + } + + override initialize(Injector injector) { + injector.injectMembers(this) + } + + } +} \ No newline at end of file diff --git a/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.java b/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.java new file mode 100644 index 000000000..0f17d2c18 --- /dev/null +++ b/org.eclipse.xtext.tests/xtend-gen/org/eclipse/xtext/xtext/generator/hoisting/HoistingGeneratorTest.java @@ -0,0 +1,1612 @@ +/** + * Copyright (c) 2022 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.xtext.xtext.generator.hoisting; + +import com.google.inject.Guice; +import com.google.inject.Injector; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.xtend2.lib.StringConcatenation; +import org.eclipse.xtext.Grammar; +import org.eclipse.xtext.XtextStandaloneSetup; +import org.eclipse.xtext.generator.InMemoryFileSystemAccess; +import org.eclipse.xtext.tests.AbstractXtextTests; +import org.eclipse.xtext.xbase.lib.Exceptions; +import org.eclipse.xtext.xbase.lib.IterableExtensions; +import org.eclipse.xtext.xtext.generator.DefaultGeneratorModule; +import org.eclipse.xtext.xtext.generator.model.IXtextGeneratorFileSystemAccess; +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrDebugContentAssistGrammarGenerator; +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrDebugProductionGrammarGenerator; +import org.eclipse.xtext.xtext.generator.parser.antlr.AntlrOptions; +import org.junit.Assert; +import org.junit.Test; + +/** + * @author overflow - Initial contribution and API + */ +@SuppressWarnings("all") +public class HoistingGeneratorTest extends AbstractXtextTests { + public static class InMemFSA extends InMemoryFileSystemAccess implements IXtextGeneratorFileSystemAccess { + @Override + public String getPath() { + return "./"; + } + + @Override + public boolean isOverwrite() { + return true; + } + + @Override + public void initialize(final Injector injector) { + injector.injectMembers(this); + } + } + + @Override + public void setUp() throws Exception { + super.setUp(); + this.with(XtextStandaloneSetup.class); + } + + @Test + public void testRenderingOfGuardConditionInAlternativesInProductionGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: $$ p0 $$?=> \'a\'"); + _builder.newLine(); + _builder.append(" "); + _builder.append("| $$ p1 $$?=> \'b\';"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this(input);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("registerRules(grammarAccess.getGrammar());"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("protected String getFirstRuleName() {"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("return \"S\";"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("protected barGrammarAccess getGrammarAccess() {"); + _builder_1.newLine(); + _builder_1.append(" \t\t"); + _builder_1.append("return grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// no init block"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@rulecatch {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("catch (RecognitionException re) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("recover(input,re);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("appendSkippedTokens();"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS returns [EObject current=null]:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ newCompositeNode(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("iv_ruleS=ruleS"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ $current=$iv_ruleS.current; }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("EOF;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS returns [EObject current=null]"); + _builder_1.newLine(); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("enterRule();"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@after {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("leaveRule();"); + _builder_1.newLine(); + _builder_1.append("}:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{(p0)}?=>"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("otherlv_1=\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("{"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t\t"); + _builder_1.append("newLeafNode(otherlv_1, grammarAccess.getSAccess().getAKeyword_0_1());"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t "); + _builder_1.append("|"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{(p1)}?=>"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("otherlv_3=\'b\'"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("{"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t\t"); + _builder_1.append("newLeafNode(otherlv_3, grammarAccess.getSAccess().getBKeyword_1_1());"); + _builder_1.newLine(); + _builder_1.append("\t\t\t\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + this.assertTranslatesToProductionGrammar(_builder, _builder_1.toString()); + } + + @Test + public void testRenderingOfGuardConditionInNonTrivialCardinalitityInProductionGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: ($$ p0 $$?=> \'a\')*;"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this(input);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("registerRules(grammarAccess.getGrammar());"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("protected String getFirstRuleName() {"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("return \"S\";"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("protected barGrammarAccess getGrammarAccess() {"); + _builder_1.newLine(); + _builder_1.append(" \t\t"); + _builder_1.append("return grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// no init block"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@rulecatch {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("catch (RecognitionException re) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("recover(input,re);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("appendSkippedTokens();"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS returns [EObject current=null]:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ newCompositeNode(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("iv_ruleS=ruleS"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ $current=$iv_ruleS.current; }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("EOF;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS returns [EObject current=null]"); + _builder_1.newLine(); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("enterRule();"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@after {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("leaveRule();"); + _builder_1.newLine(); + _builder_1.append("}:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{(p0)}?=>"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("otherlv_1=\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("newLeafNode(otherlv_1, grammarAccess.getSAccess().getAKeyword_1());"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")*"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + this.assertTranslatesToProductionGrammar(_builder, _builder_1.toString()); + } + + @Test + public void testRenderingOfSetupBlockInProductionGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("setup $$ s0 $$"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: \'a\';"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("public InternalbarParser(TokenStream input, barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this(input);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("registerRules(grammarAccess.getGrammar());"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("protected String getFirstRuleName() {"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("return \"S\";"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("protected barGrammarAccess getGrammarAccess() {"); + _builder_1.newLine(); + _builder_1.append(" \t\t"); + _builder_1.append("return grammarAccess;"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// init block"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("s0"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@rulecatch {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("catch (RecognitionException re) {"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("recover(input,re);"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("appendSkippedTokens();"); + _builder_1.newLine(); + _builder_1.append(" "); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS returns [String current=null]:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ newCompositeNode(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("iv_ruleS=ruleS"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ $current=$iv_ruleS.current.getText(); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("EOF;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS returns [AntlrDatatypeRuleToken current=new AntlrDatatypeRuleToken()]"); + _builder_1.newLine(); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("enterRule();"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@after {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("leaveRule();"); + _builder_1.newLine(); + _builder_1.append("}:"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("kw=\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("$current.merge(kw);"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("newLeafNode(kw, grammarAccess.getSAccess().getAKeyword());"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + this.assertTranslatesToProductionGrammar(_builder, _builder_1.toString()); + } + + @Test + public void testRenderingOfGuardConditionInAlternativesInContentAssistGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: $$ p0 $$?=> \'a\'"); + _builder.newLine(); + _builder.append(" "); + _builder.append("| $$ p1 $$?=> \'b\';"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("public void setGrammarAccess(barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected Grammar getGrammar() {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return grammarAccess.getGrammar();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected String getValueForTokenName(String tokenName) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return tokenName;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// no init block"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("{ before(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("ruleS"); + _builder_1.newLine(); + _builder_1.append("{ after(grammarAccess.getSRule()); } "); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("EOF "); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS "); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getAlternatives()); }"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("rule__S__Alternatives"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getAlternatives()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Alternatives"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{(p0)}?=>("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGroup_0()); }"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("rule__S__Group_0__0"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGroup_0()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("|"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{(p1)}?=>("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGroup_1()); }"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("rule__S__Group_1__0"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGroup_1()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_0__0"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_0__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_0__1"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_0__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGatedSemanticPredicate_0_0()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGatedSemanticPredicate_0_0()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_0__1"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_0__1__Impl"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_0__1__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getAKeyword_0_1()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getAKeyword_0_1()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_1__0"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_1__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_1__1"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_1__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGatedSemanticPredicate_1_0()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGatedSemanticPredicate_1_0()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_1__1"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group_1__1__Impl"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group_1__1__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getBKeyword_1_1()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("\'b\'"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getBKeyword_1_1()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + this.assertTranslatesToContentAssistGrammar(_builder, _builder_1.toString()); + } + + @Test + public void testRenderingOfGuardConditionInNonTrivialCardinalitityInContentAssistGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: ($$ p0 $$?=> \'a\')*;"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("public void setGrammarAccess(barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected Grammar getGrammar() {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return grammarAccess.getGrammar();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected String getValueForTokenName(String tokenName) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return tokenName;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// no init block"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("{ before(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("ruleS"); + _builder_1.newLine(); + _builder_1.append("{ after(grammarAccess.getSRule()); } "); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("EOF "); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS "); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGroup()); }"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("{(p0)}?=>"); + _builder_1.newLine(); + _builder_1.append("\t\t\t"); + _builder_1.append("rule__S__Group__0"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("*"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGroup()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group__0"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group__1"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group__0__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getGatedSemanticPredicate_0()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getGatedSemanticPredicate_0()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group__1"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("rule__S__Group__1__Impl"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("rule__S__Group__1__Impl"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getAKeyword_1()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getAKeyword_1()); }"); + _builder_1.newLine(); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + this.assertTranslatesToContentAssistGrammar(_builder, _builder_1.toString()); + } + + @Test + public void testRenderingOfSetupBlockInContentAssistGrammar() { + StringConcatenation _builder = new StringConcatenation(); + _builder.append("grammar com.foo.bar "); + _builder.newLine(); + _builder.append("import \"http://www.eclipse.org/emf/2002/Ecore\" as ecore"); + _builder.newLine(); + _builder.append("generate myPack \'http://mypack\'"); + _builder.newLine(); + _builder.newLine(); + _builder.append("setup $$ s0 $$"); + _builder.newLine(); + _builder.newLine(); + _builder.append("S: \'a\';"); + _builder.newLine(); + StringConcatenation _builder_1 = new StringConcatenation(); + _builder_1.append("grammar DebugInternalbar;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("options {"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@lexer::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Hack: Use our own Lexer superclass by means of import. "); + _builder_1.newLine(); + _builder_1.append("// Currently there is no other way to specify the superclass for the lexer."); + _builder_1.newLine(); + _builder_1.append("import org.eclipse.xtext.parser.antlr.Lexer;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("@parser::header {"); + _builder_1.newLine(); + _builder_1.append("package com.foo.parser.antlr.internal;"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("@parser::members {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("private barGrammarAccess grammarAccess;"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("public void setGrammarAccess(barGrammarAccess grammarAccess) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("this.grammarAccess = grammarAccess;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected Grammar getGrammar() {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return grammarAccess.getGrammar();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@Override"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("protected String getValueForTokenName(String tokenName) {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("return tokenName;"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("// init block"); + _builder_1.newLine(); + _builder_1.append(" \t"); + _builder_1.append("s0"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Entry rule entryRuleS"); + _builder_1.newLine(); + _builder_1.append("entryRuleS"); + _builder_1.newLine(); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("{ before(grammarAccess.getSRule()); }"); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("ruleS"); + _builder_1.newLine(); + _builder_1.append("{ after(grammarAccess.getSRule()); } "); + _builder_1.newLine(); + _builder_1.append("\t "); + _builder_1.append("EOF "); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.newLine(); + _builder_1.append("// Rule S"); + _builder_1.newLine(); + _builder_1.append("ruleS "); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("@init {"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("int stackSize = keepStackSize();"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("}"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(":"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("("); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ before(grammarAccess.getSAccess().getAKeyword()); }"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("\'a\'"); + _builder_1.newLine(); + _builder_1.append("\t\t"); + _builder_1.append("{ after(grammarAccess.getSAccess().getAKeyword()); }"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append(")"); + _builder_1.newLine(); + _builder_1.append(";"); + _builder_1.newLine(); + _builder_1.append("finally {"); + _builder_1.newLine(); + _builder_1.append("\t"); + _builder_1.append("restoreStackSize(stackSize);"); + _builder_1.newLine(); + _builder_1.append("}"); + _builder_1.newLine(); + this.assertTranslatesToContentAssistGrammar(_builder, _builder_1.toString()); + } + + protected void assertTranslatesToProductionGrammar(final CharSequence xtextGrammar, final String expectedDebugGrammar) { + try { + EObject _model = super.getModel(xtextGrammar.toString()); + final Grammar grammar = ((Grammar) _model); + DefaultGeneratorModule _defaultGeneratorModule = new DefaultGeneratorModule(); + final Injector injector = Guice.createInjector(_defaultGeneratorModule); + final HoistingGeneratorTest.InMemFSA inMem = new HoistingGeneratorTest.InMemFSA(); + final AntlrOptions options = new AntlrOptions(); + injector.getInstance(AntlrDebugProductionGrammarGenerator.class).generate(grammar, options, inMem); + Assert.assertEquals(expectedDebugGrammar, IterableExtensions.head(inMem.getAllFiles().values()).toString()); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } + + protected void assertTranslatesToContentAssistGrammar(final CharSequence xtextGrammar, final String expectedDebugGrammar) { + try { + EObject _model = super.getModel(xtextGrammar.toString()); + final Grammar grammar = ((Grammar) _model); + DefaultGeneratorModule _defaultGeneratorModule = new DefaultGeneratorModule(); + final Injector injector = Guice.createInjector(_defaultGeneratorModule); + final HoistingGeneratorTest.InMemFSA inMem = new HoistingGeneratorTest.InMemFSA(); + final AntlrOptions options = new AntlrOptions(); + injector.getInstance(AntlrDebugContentAssistGrammarGenerator.class).generate(grammar, options, inMem); + Assert.assertEquals(expectedDebugGrammar, IterableExtensions.head(inMem.getAllFiles().values()).toString()); + } catch (Throwable _e) { + throw Exceptions.sneakyThrow(_e); + } + } +} diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.xtend b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.xtend index 17e1e9ff3..23dbf62e1 100644 --- a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.xtend +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.xtend @@ -293,7 +293,7 @@ abstract class AbstractAntlrGrammarGenerator { protected def String compileEBNF(AbstractRule it, AntlrOptions options) ''' // Rule «originalElement.name» - «IF it instanceof ParserRule» + «IF it instanceof ParserRule && originalGrammar.isDebug» // Guard: «findGuardForRule.renderDescription» «ENDIF» «ruleName»«compileInit(options)»: diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugContentAssistGrammarGenerator.java b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugContentAssistGrammarGenerator.java new file mode 100644 index 000000000..c659413ab --- /dev/null +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugContentAssistGrammarGenerator.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.xtext.xtext.generator.parser.antlr; + +import org.eclipse.xtext.Grammar; + +import com.google.inject.Inject; + +public class AntlrDebugContentAssistGrammarGenerator extends AntlrContentAssistGrammarGenerator { + @Inject + private DebugGrammarNaming naming; + + @Override + protected GrammarNaming getGrammarNaming() { + return naming; + } + + @Override + protected String compileParserImports(Grammar it, AntlrOptions options) { + return ""; + } +} diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugProductionGrammarGenerator.java b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugProductionGrammarGenerator.java new file mode 100644 index 000000000..4a6745eb9 --- /dev/null +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/AntlrDebugProductionGrammarGenerator.java @@ -0,0 +1,28 @@ +/** + * Copyright (c) 2015, 2020 itemis AG (http://www.itemis.eu) and others. + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0. + * + * SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.xtext.xtext.generator.parser.antlr; + +import org.eclipse.xtext.Grammar; + +import com.google.inject.Inject; + +public class AntlrDebugProductionGrammarGenerator extends AntlrGrammarGenerator { + @Inject + private DebugGrammarNaming naming; + + @Override + protected GrammarNaming getGrammarNaming() { + return naming; + } + + @Override + protected String compileParserImports(Grammar it, AntlrOptions options) { + return ""; + } +} diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/JavaCodeUtils.java b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/JavaCodeUtils.java index 5f409a2e5..44dc9033f 100644 --- a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/JavaCodeUtils.java +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/JavaCodeUtils.java @@ -17,7 +17,7 @@ import org.eclipse.xtext.xtext.generator.parser.antlr.hoisting.guards.Guard; public class JavaCodeUtils { static public String getSource(JavaCode code) { String source = code.getSource(); - return source.substring(2, source.length() - 2); + return source.substring(2, source.length() - 2).trim(); } static public String formatCodeForGrammar(String code) { diff --git a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/guards/PredicateGuard.java b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/guards/PredicateGuard.java index 7eb61c119..70410dfda 100644 --- a/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/guards/PredicateGuard.java +++ b/org.eclipse.xtext.xtext.generator/src/org/eclipse/xtext/xtext/generator/parser/antlr/hoisting/guards/PredicateGuard.java @@ -29,7 +29,7 @@ public class PredicateGuard implements HoistingGuard { @Override public String render() { - return "(" + JavaCodeUtils.getSource(element.getCode()).trim() + ")"; + return "(" + JavaCodeUtils.getSource(element.getCode()) + ")"; } @Override @@ -40,7 +40,7 @@ public class PredicateGuard implements HoistingGuard { @Override public String toString() { return "PredicateGuard (\n" + - "\t" + JavaCodeUtils.getSource(element.getCode()).trim() + "\n" + + "\t" + JavaCodeUtils.getSource(element.getCode()) + "\n" + ")\n"; } diff --git a/org.eclipse.xtext.xtext.generator/xtend-gen/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.java b/org.eclipse.xtext.xtext.generator/xtend-gen/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.java index 4a748245e..3cef530c0 100644 --- a/org.eclipse.xtext.xtext.generator/xtend-gen/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.java +++ b/org.eclipse.xtext.xtext.generator/xtend-gen/org/eclipse/xtext/xtext/generator/parser/antlr/AbstractAntlrGrammarGenerator.java @@ -641,7 +641,7 @@ public abstract class AbstractAntlrGrammarGenerator { _builder.append(_name); _builder.newLineIfNotEmpty(); { - if ((it instanceof ParserRule)) { + if (((it instanceof ParserRule) && this.originalGrammar.isDebug())) { _builder.append("// Guard: "); String _renderDescription = this._hoistingProcessor.findGuardForRule(it).renderDescription(); _builder.append(_renderDescription);