Merge pull request #572 from eclipse/sz_avoidDuplicatedCode

Avoid duplicated code in CA infrastructure
This commit is contained in:
Sebastian Zarnekow 2017-12-08 15:21:50 +01:00 committed by GitHub
commit 13051ddac6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1605 additions and 1337 deletions

View file

@ -7,8 +7,9 @@
*/
package org.eclipse.xtext.ide.tests.testlanguage.ide.contentassist.antlr;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import java.util.HashMap;
import com.google.inject.Singleton;
import java.util.Map;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.TokenSource;
@ -19,11 +20,44 @@ import org.eclipse.xtext.ide.tests.testlanguage.services.IndentationAwareUiTestL
public class IndentationAwareUiTestLanguageParser extends AbstractContentAssistParser {
@Singleton
public static final class NameMappings {
private final Map<AbstractElement, String> mappings;
@Inject
public NameMappings(IndentationAwareUiTestLanguageGrammarAccess grammarAccess) {
ImmutableMap.Builder<AbstractElement, String> builder = ImmutableMap.builder();
init(builder, grammarAccess);
this.mappings = builder.build();
}
public String getRuleName(AbstractElement element) {
return mappings.get(element);
}
private static void init(ImmutableMap.Builder<AbstractElement, String> builder, IndentationAwareUiTestLanguageGrammarAccess grammarAccess) {
builder.put(grammarAccess.getTreeAccess().getGroup(), "rule__Tree__Group__0");
builder.put(grammarAccess.getTreeNodeAccess().getGroup(), "rule__TreeNode__Group__0");
builder.put(grammarAccess.getTreeNodeAccess().getGroup_1(), "rule__TreeNode__Group_1__0");
builder.put(grammarAccess.getOtherTreeNodeAccess().getGroup(), "rule__OtherTreeNode__Group__0");
builder.put(grammarAccess.getChildListAccess().getGroup(), "rule__ChildList__Group__0");
builder.put(grammarAccess.getTreeAccess().getNodesAssignment_1(), "rule__Tree__NodesAssignment_1");
builder.put(grammarAccess.getTreeAccess().getMoreNodesAssignment_2(), "rule__Tree__MoreNodesAssignment_2");
builder.put(grammarAccess.getTreeNodeAccess().getNameAssignment_0(), "rule__TreeNode__NameAssignment_0");
builder.put(grammarAccess.getTreeNodeAccess().getChildrenAssignment_1_1(), "rule__TreeNode__ChildrenAssignment_1_1");
builder.put(grammarAccess.getOtherTreeNodeAccess().getNameAssignment_0(), "rule__OtherTreeNode__NameAssignment_0");
builder.put(grammarAccess.getOtherTreeNodeAccess().getChildListAssignment_1(), "rule__OtherTreeNode__ChildListAssignment_1");
builder.put(grammarAccess.getChildListAccess().getChildrenAssignment_2(), "rule__ChildList__ChildrenAssignment_2");
}
}
@Inject
private NameMappings nameMappings;
@Inject
private IndentationAwareUiTestLanguageGrammarAccess grammarAccess;
private Map<AbstractElement, String> nameMappings;
@Override
protected InternalIndentationAwareUiTestLanguageParser createParser() {
InternalIndentationAwareUiTestLanguageParser result = new InternalIndentationAwareUiTestLanguageParser(null);
@ -38,28 +72,9 @@ public class IndentationAwareUiTestLanguageParser extends AbstractContentAssistP
@Override
protected String getRuleName(AbstractElement element) {
if (nameMappings == null) {
nameMappings = new HashMap<AbstractElement, String>() {
private static final long serialVersionUID = 1L;
{
put(grammarAccess.getTreeAccess().getGroup(), "rule__Tree__Group__0");
put(grammarAccess.getTreeNodeAccess().getGroup(), "rule__TreeNode__Group__0");
put(grammarAccess.getTreeNodeAccess().getGroup_1(), "rule__TreeNode__Group_1__0");
put(grammarAccess.getOtherTreeNodeAccess().getGroup(), "rule__OtherTreeNode__Group__0");
put(grammarAccess.getChildListAccess().getGroup(), "rule__ChildList__Group__0");
put(grammarAccess.getTreeAccess().getNodesAssignment_1(), "rule__Tree__NodesAssignment_1");
put(grammarAccess.getTreeAccess().getMoreNodesAssignment_2(), "rule__Tree__MoreNodesAssignment_2");
put(grammarAccess.getTreeNodeAccess().getNameAssignment_0(), "rule__TreeNode__NameAssignment_0");
put(grammarAccess.getTreeNodeAccess().getChildrenAssignment_1_1(), "rule__TreeNode__ChildrenAssignment_1_1");
put(grammarAccess.getOtherTreeNodeAccess().getNameAssignment_0(), "rule__OtherTreeNode__NameAssignment_0");
put(grammarAccess.getOtherTreeNodeAccess().getChildListAssignment_1(), "rule__OtherTreeNode__ChildListAssignment_1");
put(grammarAccess.getChildListAccess().getChildrenAssignment_2(), "rule__ChildList__ChildrenAssignment_2");
}
};
}
return nameMappings.get(element);
return nameMappings.getRuleName(element);
}
@Override
protected String[] getInitialHiddenTokens() {
return new String[] { "RULE_WS", "RULE_ML_COMMENT", "RULE_SL_COMMENT" };
@ -72,4 +87,12 @@ public class IndentationAwareUiTestLanguageParser extends AbstractContentAssistP
public void setGrammarAccess(IndentationAwareUiTestLanguageGrammarAccess grammarAccess) {
this.grammarAccess = grammarAccess;
}
public NameMappings getNameMappings() {
return nameMappings;
}
public void setNameMappings(NameMappings nameMappings) {
this.nameMappings = nameMappings;
}
}

View file

@ -7,8 +7,9 @@
*/
package org.eclipse.xtext.ide.tests.testlanguage.ide.contentassist.antlr;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import java.util.HashMap;
import com.google.inject.Singleton;
import java.util.Map;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.AbstractPartialContentAssistParser;
@ -17,11 +18,41 @@ import org.eclipse.xtext.ide.tests.testlanguage.services.PartialContentAssistTes
public class PartialContentAssistTestLanguageParser extends AbstractPartialContentAssistParser {
@Singleton
public static final class NameMappings {
private final Map<AbstractElement, String> mappings;
@Inject
public NameMappings(PartialContentAssistTestLanguageGrammarAccess grammarAccess) {
ImmutableMap.Builder<AbstractElement, String> builder = ImmutableMap.builder();
init(builder, grammarAccess);
this.mappings = builder.build();
}
public String getRuleName(AbstractElement element) {
return mappings.get(element);
}
private static void init(ImmutableMap.Builder<AbstractElement, String> builder, PartialContentAssistTestLanguageGrammarAccess grammarAccess) {
builder.put(grammarAccess.getPropertyAccess().getTypeAlternatives_0_0(), "rule__Property__TypeAlternatives_0_0");
builder.put(grammarAccess.getTypeDeclarationAccess().getGroup(), "rule__TypeDeclaration__Group__0");
builder.put(grammarAccess.getTypeDeclarationAccess().getGroup_2(), "rule__TypeDeclaration__Group_2__0");
builder.put(grammarAccess.getPropertyAccess().getGroup(), "rule__Property__Group__0");
builder.put(grammarAccess.getTypeDeclarationAccess().getNameAssignment_1(), "rule__TypeDeclaration__NameAssignment_1");
builder.put(grammarAccess.getTypeDeclarationAccess().getSuperTypeAssignment_2_1(), "rule__TypeDeclaration__SuperTypeAssignment_2_1");
builder.put(grammarAccess.getTypeDeclarationAccess().getPropertiesAssignment_4(), "rule__TypeDeclaration__PropertiesAssignment_4");
builder.put(grammarAccess.getPropertyAccess().getTypeAssignment_0(), "rule__Property__TypeAssignment_0");
builder.put(grammarAccess.getPropertyAccess().getNameAssignment_1(), "rule__Property__NameAssignment_1");
}
}
@Inject
private NameMappings nameMappings;
@Inject
private PartialContentAssistTestLanguageGrammarAccess grammarAccess;
private Map<AbstractElement, String> nameMappings;
@Override
protected InternalPartialContentAssistTestLanguageParser createParser() {
InternalPartialContentAssistTestLanguageParser result = new InternalPartialContentAssistTestLanguageParser(null);
@ -31,25 +62,9 @@ public class PartialContentAssistTestLanguageParser extends AbstractPartialConte
@Override
protected String getRuleName(AbstractElement element) {
if (nameMappings == null) {
nameMappings = new HashMap<AbstractElement, String>() {
private static final long serialVersionUID = 1L;
{
put(grammarAccess.getPropertyAccess().getTypeAlternatives_0_0(), "rule__Property__TypeAlternatives_0_0");
put(grammarAccess.getTypeDeclarationAccess().getGroup(), "rule__TypeDeclaration__Group__0");
put(grammarAccess.getTypeDeclarationAccess().getGroup_2(), "rule__TypeDeclaration__Group_2__0");
put(grammarAccess.getPropertyAccess().getGroup(), "rule__Property__Group__0");
put(grammarAccess.getTypeDeclarationAccess().getNameAssignment_1(), "rule__TypeDeclaration__NameAssignment_1");
put(grammarAccess.getTypeDeclarationAccess().getSuperTypeAssignment_2_1(), "rule__TypeDeclaration__SuperTypeAssignment_2_1");
put(grammarAccess.getTypeDeclarationAccess().getPropertiesAssignment_4(), "rule__TypeDeclaration__PropertiesAssignment_4");
put(grammarAccess.getPropertyAccess().getTypeAssignment_0(), "rule__Property__TypeAssignment_0");
put(grammarAccess.getPropertyAccess().getNameAssignment_1(), "rule__Property__NameAssignment_1");
}
};
}
return nameMappings.get(element);
return nameMappings.getRuleName(element);
}
@Override
protected String[] getInitialHiddenTokens() {
return new String[] { "RULE_WS", "RULE_ML_COMMENT", "RULE_SL_COMMENT" };
@ -62,4 +77,12 @@ public class PartialContentAssistTestLanguageParser extends AbstractPartialConte
public void setGrammarAccess(PartialContentAssistTestLanguageGrammarAccess grammarAccess) {
this.grammarAccess = grammarAccess;
}
public NameMappings getNameMappings() {
return nameMappings;
}
public void setNameMappings(NameMappings nameMappings) {
this.nameMappings = nameMappings;
}
}

View file

@ -7,8 +7,9 @@
*/
package org.eclipse.xtext.ide.tests.testlanguage.ide.contentassist.antlr;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import java.util.HashMap;
import com.google.inject.Singleton;
import java.util.Map;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.AbstractPartialContentAssistParser;
@ -17,11 +18,73 @@ import org.eclipse.xtext.ide.tests.testlanguage.services.PartialSerializationTes
public class PartialSerializationTestLanguageParser extends AbstractPartialContentAssistParser {
@Singleton
public static final class NameMappings {
private final Map<AbstractElement, String> mappings;
@Inject
public NameMappings(PartialSerializationTestLanguageGrammarAccess grammarAccess) {
ImmutableMap.Builder<AbstractElement, String> builder = ImmutableMap.builder();
init(builder, grammarAccess);
this.mappings = builder.build();
}
public String getRuleName(AbstractElement element) {
return mappings.get(element);
}
private static void init(ImmutableMap.Builder<AbstractElement, String> builder, PartialSerializationTestLanguageGrammarAccess grammarAccess) {
builder.put(grammarAccess.getModelAccess().getAlternatives(), "rule__Model__Alternatives");
builder.put(grammarAccess.getNodeAccess().getAlternatives_4(), "rule__Node__Alternatives_4");
builder.put(grammarAccess.getModelAccess().getGroup_0(), "rule__Model__Group_0__0");
builder.put(grammarAccess.getModelAccess().getGroup_1(), "rule__Model__Group_1__0");
builder.put(grammarAccess.getModelAccess().getGroup_2(), "rule__Model__Group_2__0");
builder.put(grammarAccess.getModelAccess().getGroup_3(), "rule__Model__Group_3__0");
builder.put(grammarAccess.getModelAccess().getGroup_4(), "rule__Model__Group_4__0");
builder.put(grammarAccess.getModelAccess().getGroup_5(), "rule__Model__Group_5__0");
builder.put(grammarAccess.getModelAccess().getGroup_6(), "rule__Model__Group_6__0");
builder.put(grammarAccess.getModelAccess().getGroup_7(), "rule__Model__Group_7__0");
builder.put(grammarAccess.getModelAccess().getGroup_8(), "rule__Model__Group_8__0");
builder.put(grammarAccess.getModelAccess().getGroup_9(), "rule__Model__Group_9__0");
builder.put(grammarAccess.getModelAccess().getGroup_10(), "rule__Model__Group_10__0");
builder.put(grammarAccess.getOptionalValueAccess().getGroup(), "rule__OptionalValue__Group__0");
builder.put(grammarAccess.getManyOptionalValuesAccess().getGroup(), "rule__ManyOptionalValues__Group__0");
builder.put(grammarAccess.getOptionalChildAccess().getGroup(), "rule__OptionalChild__Group__0");
builder.put(grammarAccess.getOptionalChildListAccess().getGroup(), "rule__OptionalChildList__Group__0");
builder.put(grammarAccess.getImportAccess().getGroup(), "rule__Import__Group__0");
builder.put(grammarAccess.getNodeAccess().getGroup(), "rule__Node__Group__0");
builder.put(grammarAccess.getNodeAccess().getGroup_3(), "rule__Node__Group_3__0");
builder.put(grammarAccess.getNodeAccess().getGroup_4_0(), "rule__Node__Group_4_0__0");
builder.put(grammarAccess.getNodeAccess().getGroup_4_0_2(), "rule__Node__Group_4_0_2__0");
builder.put(grammarAccess.getQualifiedNameAccess().getGroup(), "rule__QualifiedName__Group__0");
builder.put(grammarAccess.getQualifiedNameAccess().getGroup_1(), "rule__QualifiedName__Group_1__0");
builder.put(grammarAccess.getModelAccess().getClazzAssignment_9_1(), "rule__Model__ClazzAssignment_9_1");
builder.put(grammarAccess.getMandatoryValueAccess().getNameAssignment(), "rule__MandatoryValue__NameAssignment");
builder.put(grammarAccess.getOptionalValueAccess().getNameAssignment_2(), "rule__OptionalValue__NameAssignment_2");
builder.put(grammarAccess.getManyOptionalValuesAccess().getNameAssignment_1(), "rule__ManyOptionalValues__NameAssignment_1");
builder.put(grammarAccess.getManyMandatoryValuesAccess().getNameAssignment(), "rule__ManyMandatoryValues__NameAssignment");
builder.put(grammarAccess.getMandatoryChildAccess().getChildAssignment(), "rule__MandatoryChild__ChildAssignment");
builder.put(grammarAccess.getOptionalChildAccess().getChildAssignment_1(), "rule__OptionalChild__ChildAssignment_1");
builder.put(grammarAccess.getMandatoryChildListAccess().getChildrenAssignment(), "rule__MandatoryChildList__ChildrenAssignment");
builder.put(grammarAccess.getOptionalChildListAccess().getChildrenAssignment_1(), "rule__OptionalChildList__ChildrenAssignment_1");
builder.put(grammarAccess.getImportAccess().getImportedNamespaceAssignment_1(), "rule__Import__ImportedNamespaceAssignment_1");
builder.put(grammarAccess.getNodeAccess().getImportsAssignment_1(), "rule__Node__ImportsAssignment_1");
builder.put(grammarAccess.getNodeAccess().getNameAssignment_2(), "rule__Node__NameAssignment_2");
builder.put(grammarAccess.getNodeAccess().getRefsAssignment_3_1(), "rule__Node__RefsAssignment_3_1");
builder.put(grammarAccess.getNodeAccess().getChildrenAssignment_4_0_1(), "rule__Node__ChildrenAssignment_4_0_1");
builder.put(grammarAccess.getNodeAccess().getRefAssignment_4_0_2_1(), "rule__Node__RefAssignment_4_0_2_1");
builder.put(grammarAccess.getEClassDeclAccess().getNameAssignment(), "rule__EClassDecl__NameAssignment");
builder.put(grammarAccess.getEClassRefAccess().getRefAssignment(), "rule__EClassRef__RefAssignment");
}
}
@Inject
private NameMappings nameMappings;
@Inject
private PartialSerializationTestLanguageGrammarAccess grammarAccess;
private Map<AbstractElement, String> nameMappings;
@Override
protected InternalPartialSerializationTestLanguageParser createParser() {
InternalPartialSerializationTestLanguageParser result = new InternalPartialSerializationTestLanguageParser(null);
@ -31,57 +94,9 @@ public class PartialSerializationTestLanguageParser extends AbstractPartialConte
@Override
protected String getRuleName(AbstractElement element) {
if (nameMappings == null) {
nameMappings = new HashMap<AbstractElement, String>() {
private static final long serialVersionUID = 1L;
{
put(grammarAccess.getModelAccess().getAlternatives(), "rule__Model__Alternatives");
put(grammarAccess.getNodeAccess().getAlternatives_4(), "rule__Node__Alternatives_4");
put(grammarAccess.getModelAccess().getGroup_0(), "rule__Model__Group_0__0");
put(grammarAccess.getModelAccess().getGroup_1(), "rule__Model__Group_1__0");
put(grammarAccess.getModelAccess().getGroup_2(), "rule__Model__Group_2__0");
put(grammarAccess.getModelAccess().getGroup_3(), "rule__Model__Group_3__0");
put(grammarAccess.getModelAccess().getGroup_4(), "rule__Model__Group_4__0");
put(grammarAccess.getModelAccess().getGroup_5(), "rule__Model__Group_5__0");
put(grammarAccess.getModelAccess().getGroup_6(), "rule__Model__Group_6__0");
put(grammarAccess.getModelAccess().getGroup_7(), "rule__Model__Group_7__0");
put(grammarAccess.getModelAccess().getGroup_8(), "rule__Model__Group_8__0");
put(grammarAccess.getModelAccess().getGroup_9(), "rule__Model__Group_9__0");
put(grammarAccess.getModelAccess().getGroup_10(), "rule__Model__Group_10__0");
put(grammarAccess.getOptionalValueAccess().getGroup(), "rule__OptionalValue__Group__0");
put(grammarAccess.getManyOptionalValuesAccess().getGroup(), "rule__ManyOptionalValues__Group__0");
put(grammarAccess.getOptionalChildAccess().getGroup(), "rule__OptionalChild__Group__0");
put(grammarAccess.getOptionalChildListAccess().getGroup(), "rule__OptionalChildList__Group__0");
put(grammarAccess.getImportAccess().getGroup(), "rule__Import__Group__0");
put(grammarAccess.getNodeAccess().getGroup(), "rule__Node__Group__0");
put(grammarAccess.getNodeAccess().getGroup_3(), "rule__Node__Group_3__0");
put(grammarAccess.getNodeAccess().getGroup_4_0(), "rule__Node__Group_4_0__0");
put(grammarAccess.getNodeAccess().getGroup_4_0_2(), "rule__Node__Group_4_0_2__0");
put(grammarAccess.getQualifiedNameAccess().getGroup(), "rule__QualifiedName__Group__0");
put(grammarAccess.getQualifiedNameAccess().getGroup_1(), "rule__QualifiedName__Group_1__0");
put(grammarAccess.getModelAccess().getClazzAssignment_9_1(), "rule__Model__ClazzAssignment_9_1");
put(grammarAccess.getMandatoryValueAccess().getNameAssignment(), "rule__MandatoryValue__NameAssignment");
put(grammarAccess.getOptionalValueAccess().getNameAssignment_2(), "rule__OptionalValue__NameAssignment_2");
put(grammarAccess.getManyOptionalValuesAccess().getNameAssignment_1(), "rule__ManyOptionalValues__NameAssignment_1");
put(grammarAccess.getManyMandatoryValuesAccess().getNameAssignment(), "rule__ManyMandatoryValues__NameAssignment");
put(grammarAccess.getMandatoryChildAccess().getChildAssignment(), "rule__MandatoryChild__ChildAssignment");
put(grammarAccess.getOptionalChildAccess().getChildAssignment_1(), "rule__OptionalChild__ChildAssignment_1");
put(grammarAccess.getMandatoryChildListAccess().getChildrenAssignment(), "rule__MandatoryChildList__ChildrenAssignment");
put(grammarAccess.getOptionalChildListAccess().getChildrenAssignment_1(), "rule__OptionalChildList__ChildrenAssignment_1");
put(grammarAccess.getImportAccess().getImportedNamespaceAssignment_1(), "rule__Import__ImportedNamespaceAssignment_1");
put(grammarAccess.getNodeAccess().getImportsAssignment_1(), "rule__Node__ImportsAssignment_1");
put(grammarAccess.getNodeAccess().getNameAssignment_2(), "rule__Node__NameAssignment_2");
put(grammarAccess.getNodeAccess().getRefsAssignment_3_1(), "rule__Node__RefsAssignment_3_1");
put(grammarAccess.getNodeAccess().getChildrenAssignment_4_0_1(), "rule__Node__ChildrenAssignment_4_0_1");
put(grammarAccess.getNodeAccess().getRefAssignment_4_0_2_1(), "rule__Node__RefAssignment_4_0_2_1");
put(grammarAccess.getEClassDeclAccess().getNameAssignment(), "rule__EClassDecl__NameAssignment");
put(grammarAccess.getEClassRefAccess().getRefAssignment(), "rule__EClassRef__RefAssignment");
}
};
}
return nameMappings.get(element);
return nameMappings.getRuleName(element);
}
@Override
protected String[] getInitialHiddenTokens() {
return new String[] { "RULE_WS", "RULE_ML_COMMENT", "RULE_SL_COMMENT" };
@ -94,4 +109,12 @@ public class PartialSerializationTestLanguageParser extends AbstractPartialConte
public void setGrammarAccess(PartialSerializationTestLanguageGrammarAccess grammarAccess) {
this.grammarAccess = grammarAccess;
}
public NameMappings getNameMappings() {
return nameMappings;
}
public void setNameMappings(NameMappings nameMappings) {
this.nameMappings = nameMappings;
}
}

View file

@ -7,8 +7,9 @@
*/
package org.eclipse.xtext.ide.tests.testlanguage.ide.contentassist.antlr;
import com.google.common.collect.ImmutableMap;
import com.google.inject.Inject;
import java.util.HashMap;
import com.google.inject.Singleton;
import java.util.Map;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.AbstractContentAssistParser;
@ -17,11 +18,67 @@ import org.eclipse.xtext.ide.tests.testlanguage.services.TestLanguageGrammarAcce
public class TestLanguageParser extends AbstractContentAssistParser {
@Singleton
public static final class NameMappings {
private final Map<AbstractElement, String> mappings;
@Inject
public NameMappings(TestLanguageGrammarAccess grammarAccess) {
ImmutableMap.Builder<AbstractElement, String> builder = ImmutableMap.builder();
init(builder, grammarAccess);
this.mappings = builder.build();
}
public String getRuleName(AbstractElement element) {
return mappings.get(element);
}
private static void init(ImmutableMap.Builder<AbstractElement, String> builder, TestLanguageGrammarAccess grammarAccess) {
builder.put(grammarAccess.getMemberAccess().getAlternatives(), "rule__Member__Alternatives");
builder.put(grammarAccess.getTypeAccess().getAlternatives_0(), "rule__Type__Alternatives_0");
builder.put(grammarAccess.getPrimitiveTypeAccess().getNameAlternatives_0(), "rule__PrimitiveType__NameAlternatives_0");
builder.put(grammarAccess.getTypeDeclarationAccess().getGroup(), "rule__TypeDeclaration__Group__0");
builder.put(grammarAccess.getTypeDeclarationAccess().getGroup_2(), "rule__TypeDeclaration__Group_2__0");
builder.put(grammarAccess.getPropertyAccess().getGroup(), "rule__Property__Group__0");
builder.put(grammarAccess.getTypeAccess().getGroup(), "rule__Type__Group__0");
builder.put(grammarAccess.getTypeAccess().getGroup_1(), "rule__Type__Group_1__0");
builder.put(grammarAccess.getOperationAccess().getGroup(), "rule__Operation__Group__0");
builder.put(grammarAccess.getOperationAccess().getGroup_4(), "rule__Operation__Group_4__0");
builder.put(grammarAccess.getOperationAccess().getGroup_4_1(), "rule__Operation__Group_4_1__0");
builder.put(grammarAccess.getOperationAccess().getGroup_6(), "rule__Operation__Group_6__0");
builder.put(grammarAccess.getOperationCallAccess().getGroup(), "rule__OperationCall__Group__0");
builder.put(grammarAccess.getOperationCallAccess().getGroup_2(), "rule__OperationCall__Group_2__0");
builder.put(grammarAccess.getOperationCallAccess().getGroup_2_1(), "rule__OperationCall__Group_2_1__0");
builder.put(grammarAccess.getParameterAccess().getGroup(), "rule__Parameter__Group__0");
builder.put(grammarAccess.getModelAccess().getTypesAssignment(), "rule__Model__TypesAssignment");
builder.put(grammarAccess.getTypeDeclarationAccess().getNameAssignment_1(), "rule__TypeDeclaration__NameAssignment_1");
builder.put(grammarAccess.getTypeDeclarationAccess().getSuperTypeAssignment_2_1(), "rule__TypeDeclaration__SuperTypeAssignment_2_1");
builder.put(grammarAccess.getTypeDeclarationAccess().getMembersAssignment_4(), "rule__TypeDeclaration__MembersAssignment_4");
builder.put(grammarAccess.getPropertyAccess().getTypeAssignment_0(), "rule__Property__TypeAssignment_0");
builder.put(grammarAccess.getPropertyAccess().getNameAssignment_1(), "rule__Property__NameAssignment_1");
builder.put(grammarAccess.getTypeAccess().getArrayDiemensionsAssignment_1_0(), "rule__Type__ArrayDiemensionsAssignment_1_0");
builder.put(grammarAccess.getOperationAccess().getNameAssignment_2(), "rule__Operation__NameAssignment_2");
builder.put(grammarAccess.getOperationAccess().getParamsAssignment_4_0(), "rule__Operation__ParamsAssignment_4_0");
builder.put(grammarAccess.getOperationAccess().getParamsAssignment_4_1_1(), "rule__Operation__ParamsAssignment_4_1_1");
builder.put(grammarAccess.getOperationAccess().getReturnTypeAssignment_6_1(), "rule__Operation__ReturnTypeAssignment_6_1");
builder.put(grammarAccess.getOperationAccess().getOperationCallAssignment_8(), "rule__Operation__OperationCallAssignment_8");
builder.put(grammarAccess.getOperationCallAccess().getOperationAssignment_0(), "rule__OperationCall__OperationAssignment_0");
builder.put(grammarAccess.getOperationCallAccess().getParamsAssignment_2_0(), "rule__OperationCall__ParamsAssignment_2_0");
builder.put(grammarAccess.getOperationCallAccess().getParamsAssignment_2_1_1(), "rule__OperationCall__ParamsAssignment_2_1_1");
builder.put(grammarAccess.getParameterAccess().getNameAssignment_1(), "rule__Parameter__NameAssignment_1");
builder.put(grammarAccess.getParameterAccess().getTypeAssignment_3(), "rule__Parameter__TypeAssignment_3");
builder.put(grammarAccess.getTypeReferenceAccess().getTypeRefAssignment(), "rule__TypeReference__TypeRefAssignment");
builder.put(grammarAccess.getPrimitiveTypeAccess().getNameAssignment(), "rule__PrimitiveType__NameAssignment");
}
}
@Inject
private NameMappings nameMappings;
@Inject
private TestLanguageGrammarAccess grammarAccess;
private Map<AbstractElement, String> nameMappings;
@Override
protected InternalTestLanguageParser createParser() {
InternalTestLanguageParser result = new InternalTestLanguageParser(null);
@ -31,51 +88,9 @@ public class TestLanguageParser extends AbstractContentAssistParser {
@Override
protected String getRuleName(AbstractElement element) {
if (nameMappings == null) {
nameMappings = new HashMap<AbstractElement, String>() {
private static final long serialVersionUID = 1L;
{
put(grammarAccess.getMemberAccess().getAlternatives(), "rule__Member__Alternatives");
put(grammarAccess.getTypeAccess().getAlternatives_0(), "rule__Type__Alternatives_0");
put(grammarAccess.getPrimitiveTypeAccess().getNameAlternatives_0(), "rule__PrimitiveType__NameAlternatives_0");
put(grammarAccess.getTypeDeclarationAccess().getGroup(), "rule__TypeDeclaration__Group__0");
put(grammarAccess.getTypeDeclarationAccess().getGroup_2(), "rule__TypeDeclaration__Group_2__0");
put(grammarAccess.getPropertyAccess().getGroup(), "rule__Property__Group__0");
put(grammarAccess.getTypeAccess().getGroup(), "rule__Type__Group__0");
put(grammarAccess.getTypeAccess().getGroup_1(), "rule__Type__Group_1__0");
put(grammarAccess.getOperationAccess().getGroup(), "rule__Operation__Group__0");
put(grammarAccess.getOperationAccess().getGroup_4(), "rule__Operation__Group_4__0");
put(grammarAccess.getOperationAccess().getGroup_4_1(), "rule__Operation__Group_4_1__0");
put(grammarAccess.getOperationAccess().getGroup_6(), "rule__Operation__Group_6__0");
put(grammarAccess.getOperationCallAccess().getGroup(), "rule__OperationCall__Group__0");
put(grammarAccess.getOperationCallAccess().getGroup_2(), "rule__OperationCall__Group_2__0");
put(grammarAccess.getOperationCallAccess().getGroup_2_1(), "rule__OperationCall__Group_2_1__0");
put(grammarAccess.getParameterAccess().getGroup(), "rule__Parameter__Group__0");
put(grammarAccess.getModelAccess().getTypesAssignment(), "rule__Model__TypesAssignment");
put(grammarAccess.getTypeDeclarationAccess().getNameAssignment_1(), "rule__TypeDeclaration__NameAssignment_1");
put(grammarAccess.getTypeDeclarationAccess().getSuperTypeAssignment_2_1(), "rule__TypeDeclaration__SuperTypeAssignment_2_1");
put(grammarAccess.getTypeDeclarationAccess().getMembersAssignment_4(), "rule__TypeDeclaration__MembersAssignment_4");
put(grammarAccess.getPropertyAccess().getTypeAssignment_0(), "rule__Property__TypeAssignment_0");
put(grammarAccess.getPropertyAccess().getNameAssignment_1(), "rule__Property__NameAssignment_1");
put(grammarAccess.getTypeAccess().getArrayDiemensionsAssignment_1_0(), "rule__Type__ArrayDiemensionsAssignment_1_0");
put(grammarAccess.getOperationAccess().getNameAssignment_2(), "rule__Operation__NameAssignment_2");
put(grammarAccess.getOperationAccess().getParamsAssignment_4_0(), "rule__Operation__ParamsAssignment_4_0");
put(grammarAccess.getOperationAccess().getParamsAssignment_4_1_1(), "rule__Operation__ParamsAssignment_4_1_1");
put(grammarAccess.getOperationAccess().getReturnTypeAssignment_6_1(), "rule__Operation__ReturnTypeAssignment_6_1");
put(grammarAccess.getOperationAccess().getOperationCallAssignment_8(), "rule__Operation__OperationCallAssignment_8");
put(grammarAccess.getOperationCallAccess().getOperationAssignment_0(), "rule__OperationCall__OperationAssignment_0");
put(grammarAccess.getOperationCallAccess().getParamsAssignment_2_0(), "rule__OperationCall__ParamsAssignment_2_0");
put(grammarAccess.getOperationCallAccess().getParamsAssignment_2_1_1(), "rule__OperationCall__ParamsAssignment_2_1_1");
put(grammarAccess.getParameterAccess().getNameAssignment_1(), "rule__Parameter__NameAssignment_1");
put(grammarAccess.getParameterAccess().getTypeAssignment_3(), "rule__Parameter__TypeAssignment_3");
put(grammarAccess.getTypeReferenceAccess().getTypeRefAssignment(), "rule__TypeReference__TypeRefAssignment");
put(grammarAccess.getPrimitiveTypeAccess().getNameAssignment(), "rule__PrimitiveType__NameAssignment");
}
};
}
return nameMappings.get(element);
return nameMappings.getRuleName(element);
}
@Override
protected String[] getInitialHiddenTokens() {
return new String[] { "RULE_WS", "RULE_ML_COMMENT", "RULE_SL_COMMENT" };
@ -88,4 +103,12 @@ public class TestLanguageParser extends AbstractContentAssistParser {
public void setGrammarAccess(TestLanguageGrammarAccess grammarAccess) {
this.grammarAccess = grammarAccess;
}
public NameMappings getNameMappings() {
return nameMappings;
}
public void setNameMappings(NameMappings nameMappings) {
this.nameMappings = nameMappings;
}
}

View file

@ -71,17 +71,15 @@ public class PartialSerializationTestLanguageSyntacticSequencer extends Abstract
* This ambiguous syntax occurs at:
* (rule start) '#1' (ambiguity) '{' 'ref' ref=[Node|QualifiedName]
* (rule start) '#1' (ambiguity) '{' children+=Node
* (rule start) '#1' (ambiguity) (';' | ('{' '}')) (rule start)
* (rule start) '#1' (ambiguity) (('{' '}') | ';') (rule start)
* (rule start) (ambiguity) '{' 'ref' ref=[Node|QualifiedName]
* (rule start) (ambiguity) '{' children+=Node
* (rule start) (ambiguity) (('{' '}') | ';') (rule start)
* imports+=Import (ambiguity) '{' 'ref' ref=[Node|QualifiedName]
* imports+=Import (ambiguity) '{' children+=Node
* imports+=Import (ambiguity) (';' | ('{' '}')) (rule end)
* imports+=Import (ambiguity) (('{' '}') | ';') (rule end)
* name=ID (ambiguity) '{' 'ref' ref=[Node|QualifiedName]
* name=ID (ambiguity) '{' children+=Node
* name=ID (ambiguity) (';' | ('{' '}')) (rule end)
* name=ID (ambiguity) (('{' '}') | ';') (rule end)
*/
protected void emit_Node_RefsKeyword_3_0_q(EObject semanticObject, ISynNavigable transition, List<INode> nodes) {
@ -90,7 +88,7 @@ public class PartialSerializationTestLanguageSyntacticSequencer extends Abstract
/**
* Ambiguous syntax:
* ';' | ('{' '}')
* ('{' '}') | ';'
*
* This ambiguous syntax occurs at:
* (rule start) '#1' 'refs'? (ambiguity) (rule start)

View file

@ -260,7 +260,8 @@ public class IndentationAwareUiTestLanguageGrammarAccess extends AbstractGrammar
return getChildListAccess().getRule();
}
//@ Override terminal SL_COMMENT:
//@Override
//terminal SL_COMMENT:
// '//' !('\n' | '\r')*;
public TerminalRule getSL_COMMENTRule() {
return tSL_COMMENT;

View file

@ -7,30 +7,13 @@
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.TokenSource;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.LexerIdeBindings;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.AbstractInternalContentAssistParser;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.InfiniteRecursion;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.Lexer;
import org.eclipse.xtext.ide.editor.partialEditing.IPartialEditingContentAssistParser;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
import org.eclipse.xtext.xtext.RuleNames;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;
@ -38,217 +21,19 @@ import com.google.inject.name.Named;
/**
* @since 2.9
*/
public abstract class AbstractContentAssistParser extends BaseContentAssistParser implements IContentAssistParser, IPartialEditingContentAssistParser {
public abstract class AbstractContentAssistParser
extends BaseContentAssistParser<FollowElement, LookAheadTerminal, AbstractInternalContentAssistParser>
implements IContentAssistParser, IPartialEditingContentAssistParser {
@Inject
@Named(LexerIdeBindings.CONTENT_ASSIST)
private Provider<Lexer> lexerProvider;
@Inject
private RuleNames ruleNames;
private AbstractRule entryRule;
@Inject
private void initEntryRule(IGrammarAccess grammar) {
initializeFor(grammar.getGrammar().getRules().get(0));
}
@Override
public void initializeFor(AbstractRule rule) {
this.entryRule = rule;
}
public AbstractRule getEntryRule() {
return entryRule;
}
@Override
protected TokenSource createLexer(CharStream stream) {
Lexer lexer = lexerProvider.get();
lexer.setCharStream(stream);
return lexer;
}
@Override
public Collection<FollowElement> getFollowElements(FollowElement element) {
if (element.getLookAhead() <= 1)
throw new IllegalArgumentException("lookahead may not be less than or equal to 1");
Collection<FollowElement> result = new ArrayList<FollowElement>();
for(AbstractElement elementToParse: getElementsToParse(element)) {
elementToParse = unwrapSingleElementGroups(elementToParse);
String ruleName = getRuleName(elementToParse);
String[][] allRuleNames = getRequiredRuleNames(ruleName, element.getParamStack(), elementToParse);
for (String[] ruleNames: allRuleNames) {
for(int i = 0; i < ruleNames.length; i++) {
AbstractInternalContentAssistParser parser = createParser();
parser.setUnorderedGroupHelper(createUnorderedGroupHelper());
parser.getUnorderedGroupHelper().initializeWith(parser);
ObservableXtextTokenStream tokens = setTokensFromFollowElement(parser, element);
tokens.setListener(parser);
parser.getGrammarElements().addAll(element.getTrace());
parser.getGrammarElements().add(elementToParse);
parser.getLocalTrace().addAll(element.getLocalTrace());
parser.getLocalTrace().add(elementToParse);
parser.getParamStack().addAll(element.getParamStack());
if (elementToParse instanceof UnorderedGroup && element.getGrammarElement() == elementToParse) {
UnorderedGroup group = (UnorderedGroup) elementToParse;
IUnorderedGroupHelper helper = getInitializedUnorderedGroupHelper(element, parser, group);
parser.setUnorderedGroupHelper(ignoreFirstEntrance(helper));
}
Collection<FollowElement> elements = getFollowElements(parser, elementToParse, ruleNames, i);
result.addAll(elements);
}
}
}
return result;
}
/**
* @since 2.14
*/
protected ObservableXtextTokenStream setTokensFromFollowElement(AbstractInternalContentAssistParser parser,
FollowElement element) {
final Iterator<LookAheadTerminal> iter = element.getLookAheadTerminals().iterator();
ObservableXtextTokenStream tokens = new ObservableXtextTokenStream(new LookAheadBasedTokenSource(iter), parser);
parser.setTokenStream(tokens);
return tokens;
}
/**
* @since 2.14
*/
protected IUnorderedGroupHelper getInitializedUnorderedGroupHelper(FollowElement element,
AbstractInternalContentAssistParser parser, UnorderedGroup group) {
final IUnorderedGroupHelper helper = parser.getUnorderedGroupHelper();
helper.enter(group);
for(AbstractElement consumed: element.getHandledUnorderedGroupElements()) {
parser.before(consumed);
helper.select(group, group.getElements().indexOf(consumed));
helper.returnFromSelection(group);
parser.after(consumed);
}
return helper;
}
/**
* @since 2.14
*/
protected Collection<FollowElement> getFollowElements(
final AbstractInternalContentAssistParser parser,
final AbstractElement elementToParse,
String[] ruleNames,
final int startIndex) {
try {
EofListener listener = createEofListener(parser, elementToParse);
int i = startIndex;
Collection<FollowElement> result = null;
while(i < ruleNames.length && !listener.wasEof && listener.consumedSomething) {
listener.reset();
String ruleName = ruleNames[i];
result = getFollowElements(parser, ruleName, true);
if (i == ruleNames.length - 1 && !GrammarUtil.isMultipleCardinality(elementToParse)) {
if (listener.consumedSomething || listener.announcedEofWithLA)
return result;
return Collections.emptyList();
}
if (!listener.wasEof && ruleNames.length != 1)
i++;
if (ruleNames.length > 2)
throw new IllegalArgumentException("The following lines assume that we have at most two rules to call.");
}
return result;
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @since 2.14
*/
protected EofListener createEofListener(final AbstractInternalContentAssistParser parser,
final AbstractElement elementToParse) {
return new EofListener(parser, elementToParse);
}
/**
* @since 2.14
*/
protected Set<FollowElement> getFollowElements(final AbstractInternalContentAssistParser parser, String ruleName, boolean swallowInfiniteRecursion)
throws Exception {
Method method = parser.getClass().getMethod(ruleName);
method.setAccessible(true);
try {
method.invoke(parser);
} catch(InvocationTargetException targetException) {
Throwable cause = targetException.getCause();
if (cause instanceof InfiniteRecursion) {
if (swallowInfiniteRecursion) {
return parser.getFollowElements();
} else {
throw (InfiniteRecursion) cause;
}
}
throw targetException;
}
return parser.getFollowElements();
}
/**
* @since 2.14
*/
protected Collection<AbstractElement> getElementsToParse(FollowElement element) {
return getElementsToParse(element.getGrammarElement(), element.getHandledUnorderedGroupElements());
}
protected abstract AbstractInternalContentAssistParser createParser();
protected Collection<FollowElement> getFollowElements(AbstractInternalContentAssistParser parser) {
return getFollowElements(parser, entryRule);
}
protected Collection<FollowElement> getFollowElements(AbstractInternalContentAssistParser parser,
AbstractRule rule) {
String ruleName = ruleNames.getAntlrRuleName(rule);
return getFollowElements(parser, ruleName);
}
protected Collection<FollowElement> getFollowElements(AbstractInternalContentAssistParser parser, String ruleName) {
try {
return getFollowElements(parser, ruleName, false);
} catch (InfiniteRecursion e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected abstract String[] getInitialHiddenTokens();
@Override
public Collection<FollowElement> getFollowElements(String input, boolean strict) {
TokenSource tokenSource = createTokenSource(input);
AbstractInternalContentAssistParser parser = createParser();
parser.setStrict(strict);
ObservableXtextTokenStream tokens = new ObservableXtextTokenStream(tokenSource, parser);
tokens.setInitialHiddenTokens(getInitialHiddenTokens());
parser.setTokenStream(tokens);
IUnorderedGroupHelper helper = createUnorderedGroupHelper();
parser.setUnorderedGroupHelper(helper);
helper.initializeWith(parser);
tokens.setListener(parser);
try {
return Lists.newArrayList(getFollowElements(parser));
} catch(InfiniteRecursion infinite) {
return Lists.newArrayList(parser.getFollowElements());
}
}
/**
* @since 2.14
*/
protected RuleNames getRuleNames() {
return ruleNames;
}
}

View file

@ -9,26 +9,8 @@ package org.eclipse.xtext.ide.editor.contentassist.antlr;
import java.util.Collection;
import org.antlr.runtime.TokenSource;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.AbstractInternalContentAssistParser;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.InfiniteRecursion;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
import org.eclipse.xtext.xtext.RuleNames;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
/**
@ -41,120 +23,9 @@ public abstract class AbstractPartialContentAssistParser extends AbstractContent
@Inject
private EntryPointFinder entryPointFinder;
@Inject
private RuleNames ruleNames;
@Override
public Collection<FollowElement> getFollowElements(IParseResult parseResult, int offset, boolean strict) {
ICompositeNode entryPoint = entryPointFinder.findEntryPoint(parseResult, offset);
if (entryPoint != null) {
String parseMe = getTextToParse(parseResult, entryPoint, offset);
TokenSource tokenSource = createTokenSource(parseMe);
AbstractInternalContentAssistParser parser = createParser();
parser.setStrict(strict);
ObservableXtextTokenStream tokens = new ObservableXtextTokenStream(tokenSource, parser);
tokens.setInitialHiddenTokens(getInitialHiddenTokens());
parser.setTokenStream(tokens);
IUnorderedGroupHelper helper = createUnorderedGroupHelper();
parser.setUnorderedGroupHelper(helper);
helper.initializeWith(parser);
tokens.setListener(parser);
try {
Collection<FollowElement> followElements = getFollowElements(parser, getEntryGrammarElement(entryPoint));
return Lists.newArrayList(followElements);
} catch (InfiniteRecursion infinite) {
return Lists.newArrayList(parser.getFollowElements());
}
} else {
String text = parseResult.getRootNode().getText();
String parseMe = text.substring(0, offset);
initializeFor(NodeModelUtils.getEntryParserRule(parseResult.getRootNode()));
Collection<FollowElement> followElements = getFollowElements(parseMe, strict);
return followElements;
}
return getFollowElements(parseResult, entryPointFinder, offset, strict);
}
protected AbstractElement getEntryGrammarElement(ICompositeNode entryPoint) {
EObject grammarElement = entryPoint.getGrammarElement();
if (grammarElement instanceof RuleCall) {
AbstractRule rule = ((RuleCall) grammarElement).getRule();
if (rule instanceof ParserRule) {
if (!GrammarUtil.isMultipleCardinality(rule.getAlternatives())) {
grammarElement = rule.getAlternatives();
}
}
} else if (grammarElement instanceof ParserRule) {
grammarElement = ((ParserRule) grammarElement).getAlternatives();
} else if (grammarElement instanceof CrossReference) {
grammarElement = GrammarUtil.containingAssignment(grammarElement);
}
AbstractElement result = (AbstractElement) grammarElement;
if (result instanceof Action) {
return getEntryGrammarElement((ICompositeNode) entryPoint.getFirstChild());
}
return result;
}
protected String getTextToParse(IParseResult parseResult, ICompositeNode entryPoint, int offset) {
StringBuilder result = new StringBuilder(offset - entryPoint.getTotalOffset());
appendTextToParse(entryPoint, offset, false, result);
return result.toString();
}
protected boolean appendTextToParse(ICompositeNode node, int offset, boolean skipOptional, StringBuilder result) {
for (INode child : node.getChildren()) {
if (child instanceof ILeafNode) {
String text = child.getText();
if (child.getTotalEndOffset() >= offset) {
String sub = text.substring(0, offset - child.getTotalOffset());
result.append(sub);
return true;
} else {
result.append(text);
}
} else {
if (!skipOptional) {
if (appendTextToParse((ICompositeNode) child, offset, child.getTotalEndOffset() < offset, result)) {
return true;
}
} else {
String skippedAs = getReplacement((ICompositeNode) child);
if (skippedAs != null) {
result.append(skippedAs);
} else {
if (appendTextToParse((ICompositeNode) child, offset, true, result)) {
return true;
}
}
}
}
}
return false;
}
/**
* Returns a syntactically correct replacement for nodes whose real content does not need to be parsed.
* @return the replacement or <code>null</code>
*/
protected String getReplacement(ICompositeNode node) {
return null;
}
protected Collection<FollowElement> getFollowElements(AbstractInternalContentAssistParser parser,
AbstractElement entryPoint) {
String ruleName = getRuleName(entryPoint);
if (ruleName == null) {
if (entryPoint instanceof RuleCall) {
RuleCall call = (RuleCall) entryPoint;
AbstractRule rule = call.getRule();
if (rule instanceof ParserRule) {
ruleName = ruleNames.getAntlrRuleName(rule);
}
}
}
if (ruleName == null) {
throw new IllegalStateException("entryPoint: " + entryPoint);
}
return getFollowElements(parser, ruleName);
}
}

View file

@ -7,51 +7,268 @@
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.TokenSource;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.Action;
import org.eclipse.xtext.Alternatives;
import org.eclipse.xtext.CompoundElement;
import org.eclipse.xtext.CrossReference;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.Group;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.ParserRule;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.BaseInternalContentAssistParser;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.InfiniteRecursion;
import org.eclipse.xtext.nodemodel.ICompositeNode;
import org.eclipse.xtext.nodemodel.ILeafNode;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.util.NodeModelUtils;
import org.eclipse.xtext.parser.IParseResult;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
import org.eclipse.xtext.xtext.RuleNames;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.google.inject.Provider;
/**
* Abstract base type for the {@link AbstractContentAssistParser} and the deprecated
* equivalent in the xtext.ui bundle.
* Abstract base type for the {@link AbstractContentAssistParser} and the deprecated equivalent in the xtext.ui bundle.
*
* @author Sebastian Zarnekow - Initial contribution and API
* @since 2.14
*/
public abstract class BaseContentAssistParser {
public abstract class BaseContentAssistParser<FE extends BaseFollowElement<LATerminal>, LATerminal extends ILookAheadTerminal, InternalParser extends BaseInternalContentAssistParser<FE, LATerminal>> {
@Inject
private Provider<IUnorderedGroupHelper> unorderedGroupHelper;
@Inject
private RequiredRuleNameComputer requiredRuleNameComputer;
@Inject
private RuleNames ruleNames;
private AbstractRule entryRule;
/**
* Create a token source for the given input based on the bound lexer.
*/
protected TokenSource createTokenSource(String input) {
return createLexer(new ANTLRStringStream(input));
}
protected abstract TokenSource createLexer(CharStream stream);
/**
* Returns the elementToParse or the innermost element if the elementToParse is
* a (parameterized) group that contains only a single element.
* Create a token source for the given input based on the bound lexer.
*/
protected abstract TokenSource createLexer(CharStream stream);
public Collection<FE> getFollowElements(FE element) {
if (element.getLookAhead() <= 1)
throw new IllegalArgumentException("lookahead may not be less than or equal to 1");
Collection<FE> result = new ArrayList<FE>();
for (AbstractElement elementToParse : getElementsToParse(element)) {
elementToParse = unwrapSingleElementGroups(elementToParse);
String ruleName = getRuleName(elementToParse);
String[][] allRuleNames = getRequiredRuleNames(ruleName, element.getParamStack(), elementToParse);
for (String[] ruleNames : allRuleNames) {
for (int i = 0; i < ruleNames.length; i++) {
InternalParser parser = createParser();
parser.setUnorderedGroupHelper(createUnorderedGroupHelper());
parser.getUnorderedGroupHelper().initializeWith(parser);
ObservableXtextTokenStream tokens = setTokensFromFollowElement(parser, element);
tokens.setListener(parser);
parser.getGrammarElements().addAll(element.getTrace());
parser.getGrammarElements().add(elementToParse);
parser.getLocalTrace().addAll(element.getLocalTrace());
parser.getLocalTrace().add(elementToParse);
parser.getParamStack().addAll(element.getParamStack());
if (elementToParse instanceof UnorderedGroup && element.getGrammarElement() == elementToParse) {
UnorderedGroup group = (UnorderedGroup) elementToParse;
IUnorderedGroupHelper helper = getInitializedUnorderedGroupHelper(element, parser, group);
parser.setUnorderedGroupHelper(ignoreFirstEntrance(helper));
}
Collection<FE> elements = getFollowElements(parser, elementToParse, ruleNames, i);
result.addAll(elements);
}
}
}
return result;
}
protected abstract InternalParser createParser();
/**
* @since 2.14
*/
protected ObservableXtextTokenStream setTokensFromFollowElement(InternalParser parser, FE element) {
final Iterator<LATerminal> iter = element.getLookAheadTerminals().iterator();
LookAheadBasedTokenSource tokenSource = new LookAheadBasedTokenSource(iter);
ObservableXtextTokenStream tokens = createObservableTokenStream(tokenSource, parser);
parser.setTokenStream(tokens);
return tokens;
}
/**
* @since 2.14
*/
protected Collection<FE> getFollowElements(final InternalParser parser, final AbstractElement elementToParse,
String[] ruleNames, final int startIndex) {
try {
EofListener listener = createEofListener(parser, elementToParse);
int i = startIndex;
Collection<FE> result = null;
while (i < ruleNames.length && !listener.wasEof && listener.consumedSomething) {
listener.reset();
String ruleName = ruleNames[i];
result = getFollowElements(parser, ruleName, true);
if (i == ruleNames.length - 1 && !GrammarUtil.isMultipleCardinality(elementToParse)) {
if (listener.consumedSomething || listener.announcedEofWithLA)
return result;
return Collections.emptyList();
}
if (!listener.wasEof && ruleNames.length != 1)
i++;
if (ruleNames.length > 2)
throw new IllegalArgumentException(
"The following lines assume that we have at most two rules to call.");
}
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @since 2.14
*/
protected EofListener createEofListener(final InternalParser parser, final AbstractElement elementToParse) {
return new EofListener(parser, elementToParse);
}
/**
* @since 2.14
*/
protected Set<FE> getFollowElements(final InternalParser parser, String ruleName, boolean swallowInfiniteRecursion)
throws Exception {
Method method = parser.getClass().getMethod(ruleName);
method.setAccessible(true);
try {
method.invoke(parser);
} catch (InvocationTargetException targetException) {
Throwable cause = targetException.getCause();
if (cause instanceof InfiniteRecursion) {
if (swallowInfiniteRecursion) {
return parser.getFollowElements();
} else {
throw (InfiniteRecursion) cause;
}
}
throw targetException;
}
return parser.getFollowElements();
}
/**
* @since 2.14
*/
protected Collection<AbstractElement> getElementsToParse(FE element) {
return getElementsToParse(element.getGrammarElement(), element.getHandledUnorderedGroupElements());
}
/**
* @since 2.14
*/
protected ObservableXtextTokenStream createObservableTokenStream(LookAheadBasedTokenSource tokenSource,
InternalParser parser) {
return new ObservableXtextTokenStream(tokenSource, parser);
}
/**
* @since 2.14
*/
protected IUnorderedGroupHelper getInitializedUnorderedGroupHelper(FE element, InternalParser parser,
UnorderedGroup group) {
final IUnorderedGroupHelper helper = parser.getUnorderedGroupHelper();
helper.enter(group);
for (AbstractElement consumed : element.getHandledUnorderedGroupElements()) {
parser.before(consumed);
helper.select(group, group.getElements().indexOf(consumed));
helper.returnFromSelection(group);
parser.after(consumed);
}
return helper;
}
@Inject
private void initEntryRule(IGrammarAccess grammar) {
initializeFor(grammar.getGrammar().getRules().get(0));
}
public void initializeFor(AbstractRule rule) {
this.entryRule = rule;
}
public AbstractRule getEntryRule() {
return entryRule;
}
protected Collection<FE> getFollowElements(InternalParser parser) {
return getFollowElements(parser, entryRule);
}
protected Collection<FE> getFollowElements(InternalParser parser, AbstractRule rule) {
String ruleName = ruleNames.getAntlrRuleName(rule);
return getFollowElements(parser, ruleName);
}
protected Collection<FE> getFollowElements(InternalParser parser, String ruleName) {
try {
return getFollowElements(parser, ruleName, false);
} catch (InfiniteRecursion e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
protected abstract String[] getInitialHiddenTokens();
public Collection<FE> getFollowElements(String input, boolean strict) {
TokenSource tokenSource = createTokenSource(input);
InternalParser parser = createParser();
parser.setStrict(strict);
ObservableXtextTokenStream tokens = new ObservableXtextTokenStream(tokenSource, parser);
tokens.setInitialHiddenTokens(getInitialHiddenTokens());
parser.setTokenStream(tokens);
IUnorderedGroupHelper helper = createUnorderedGroupHelper();
parser.setUnorderedGroupHelper(helper);
helper.initializeWith(parser);
tokens.setListener(parser);
try {
return Lists.newArrayList(getFollowElements(parser));
} catch (InfiniteRecursion infinite) {
return Lists.newArrayList(parser.getFollowElements());
}
}
/**
* Returns the elementToParse or the innermost element if the elementToParse is a (parameterized) group that
* contains only a single element.
*/
protected AbstractElement unwrapSingleElementGroups(AbstractElement elementToParse) {
if (elementToParse instanceof Group) {
@ -62,18 +279,19 @@ public abstract class BaseContentAssistParser {
}
return elementToParse;
}
/**
* Returns the root element or its alternative branches if it is an {@link Alternatives} or an {@link UnorderedGroup}.
* In case of an {@link UnorderedGroup} the result contains only the elements that are not yet processed up to the
* relevant cursor position.
* Returns the root element or its alternative branches if it is an {@link Alternatives} or an
* {@link UnorderedGroup}. In case of an {@link UnorderedGroup} the result contains only the elements that are not
* yet processed up to the relevant cursor position.
*/
protected Collection<AbstractElement> getElementsToParse(AbstractElement root, List<AbstractElement> handledUnorderedGroupElements) {
protected Collection<AbstractElement> getElementsToParse(AbstractElement root,
List<AbstractElement> handledUnorderedGroupElements) {
if (root instanceof UnorderedGroup) {
if (handledUnorderedGroupElements.isEmpty())
return ((CompoundElement) root).getElements();
List<AbstractElement> result = Lists.newArrayList(root);
for(AbstractElement child: ((UnorderedGroup) root).getElements()) {
for (AbstractElement child : ((UnorderedGroup) root).getElements()) {
if (!handledUnorderedGroupElements.contains(child)) {
result.add(child);
}
@ -82,14 +300,14 @@ public abstract class BaseContentAssistParser {
}
return getElementsToParse(root);
}
/**
* Factory method for the {@link IgnoreFirstEntranceUnorderedGroupHelper}.
*/
protected IUnorderedGroupHelper ignoreFirstEntrance(final IUnorderedGroupHelper helper) {
return new IgnoreFirstEntranceUnorderedGroupHelper(helper);
}
/**
* Return the element itself or its components if it is an {@link Alternatives}.
*/
@ -98,25 +316,27 @@ public abstract class BaseContentAssistParser {
return ((CompoundElement) root).getElements();
return Collections.singleton(root);
}
protected String[][] getRequiredRuleNames(String ruleName, List<Integer> paramStack, AbstractElement elementToParse) {
return requiredRuleNameComputer.getRequiredRuleNames(new RequiredRuleNameComputer.Param(ruleName, paramStack, elementToParse) {
@Override
public String getBaseRuleName(AbstractElement element) {
return getRuleName(element);
}
});
protected String[][] getRequiredRuleNames(String ruleName, List<Integer> paramStack,
AbstractElement elementToParse) {
return requiredRuleNameComputer
.getRequiredRuleNames(new RequiredRuleNameComputer.Param(ruleName, paramStack, elementToParse) {
@Override
public String getBaseRuleName(AbstractElement element) {
return getRuleName(element);
}
});
}
protected abstract String getRuleName(AbstractElement element);
/**
* Creates a new {@link IUnorderedGroupHelper} that is not yet initialized.
*/
protected IUnorderedGroupHelper createUnorderedGroupHelper() {
return getUnorderedGroupHelper().get();
}
/**
* Public for testing purpose.
*/
@ -130,18 +350,139 @@ public abstract class BaseContentAssistParser {
public Provider<IUnorderedGroupHelper> getUnorderedGroupHelper() {
return unorderedGroupHelper;
}
/**
* Public for testing purpose.
*/
public void setRequiredRuleNameComputer(RequiredRuleNameComputer requiredRuleNameComputer) {
this.requiredRuleNameComputer = requiredRuleNameComputer;
}
/**
* Public for testing purpose.
*/
public RequiredRuleNameComputer getRequiredRuleNameComputer() {
return requiredRuleNameComputer;
}
/**
* @since 2.14
*/
protected RuleNames getRuleNames() {
return ruleNames;
}
public Collection<FE> getFollowElements(IParseResult parseResult, EntryPointFinder entryPointFinder, int offset,
boolean strict) {
ICompositeNode entryPoint = entryPointFinder.findEntryPoint(parseResult, offset);
if (entryPoint != null) {
String parseMe = getTextToParse(parseResult, entryPoint, offset);
TokenSource tokenSource = createTokenSource(parseMe);
InternalParser parser = createParser();
parser.setStrict(strict);
ObservableXtextTokenStream tokens = new ObservableXtextTokenStream(tokenSource, parser);
tokens.setInitialHiddenTokens(getInitialHiddenTokens());
parser.setTokenStream(tokens);
IUnorderedGroupHelper helper = createUnorderedGroupHelper();
parser.setUnorderedGroupHelper(helper);
helper.initializeWith(parser);
tokens.setListener(parser);
try {
Collection<FE> followElements = getFollowElements(parser, getEntryGrammarElement(entryPoint));
return Lists.newArrayList(followElements);
} catch (InfiniteRecursion infinite) {
return Lists.newArrayList(parser.getFollowElements());
}
} else {
String text = parseResult.getRootNode().getText();
String parseMe = text.substring(0, offset);
initializeFor(NodeModelUtils.getEntryParserRule(parseResult.getRootNode()));
Collection<FE> followElements = getFollowElements(parseMe, strict);
return followElements;
}
}
protected AbstractElement getEntryGrammarElement(ICompositeNode entryPoint) {
EObject grammarElement = entryPoint.getGrammarElement();
if (grammarElement instanceof RuleCall) {
AbstractRule rule = ((RuleCall) grammarElement).getRule();
if (rule instanceof ParserRule) {
if (!GrammarUtil.isMultipleCardinality(rule.getAlternatives())) {
grammarElement = rule.getAlternatives();
}
}
} else if (grammarElement instanceof ParserRule) {
grammarElement = ((ParserRule) grammarElement).getAlternatives();
} else if (grammarElement instanceof CrossReference) {
grammarElement = GrammarUtil.containingAssignment(grammarElement);
}
AbstractElement result = (AbstractElement) grammarElement;
if (result instanceof Action) {
return getEntryGrammarElement((ICompositeNode) entryPoint.getFirstChild());
}
return result;
}
protected String getTextToParse(IParseResult parseResult, ICompositeNode entryPoint, int offset) {
StringBuilder result = new StringBuilder(offset - entryPoint.getTotalOffset());
appendTextToParse(entryPoint, offset, false, result);
return result.toString();
}
protected boolean appendTextToParse(ICompositeNode node, int offset, boolean skipOptional, StringBuilder result) {
for (INode child : node.getChildren()) {
if (child instanceof ILeafNode) {
String text = child.getText();
if (child.getTotalEndOffset() >= offset) {
String sub = text.substring(0, offset - child.getTotalOffset());
result.append(sub);
return true;
} else {
result.append(text);
}
} else {
if (!skipOptional) {
if (appendTextToParse((ICompositeNode) child, offset, child.getTotalEndOffset() < offset, result)) {
return true;
}
} else {
String skippedAs = getReplacement((ICompositeNode) child);
if (skippedAs != null) {
result.append(skippedAs);
} else {
if (appendTextToParse((ICompositeNode) child, offset, true, result)) {
return true;
}
}
}
}
}
return false;
}
/**
* Returns a syntactically correct replacement for nodes whose real content does not need to be parsed.
*
* @return the replacement or <code>null</code>
*/
protected String getReplacement(ICompositeNode node) {
return null;
}
protected Collection<FE> getFollowElements(InternalParser parser, AbstractElement entryPoint) {
String ruleName = getRuleName(entryPoint);
if (ruleName == null) {
if (entryPoint instanceof RuleCall) {
RuleCall call = (RuleCall) entryPoint;
AbstractRule rule = call.getRule();
if (rule instanceof ParserRule) {
ruleName = getRuleNames().getAntlrRuleName(rule);
}
}
}
if (ruleName == null) {
throw new IllegalStateException("entryPoint: " + entryPoint);
}
return getFollowElements(parser, ruleName);
}
}

View file

@ -0,0 +1,154 @@
/*******************************************************************************
* Copyright (c) 2017 itemis AG (http://www.itemis.de) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr;
import java.util.List;
import org.eclipse.xtext.AbstractElement;
/**
* @author Sebastian Zarnekow - Initial contribution and API
*
* @since 2.14
*/
public class BaseFollowElement<LATerminal extends ILookAheadTerminal> {
private AbstractElement currentGrammarElement;
private List<AbstractElement> trace;
private List<AbstractElement> localTrace;
private int lookAhead;
private List<Integer> paramStack;
private List<LATerminal> lookAheadTerminals;
private List<AbstractElement> handledUnorderedGroupElements;
public AbstractElement getGrammarElement() {
return currentGrammarElement;
}
public void setGrammarElement(AbstractElement grammarElement) {
this.currentGrammarElement = grammarElement;
}
public List<AbstractElement> getTrace() {
return trace;
}
public void setTrace(List<AbstractElement> trace) {
this.trace = trace;
}
public int getLookAhead() {
return lookAhead;
}
public void setLookAhead(int lookAhead) {
this.lookAhead = lookAhead;
}
public List<Integer> getParamStack() {
return paramStack;
}
public void setParamStack(List<Integer> paramStack) {
this.paramStack = paramStack;
}
public List<LATerminal> getLookAheadTerminals() {
return lookAheadTerminals;
}
public void setLookAheadTerminals(List<LATerminal> lookAheadTerminals) {
this.lookAheadTerminals = lookAheadTerminals;
}
public void setLocalTrace(List<AbstractElement> localTrace) {
this.localTrace = localTrace;
}
public List<AbstractElement> getLocalTrace() {
return localTrace;
}
public void setHandledUnorderedGroupElements(List<AbstractElement> handledUnorderedGroupElements) {
this.handledUnorderedGroupElements = handledUnorderedGroupElements;
}
public List<AbstractElement> getHandledUnorderedGroupElements() {
return handledUnorderedGroupElements;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((currentGrammarElement == null) ? 0 : currentGrammarElement.hashCode());
result = prime * result + ((localTrace == null) ? 0 : localTrace.hashCode());
result = prime * result + lookAhead;
result = prime * result + ((paramStack == null) ? 0 : paramStack.hashCode());
result = prime * result + ((lookAheadTerminals == null) ? 0 : lookAheadTerminals.hashCode());
result = prime * result + ((trace == null) ? 0 : trace.hashCode());
result = prime * result + ((handledUnorderedGroupElements == null) ? 0 : handledUnorderedGroupElements.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BaseFollowElement<?> other = (BaseFollowElement<?>) obj;
if (currentGrammarElement == null) {
if (other.currentGrammarElement != null)
return false;
}
else if (!currentGrammarElement.equals(other.currentGrammarElement))
return false;
if (localTrace == null) {
if (other.localTrace != null)
return false;
}
else if (!localTrace.equals(other.localTrace))
return false;
if (lookAhead != other.lookAhead)
return false;
if (paramStack == null) {
if (other.paramStack != null)
return false;
}
else if (!paramStack.equals(other.paramStack))
return false;
if (lookAheadTerminals == null) {
if (other.lookAheadTerminals != null)
return false;
}
else if (!lookAheadTerminals.equals(other.lookAheadTerminals))
return false;
if (trace == null) {
if (other.trace != null)
return false;
}
else if (!trace.equals(other.trace))
return false;
if (handledUnorderedGroupElements == null) {
if (other.handledUnorderedGroupElements != null)
return false;
}
else if (!handledUnorderedGroupElements.equals(other.handledUnorderedGroupElements))
return false;
return true;
}
@Override
public String toString() {
return "FollowElement: " + getGrammarElement() + " LA: " + getLookAhead();
}
}

View file

@ -12,6 +12,7 @@ import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.editor.contentassist.antlr.ObservableXtextTokenStream.StreamListener;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.AbstractInternalContentAssistParser;
import org.eclipse.xtext.ide.editor.contentassist.antlr.internal.BaseInternalContentAssistParser;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
/**
@ -28,10 +29,10 @@ public class EofListener implements StreamListener, AbstractInternalContentAssis
public int startedErrorRecoveryAt;
private final AbstractInternalContentAssistParser parser;
private final BaseInternalContentAssistParser<?, ?> parser;
private final AbstractElement elementToParse;
protected EofListener(AbstractInternalContentAssistParser parser, AbstractElement elementToParse) {
protected EofListener(BaseInternalContentAssistParser<?, ?> parser, AbstractElement elementToParse) {
this.parser = parser;
this.elementToParse = elementToParse;
this.parserState = parser.getInternalRecognizerSharedState();
@ -39,7 +40,7 @@ public class EofListener implements StreamListener, AbstractInternalContentAssis
registerAsListenerAt(parser);
}
protected void registerAsListenerAt(AbstractInternalContentAssistParser parser) {
protected void registerAsListenerAt(BaseInternalContentAssistParser<?, ?> parser) {
ObservableXtextTokenStream stream = (ObservableXtextTokenStream) parser.getTokenStream();
stream.setListener(this);
parser.setRecoveryListener(this);
@ -105,7 +106,7 @@ public class EofListener implements StreamListener, AbstractInternalContentAssis
return elementToParse;
}
protected AbstractInternalContentAssistParser getParser() {
protected BaseInternalContentAssistParser<?, ?> getParser() {
return parser;
}

View file

@ -7,154 +7,10 @@
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr;
import java.util.List;
import org.eclipse.xtext.AbstractElement;
/**
* Simple bean that reflects the current state, when the content assist parser
* hit EOF.
* @since 2.9
*/
public class FollowElement {
private AbstractElement currentGrammarElement;
private List<AbstractElement> trace;
private List<AbstractElement> localTrace;
private int lookAhead;
private List<Integer> paramStack;
private List<LookAheadTerminal> lookAheadTerminals;
private List<AbstractElement> handledUnorderedGroupElements;
public AbstractElement getGrammarElement() {
return currentGrammarElement;
}
public void setGrammarElement(AbstractElement grammarElement) {
this.currentGrammarElement = grammarElement;
}
public List<AbstractElement> getTrace() {
return trace;
}
public void setTrace(List<AbstractElement> trace) {
this.trace = trace;
}
public int getLookAhead() {
return lookAhead;
}
public void setLookAhead(int lookAhead) {
this.lookAhead = lookAhead;
}
/**
* @since 2.9
*/
public List<Integer> getParamStack() {
return paramStack;
}
/**
* @since 2.9
*/
public void setParamStack(List<Integer> paramStack) {
this.paramStack = paramStack;
}
public List<LookAheadTerminal> getLookAheadTerminals() {
return lookAheadTerminals;
}
public void setLookAheadTerminals(List<LookAheadTerminal> lookAheadTerminals) {
this.lookAheadTerminals = lookAheadTerminals;
}
public void setLocalTrace(List<AbstractElement> localTrace) {
this.localTrace = localTrace;
}
public List<AbstractElement> getLocalTrace() {
return localTrace;
}
public void setHandledUnorderedGroupElements(List<AbstractElement> handledUnorderedGroupElements) {
this.handledUnorderedGroupElements = handledUnorderedGroupElements;
}
public List<AbstractElement> getHandledUnorderedGroupElements() {
return handledUnorderedGroupElements;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((currentGrammarElement == null) ? 0 : currentGrammarElement.hashCode());
result = prime * result + ((localTrace == null) ? 0 : localTrace.hashCode());
result = prime * result + lookAhead;
result = prime * result + ((paramStack == null) ? 0 : paramStack.hashCode());
result = prime * result + ((lookAheadTerminals == null) ? 0 : lookAheadTerminals.hashCode());
result = prime * result + ((trace == null) ? 0 : trace.hashCode());
result = prime * result + ((handledUnorderedGroupElements == null) ? 0 : handledUnorderedGroupElements.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
FollowElement other = (FollowElement) obj;
if (currentGrammarElement == null) {
if (other.currentGrammarElement != null)
return false;
}
else if (!currentGrammarElement.equals(other.currentGrammarElement))
return false;
if (localTrace == null) {
if (other.localTrace != null)
return false;
}
else if (!localTrace.equals(other.localTrace))
return false;
if (lookAhead != other.lookAhead)
return false;
if (paramStack == null) {
if (other.paramStack != null)
return false;
}
else if (!paramStack.equals(other.paramStack))
return false;
if (lookAheadTerminals == null) {
if (other.lookAheadTerminals != null)
return false;
}
else if (!lookAheadTerminals.equals(other.lookAheadTerminals))
return false;
if (trace == null) {
if (other.trace != null)
return false;
}
else if (!trace.equals(other.trace))
return false;
if (handledUnorderedGroupElements == null) {
if (other.handledUnorderedGroupElements != null)
return false;
}
else if (!handledUnorderedGroupElements.equals(other.handledUnorderedGroupElements))
return false;
return true;
}
@Override
public String toString() {
return "FollowElement: " + getGrammarElement() + " LA: " + getLookAhead();
}
public class FollowElement extends BaseFollowElement<LookAheadTerminal> {
}

View file

@ -0,0 +1,21 @@
/*******************************************************************************
* Copyright (c) 2017 itemis AG (http://www.itemis.eu) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr;
import org.antlr.runtime.Token;
/**
* @author Sebastian Zarnekow - Initial contribution and API
*
* @since 2.14
*/
public interface ILookAheadTerminal {
Token getToken();
}

View file

@ -17,16 +17,16 @@ import org.antlr.runtime.TokenSource;
* @since 2.14
*/
public class LookAheadBasedTokenSource implements TokenSource {
private final Iterator<LookAheadTerminal> iter;
private final Iterator<? extends ILookAheadTerminal> iter;
protected LookAheadBasedTokenSource(Iterator<LookAheadTerminal> iter) {
protected LookAheadBasedTokenSource(Iterator<? extends ILookAheadTerminal> iter) {
this.iter = iter;
}
@Override
public Token nextToken() {
if (iter.hasNext()) {
LookAheadTerminal lookAhead = iter.next();
ILookAheadTerminal lookAhead = iter.next();
return lookAhead.getToken();
}
return Token.EOF_TOKEN;

View file

@ -13,12 +13,13 @@ import org.eclipse.xtext.AbstractElement;
/**
* @since 2.9
*/
public abstract class LookAheadTerminal {
public abstract class LookAheadTerminal implements ILookAheadTerminal {
private Token token;
public abstract boolean matches(AbstractElement element);
@Override
public Token getToken() {
return token;
}

View file

@ -0,0 +1,85 @@
/*******************************************************************************
* Copyright (c) 2017 itemis AG (http://www.itemis.de) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr.internal;
import java.util.Collections;
import java.util.List;
import org.antlr.runtime.Token;
import org.apache.log4j.Logger;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.editor.contentassist.antlr.BaseFollowElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.ILookAheadTerminal;
import com.google.common.collect.Iterators;
import com.google.common.collect.Lists;
/**
* @author Sebastian Zarnekow - Initial contribution and API
*
* @since 2.14
*/
public abstract class AbstractFollowElementFactory<FollowElement extends BaseFollowElement<LookAheadTerminal>, LookAheadTerminal extends ILookAheadTerminal> {
private static final Logger logger = Logger.getLogger(AbstractFollowElementFactory.class);
private final BaseInternalContentAssistParser<FollowElement, LookAheadTerminal> parser;
protected AbstractFollowElementFactory(BaseInternalContentAssistParser<FollowElement, LookAheadTerminal> parser) {
this.parser = parser;
}
protected abstract FollowElement doCreateElement();
protected abstract LookAheadTerminal doCreateLookAheadTerminal(Token token);
public FollowElement createFollowElement(AbstractElement current, int lookAhead) {
if (logger.isDebugEnabled())
logger.debug("Creating FollowElement for: " + current);
FollowElement result = doCreateElement();
result.setLookAhead(lookAhead);
if (lookAhead != 1) {
int from = parser.input.index();
int to = parser.input.size();
if (parser.marked > 0) {
from = parser.firstMarker;
}
List<LookAheadTerminal> lookAheadTerminals = Lists.newArrayListWithExpectedSize(to - from);
for (int tokenIndex = from; tokenIndex < to; tokenIndex++) {
Token token = parser.input.get(tokenIndex);
if (token != null) {
LookAheadTerminal lookAheadTerminal = doCreateLookAheadTerminal(token);
lookAheadTerminals.add(lookAheadTerminal);
}
}
result.setLookAheadTerminals(lookAheadTerminals);
result.setLookAhead(lookAheadTerminals.size() + 1);
}
result.setGrammarElement(current);
result.setTrace(Lists.newArrayList(Iterators.filter(parser.grammarElements.iterator(), AbstractElement.class)));
result.setLocalTrace(Lists.newArrayList(Iterators.filter(parser.localTrace.iterator(), AbstractElement.class)));
result.setParamStack(Lists.newArrayList(parser.paramStack));
if (current instanceof UnorderedGroup) {
if (parser.indexToHandledElements != null) {
int index = parser.grammarElements.lastIndexOf(current);
List<AbstractElement> alreadyHandled = Lists.newArrayList(Iterators.filter(parser.indexToHandledElements.get(index).iterator(), AbstractElement.class));
result.setHandledUnorderedGroupElements(alreadyHandled);
} else {
result.setHandledUnorderedGroupElements(Collections.<AbstractElement>emptyList());
}
}
if (logger.isDebugEnabled()) {
logger.debug("FollowElement is: " + current);
logger.debug("==================================");
}
return result;
}
}

View file

@ -7,530 +7,116 @@
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr.internal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.antlr.runtime.BitSet;
import org.antlr.runtime.DFA;
import org.antlr.runtime.FailedPredicateException;
import org.antlr.runtime.IntStream;
import org.antlr.runtime.Parser;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
import org.apache.log4j.Logger;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.TerminalRule;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.LookAheadTerminal;
import org.eclipse.xtext.ide.editor.contentassist.antlr.LookAheadTerminalRuleCall;
import org.eclipse.xtext.ide.editor.contentassist.antlr.LookaheadKeyword;
import org.eclipse.xtext.ide.editor.contentassist.antlr.ObservableXtextTokenStream;
import org.eclipse.xtext.parser.antlr.ITokenDefProvider;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
import org.eclipse.xtext.parser.antlr.TokenTool;
import com.google.common.collect.Iterators;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
/*
* Initially copied from org.eclipse.xtext.ui.editor.contentassist.antlr.internal.AbstractInternalContentAssistParser
*/
/**
* @since 2.9
*/
public abstract class AbstractInternalContentAssistParser extends Parser implements
ObservableXtextTokenStream.StreamListener, ITokenDefProvider {
public abstract class AbstractInternalContentAssistParser extends BaseInternalContentAssistParser<FollowElement, LookAheadTerminal> implements
ObservableXtextTokenStream.StreamListener {
private static final Logger logger = Logger.getLogger(AbstractInternalContentAssistParser.class);
protected class DefaultFollowElementFactory implements IFollowElementFactory {
@Override
public FollowElement createFollowElement(AbstractElement current, int lookAhead) {
if (logger.isDebugEnabled())
logger.debug("Creating FollowElement for: " + current);
FollowElement result = new FollowElement();
result.setLookAhead(lookAhead);
if (lookAhead != 1) {
int from = input.index();
int to = input.size();
if (marked > 0) {
from = firstMarker;
}
List<LookAheadTerminal> lookAheadTerminals = Lists.newArrayListWithExpectedSize(to - from);
for (int tokenIndex = from; tokenIndex < to; tokenIndex++) {
Token token = input.get(tokenIndex);
if (token != null) {
LookAheadTerminal lookAheadTerminal = createLookAheadTerminal(token);
lookAheadTerminals.add(lookAheadTerminal);
}
}
result.setLookAheadTerminals(lookAheadTerminals);
result.setLookAhead(lookAheadTerminals.size() + 1);
}
result.setGrammarElement(current);
result.setTrace(Lists.newArrayList(Iterators.filter(grammarElements.iterator(), AbstractElement.class)));
result.setLocalTrace(Lists.newArrayList(Iterators.filter(localTrace.iterator(), AbstractElement.class)));
result.setParamStack(Lists.newArrayList(paramStack));
if (current instanceof UnorderedGroup) {
if (indexToHandledElements != null) {
int index = grammarElements.lastIndexOf(current);
List<AbstractElement> alreadyHandled = Lists.newArrayList(Iterators.filter(indexToHandledElements.get(index).iterator(), AbstractElement.class));
result.setHandledUnorderedGroupElements(alreadyHandled);
} else {
result.setHandledUnorderedGroupElements(Collections.<AbstractElement>emptyList());
}
}
if (logger.isDebugEnabled()) {
logger.debug("FollowElement is: " + current);
logger.debug("==================================");
}
return result;
protected class DefaultFollowElementFactory extends AbstractFollowElementFactory<FollowElement, LookAheadTerminal> implements IFollowElementFactory {
protected DefaultFollowElementFactory() {
super(AbstractInternalContentAssistParser.this);
}
@Override
protected FollowElement doCreateElement() {
return new FollowElement();
}
@Override
protected LookAheadTerminal doCreateLookAheadTerminal(Token token) {
return createLookAheadTerminal(token);
}
}
public interface RecoveryListener {
void beginErrorRecovery();
void endErrorRecovery();
public interface RecoveryListener extends BaseInternalContentAssistParser.RecoveryListener {
}
interface IFollowElementFactory {
FollowElement createFollowElement(AbstractElement current, int lookAhead);
interface IFollowElementFactory extends BaseInternalContentAssistParser.IFollowElementFactory<FollowElement, LookAheadTerminal> {
}
protected final List<EObject> grammarElements;
protected final List<EObject> localTrace;
protected final List<Integer> paramStack;
protected final List<Integer> grammarElementsWithParams;
protected int stackSize;
protected final Set<FollowElement> followElements;
protected ObservableXtextTokenStream.StreamListener delegate;
protected List<TerminalRule> terminalRules;
protected boolean mismatch;
protected RecoveryListener recoveryListener;
protected int lookAheadAddOn;
protected int marked = 0;
protected boolean resyncing = false;
protected boolean strict = false;
protected int wasErrorCount = -1;
protected int predictionLevel = 0;
protected int currentMarker;
protected int firstMarker;
protected boolean inMismatchIsUnwantedToken = false;
protected boolean failedPredicateAtEOF = false;
protected Multimap<Integer, AbstractElement> indexToHandledElements;
protected IUnorderedGroupHelper unorderedGroupHelper;
protected IFollowElementFactory followElementFactory = new DefaultFollowElementFactory();
public AbstractInternalContentAssistParser(TokenStream input, RecognizerSharedState state) {
super(input, state);
this.grammarElements = new ArrayList<EObject>();
this.localTrace = new ArrayList<EObject>();
this.paramStack = new ArrayList<Integer>();
this.grammarElementsWithParams = new ArrayList<Integer>();
this.followElements = new LinkedHashSetWithoutNull<FollowElement>();
}
public AbstractInternalContentAssistParser(TokenStream input) {
super(input);
this.grammarElements = new ArrayList<EObject>();
this.localTrace = new ArrayList<EObject>();
this.followElements = new LinkedHashSetWithoutNull<FollowElement>();
this.paramStack = new ArrayList<Integer>();
this.grammarElementsWithParams = new ArrayList<Integer>();
}
/**
* When experiencing slow content assist, try to reduce the threshold.
*/
protected int getLookaheadThreshold() {
return Integer.MAX_VALUE;
}
public void before(EObject grammarElement) {
if (input.size() == input.index()) {
int idx = localTrace.indexOf(grammarElement);
// due to error recovery inconveniences we have to add some grammarElements
// twice immediately after each other
if (idx >= 0 && idx != localTrace.size() - 1) {
List<EObject> traceAfterFirstOccurrence = localTrace.subList(idx + 1, localTrace.size());
int secondIdx = traceAfterFirstOccurrence.indexOf(grammarElement);
if (secondIdx >= 0 && secondIdx != traceAfterFirstOccurrence.size() - 1) {
List<EObject> firstRun = localTrace.subList(idx, idx + 1 + secondIdx);
List<EObject> secondRun = traceAfterFirstOccurrence.subList(secondIdx, traceAfterFirstOccurrence.size());
if (firstRun.equals(secondRun)) {
throw new InfiniteRecursion();
}
}
}
}
grammarElements.add(grammarElement);
localTrace.add(grammarElement);
}
public void before(EObject grammarElement, int paramConfig) {
before(grammarElement);
paramStack.add(paramConfig);
grammarElementsWithParams.add(stackSize);
@Override
protected DefaultFollowElementFactory newFollowElementFactory() {
return new DefaultFollowElementFactory();
}
public void after(EObject grammarElement, int paramConfig) {
int old = removeLast(paramStack);
if (old != paramConfig) {
throw new IllegalStateException(paramConfig + "!=" + old);
}
removeLast(grammarElementsWithParams);
after(grammarElement);
protected abstract class StreamAdapter extends BaseInternalContentAssistParser<FollowElement, LookAheadTerminal>.StreamAdapter {
}
protected StreamAdapter delegate(BaseInternalContentAssistParser<FollowElement, LookAheadTerminal>.StreamAdapter delegate) {
return new StreamAdapter() {
public void after(EObject grammarElement) {
EObject foundGrammarElement = removeLast(grammarElements);
if (grammarElement != foundGrammarElement)
throw new IllegalStateException("expected element: '" + grammarElement + "', but was: '"
+ foundGrammarElement + "'");
if (grammarElement instanceof UnorderedGroup && indexToHandledElements != null) {
indexToHandledElements.removeAll(grammarElements.size());
} else if (!grammarElements.isEmpty()) {
int index = grammarElements.size() - 1;
if (grammarElements.get(index) instanceof UnorderedGroup) {
if (indexToHandledElements == null) {
indexToHandledElements = LinkedHashMultimap.create();
}
indexToHandledElements.put(index, (AbstractElement) grammarElement);
@Override
public void announceEof(int lookAhead) {
delegate.announceEof(lookAhead);
}
}
@Override
public void announceConsume() {
delegate.announceConsume();
}
@Override
public void announceMark(int marker) {
delegate.announceMark(marker);
}
@Override
public void announceRewind(int marker) {
delegate.announceRewind(marker);
}
};
}
@Override
public void recover(IntStream stream, RecognitionException ex) {
if (recoveryListener != null)
recoveryListener.beginErrorRecovery();
removeUnexpectedElements();
if (ex instanceof FailedPredicateException && ex.token.getType() == Token.EOF) {
failedPredicateAtEOF = true;
}
super.recover(stream, ex);
if (recoveryListener != null)
recoveryListener.endErrorRecovery();
}
private void removeUnexpectedElements() {
int dropParamAt = -1;
if (!grammarElementsWithParams.isEmpty()) {
dropParamAt = getLast(grammarElementsWithParams);
}
while (stackSize < grammarElements.size()) {
removeLast(grammarElements);
if (dropParamAt == grammarElements.size()) {
removeLast(paramStack);
removeLast(grammarElementsWithParams);
if (!grammarElementsWithParams.isEmpty()) {
dropParamAt = getLast(grammarElementsWithParams);
}
}
}
}
private <T> T getLast(List<T> list) {
return list.get(list.size() - 1);
}
private <T> T removeLast(List<T> list) {
return list.remove(list.size() - 1);
}
@Override
public void emitErrorMessage(String msg) {
// don't call super, since it would do a plain vanilla
// System.err.println(msg);
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
public RecognizerSharedState getInternalRecognizerSharedState() {
return state;
}
protected abstract Grammar getGrammar();
protected int keepStackSize() {
int result = stackSize;
stackSize = grammarElements.size();
return result;
}
protected void restoreStackSize(int stackSize) {
if (!isBacktracking()) {
removeUnexpectedElements();
this.stackSize = stackSize;
}
}
protected boolean isBacktracking() {
return state.backtracking != 0;
}
protected abstract class StreamAdapter implements ObservableXtextTokenStream.StreamListener {
@Override
public void announceConsume() {
AbstractInternalContentAssistParser.this.announceConsume();
}
@Override
public void announceMark(int marker) {
AbstractInternalContentAssistParser.this.announceMark(marker);
}
@Override
public void announceRewind(int marker) {
AbstractInternalContentAssistParser.this.announceRewind(marker);
}
}
protected void selectEofStrategy(int lookAhead) {
if (mismatch || !state.errorRecovery) {
selectEofStrategy();
} else if (strict && lookAhead == 1) {
delegate = createNoOpStrategy();
if (predictionLevel > 0) {
delegate = createPredictionStrategy();
}
} else {
selectEofStrategy();
}
}
protected void selectEofStrategy() throws UnsupportedOperationException {
if (mismatch) {
delegate = createMismatchStrategy();
} else if (!state.errorRecovery) {
if (marked > 0 && state.syntaxErrors > 0 && state.lastErrorIndex >= firstMarker) {
delegate = createNoOpStrategy();
return;
} else {
delegate = createNotErrorRecoveryStrategy();
}
} else {
delegate = createErrorRecoveryStrategy();
}
if (predictionLevel > 0) {
delegate = createPredictionStrategy();
}
}
protected StreamAdapter createNoOpStrategy() {
return new StreamAdapter() {
@Override
public void announceEof(int lookAhead) {
}
};
return delegate(super.createNoOpStrategy());
}
@Override
protected StreamAdapter createPredictionStrategy() {
return new StreamAdapter() {
private AbstractElement lastAddedElement;
private AbstractElement globalLastAddedElement;
private int lastKnownSyntaxErrors = Integer.MAX_VALUE;
private boolean wasMismatch = false;
private ObservableXtextTokenStream.StreamListener privateDelegate = delegate;
private IFollowElementFactory followElementFactory;
private AbstractElement recovered;
{
followElementFactory = AbstractInternalContentAssistParser.this.followElementFactory;
AbstractInternalContentAssistParser.this.followElementFactory = new IFollowElementFactory() {
@Override
public FollowElement createFollowElement(AbstractElement current, int lookAhead) {
if (lastKnownSyntaxErrors == Integer.MAX_VALUE || state.lastErrorIndex < 0) {
FollowElement result = followElementFactory.createFollowElement(current, lookAhead);
if (result != null) {
globalLastAddedElement = result.getGrammarElement();
if (lookAhead > 1 && isBacktracking() && lastKnownSyntaxErrors == Integer.MAX_VALUE) {
lastKnownSyntaxErrors = state.syntaxErrors;
}
}
return result;
}
return null;
}
};
}
@Override
public void announceEof(int lookAhead) {
try {
if (predictionLevel == 0) {
if (!wasMismatch && (!state.errorRecovery || !resyncing)) {
AbstractElement current = getCurrentGrammarElement();
if (current != null
&& (lastAddedElement == null ||
!EcoreUtil.isAncestor(current, lastAddedElement))) {
if (state.errorRecovery) {
if (!failedPredicateAtEOF && (globalLastAddedElement != current && (globalLastAddedElement == null
|| GrammarUtil.isOptionalCardinality(globalLastAddedElement)
|| GrammarUtil.isOneOrMoreCardinality(globalLastAddedElement)))) {
createAndAddFollowElement(current, lookAhead);
}
} else {
if (globalLastAddedElement != current && state.syntaxErrors <= lastKnownSyntaxErrors)
createAndAddFollowElement(current, lookAhead);
}
}
}
if (mismatch && !wasMismatch && !failedPredicateAtEOF) {
AbstractElement current = getCurrentGrammarElement();
if (recovered == null || recovered == current) {
if (current != null
&& (lastAddedElement == null ||
!EcoreUtil.isAncestor(current, lastAddedElement))) {
createAndAddFollowElement(current, lookAhead);
}
}
}
} else {
if (globalLastAddedElement != getCurrentGrammarElement())
privateDelegate.announceEof(lookAhead);
}
} finally {
wasMismatch |= mismatch;
if (getCurrentGrammarElement() != null && getCurrentGrammarElement() != globalLastAddedElement) {
if (state.errorRecovery && recovered == null) {
recovered = getCurrentGrammarElement();
}
}
}
}
protected void createAndAddFollowElement(AbstractElement current, int lookAhead) {
if (marked > 0)
lookAhead+=lookAheadAddOn;
FollowElement followElement = followElementFactory.createFollowElement(current, lookAhead);
if (followElement != null) {
followElements.add(followElement);
lastAddedElement = current;
globalLastAddedElement = current;
}
}
};
return delegate(super.createPredictionStrategy());
}
@Override
protected StreamAdapter createErrorRecoveryStrategy() {
return new StreamAdapter() {
private AbstractElement lastAddedElement;
@Override
public void announceEof(int lookAhead) {
AbstractElement current = getCurrentGrammarElement();
if (current != null
&& (lastAddedElement == null ||
!EcoreUtil.isAncestor(current, lastAddedElement))) {
if (marked > 0)
lookAhead+=lookAheadAddOn;
followElements.add(createFollowElement(current, lookAhead));
lastAddedElement = current;
}
}
};
return delegate(super.createErrorRecoveryStrategy());
}
@Override
protected StreamAdapter createNotErrorRecoveryStrategy() {
return new StreamAdapter() {
@Override
public void announceEof(int lookAhead) {
if (!state.errorRecovery && !mismatch && ((!isBacktracking() || marked > 0) || wasErrorCount <= 0)) {
AbstractElement current = getCurrentGrammarElement();
if (current != null) {
if (marked > 0)
lookAhead+=lookAheadAddOn;
if (lookAhead <= getLookaheadThreshold())
followElements.add(createFollowElement(current, lookAhead));
}
}
}
};
return delegate(super.createNotErrorRecoveryStrategy());
}
@Override
protected StreamAdapter createMismatchStrategy() {
return new StreamAdapter() {
private boolean wasErrorRecovery = false;
@Override
public void announceEof(int lookAhead) {
wasErrorRecovery = wasErrorRecovery || state.errorRecovery;
if (!wasErrorRecovery && !mismatch) {
AbstractElement current = getCurrentGrammarElement();
if (current != null) {
if (marked > 0)
lookAhead+=lookAheadAddOn;
followElements.add(createFollowElement(current, lookAhead));
}
}
}
};
return delegate(super.createMismatchStrategy());
}
@Override
public void beginResync() {
resyncing = true;
}
@Override
public void endResync() {
resyncing = false;
}
@Override
protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
try {
mismatch = true;
return super.recoverFromMismatchedToken(input, ttype, follow);
}
finally {
mismatch = false;
}
}
@Override
public boolean mismatchIsMissingToken(IntStream input, BitSet follow) {
return false;
}
protected AbstractElement getCurrentGrammarElement() {
for (int i = grammarElements.size() - 1; i >= 0; i--) {
EObject result = grammarElements.get(i);
if (result instanceof AbstractElement)
return (AbstractElement) result;
}
return null;
}
protected FollowElement createFollowElement(AbstractElement current, int lookAhead) {
return followElementFactory.createFollowElement(current, lookAhead);
}
public LookAheadTerminal createLookAheadTerminal(Token token) {
Grammar grammar = getGrammar();
String tokenName = getTokenNames()[token.getType()];
@ -556,181 +142,12 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme
}
@Override
public void announceEof(int lookAhead) {
if (logger.isDebugEnabled()) {
logger.debug("Reached Eof with LA " + lookAhead);
logger.debug("Internal parser state is: ");
logger.debug(" current: " + getCurrentGrammarElement());
logger.debug(" failed: " + state.failed);
logger.debug(" errorRecovery: " + state.errorRecovery);
logger.debug(" resyncing: " + resyncing);
logger.debug(" marked: " + marked);
logger.debug(" firstMarker: " + firstMarker);
logger.debug(" currentMarker: " + currentMarker);
logger.debug(" lookAheadAddOn: " + lookAheadAddOn);
logger.debug(" params: " + paramStack);
logger.debug(" predictionLevel: " + predictionLevel);
logger.debug(" stackSize: " + stackSize);
logger.debug(" backtracking: " + state.backtracking);
logger.debug(" syntaxErrors: " + state.syntaxErrors);
logger.debug(" token: " + state.token);
logger.debug("==================================");
}
if (delegate == null) {
selectEofStrategy(lookAhead);
if (strict) {
wasErrorCount = state.syntaxErrors;
}
}
if (inMismatchIsUnwantedToken)
return;
if (grammarElements.isEmpty() || delegate == null)
return;
if (strict) {
if (wasErrorCount != state.syntaxErrors)
return;
}
delegate.announceEof(lookAhead);
}
@Override
public void reportError(RecognitionException e) {
if (strict) {
if ( state.errorRecovery ) {
return;
}
if (e.index != input.size()) {
// don't count errors at EOF in strict mode
state.syntaxErrors++;
}
state.errorRecovery = true;
} else {
super.reportError(e);
}
}
@Override
public void announceConsume() {
if (marked <= 0)
localTrace.clear();
else
lookAheadAddOn++;
}
@Override
public boolean mismatchIsUnwantedToken(IntStream input, int ttype) {
try {
inMismatchIsUnwantedToken = true;
boolean result = super.mismatchIsUnwantedToken(input, ttype);
return result;
} finally {
inMismatchIsUnwantedToken = false;
}
}
@Override
public void announceRewind(int marker) {
int useLookAhead = -1;
if (marker != 0 && delegate == null && strict && predictionLevel != 0 && lookAheadAddOn > 0 && state.syntaxErrors == 0
&& input.index() == input.size()
&& marker + lookAheadAddOn <= input.size()
&& isBacktracking()) {
useLookAhead = lookAheadAddOn;
delegate = createNotErrorRecoveryStrategy();
wasErrorCount = state.syntaxErrors;
}
currentMarker = marker;
lookAheadAddOn = currentMarker - firstMarker;
if (useLookAhead != -1 && useLookAhead + firstMarker >= input.index()) {
announceEof(useLookAhead);
}
marked --;
}
@Override
public void announceMark(int marker) {
if (marked <= 0) {
marked++;
lookAheadAddOn = 0;
currentMarker = marker;
firstMarker = marker;
} else {
marked++;
currentMarker = marker;
}
}
public void beginDFAPrediction() {
predictionLevel++;
}
public boolean isDFAPrediction() {
return predictionLevel != 0;
}
public void endDFAPrediction() {
predictionLevel--;
}
public Set<FollowElement> getFollowElements() {
if (logger.isDebugEnabled()) {
logger.debug("getFollowElements()");
}
return followElements;
}
@Override
public Map<Integer, String> getTokenDefMap() {
String[] names = getTokenNames();
Map<Integer, String> result = Maps.newHashMapWithExpectedSize(names.length - Token.MIN_TOKEN_TYPE);
for (int i = Token.MIN_TOKEN_TYPE; i < names.length; i++) {
result.put(i, getValueForTokenName(names[i]));
}
return result;
}
protected String getValueForTokenName(String tokenName) {
return tokenName;
}
public List<EObject> getGrammarElements() {
return grammarElements;
}
public List<EObject> getLocalTrace() {
return localTrace;
}
public List<Integer> getParamStack() {
return paramStack;
}
public RecoveryListener getRecoveryListener() {
return recoveryListener;
return (RecoveryListener) super.getRecoveryListener();
}
public void setRecoveryListener(RecoveryListener recoveryListener) {
this.recoveryListener = recoveryListener;
}
public void setUnorderedGroupHelper(IUnorderedGroupHelper unorderedGroupHelper) {
this.unorderedGroupHelper = unorderedGroupHelper;
}
public IUnorderedGroupHelper getUnorderedGroupHelper() {
return unorderedGroupHelper;
}
public void setStrict(boolean strict) {
this.strict = strict;
}
protected static short[][] unpackEncodedStringArray(String[] arr) {
int numStates = arr.length;
short[][] result = new short[numStates][];
for (int i = 0; i < numStates; i++) {
result[i] = DFA.unpackEncodedString(arr[i]);
}
return result;
}
}

View file

@ -0,0 +1,640 @@
/*******************************************************************************
* Copyright (c) 2017 itemis AG (http://www.itemis.de) and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*******************************************************************************/
package org.eclipse.xtext.ide.editor.contentassist.antlr.internal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.antlr.runtime.BitSet;
import org.antlr.runtime.DFA;
import org.antlr.runtime.FailedPredicateException;
import org.antlr.runtime.IntStream;
import org.antlr.runtime.Parser;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.RecognizerSharedState;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenStream;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.xtext.AbstractElement;
import org.eclipse.xtext.Grammar;
import org.eclipse.xtext.GrammarUtil;
import org.eclipse.xtext.TerminalRule;
import org.eclipse.xtext.UnorderedGroup;
import org.eclipse.xtext.ide.editor.contentassist.antlr.BaseFollowElement;
import org.eclipse.xtext.ide.editor.contentassist.antlr.ILookAheadTerminal;
import org.eclipse.xtext.ide.editor.contentassist.antlr.ObservableXtextTokenStream;
import org.eclipse.xtext.parser.antlr.ITokenDefProvider;
import org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper;
import com.google.common.collect.LinkedHashMultimap;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
/**
* @author Sebastian Zarnekow - Initial contribution and API
* @since 2.14
*/
public abstract class BaseInternalContentAssistParser<FollowElement extends BaseFollowElement<LookAheadTerminal>, LookAheadTerminal extends ILookAheadTerminal>
extends Parser implements ObservableXtextTokenStream.StreamListener, ITokenDefProvider {
public interface RecoveryListener {
void beginErrorRecovery();
void endErrorRecovery();
}
public interface IFollowElementFactory<FollowElement extends BaseFollowElement<LookAheadTerminal>, LookAheadTerminal extends ILookAheadTerminal> {
FollowElement createFollowElement(AbstractElement current, int lookAhead);
}
protected final List<EObject> grammarElements;
protected final List<EObject> localTrace;
protected final List<Integer> paramStack;
protected final List<Integer> grammarElementsWithParams;
protected int stackSize;
protected final Set<FollowElement> followElements;
protected ObservableXtextTokenStream.StreamListener delegate;
protected List<TerminalRule> terminalRules;
protected boolean mismatch;
protected RecoveryListener recoveryListener;
protected int lookAheadAddOn;
protected int marked = 0;
protected boolean resyncing = false;
protected boolean strict = false;
protected int wasErrorCount = -1;
protected int predictionLevel = 0;
protected int currentMarker;
protected int firstMarker;
protected boolean inMismatchIsUnwantedToken = false;
protected boolean failedPredicateAtEOF = false;
protected Multimap<Integer, AbstractElement> indexToHandledElements;
protected IUnorderedGroupHelper unorderedGroupHelper;
protected IFollowElementFactory<FollowElement, LookAheadTerminal> followElementFactory = newFollowElementFactory();
public BaseInternalContentAssistParser(TokenStream input, RecognizerSharedState state) {
super(input, state);
this.grammarElements = new ArrayList<EObject>();
this.localTrace = new ArrayList<EObject>();
this.paramStack = new ArrayList<Integer>();
this.grammarElementsWithParams = new ArrayList<Integer>();
this.followElements = new LinkedHashSetWithoutNull<FollowElement>();
}
public BaseInternalContentAssistParser(TokenStream input) {
super(input);
this.grammarElements = new ArrayList<EObject>();
this.localTrace = new ArrayList<EObject>();
this.followElements = new LinkedHashSetWithoutNull<FollowElement>();
this.paramStack = new ArrayList<Integer>();
this.grammarElementsWithParams = new ArrayList<Integer>();
}
protected abstract IFollowElementFactory<FollowElement, LookAheadTerminal> newFollowElementFactory();
/**
* When experiencing slow content assist, try to reduce the threshold.
*/
protected int getLookaheadThreshold() {
return Integer.MAX_VALUE;
}
public void before(EObject grammarElement) {
if (input.size() == input.index()) {
int idx = localTrace.indexOf(grammarElement);
// due to error recovery inconveniences we have to add some grammarElements
// twice immediately after each other
if (idx >= 0 && idx != localTrace.size() - 1) {
List<EObject> traceAfterFirstOccurrence = localTrace.subList(idx + 1, localTrace.size());
int secondIdx = traceAfterFirstOccurrence.indexOf(grammarElement);
if (secondIdx >= 0 && secondIdx != traceAfterFirstOccurrence.size() - 1) {
List<EObject> firstRun = localTrace.subList(idx, idx + 1 + secondIdx);
List<EObject> secondRun = traceAfterFirstOccurrence.subList(secondIdx,
traceAfterFirstOccurrence.size());
if (firstRun.equals(secondRun)) {
throw infiniteRecursion();
}
}
}
}
grammarElements.add(grammarElement);
localTrace.add(grammarElement);
}
protected InfiniteRecursion infiniteRecursion() {
return new InfiniteRecursion();
}
public void before(EObject grammarElement, int paramConfig) {
before(grammarElement);
paramStack.add(paramConfig);
grammarElementsWithParams.add(stackSize);
}
public void after(EObject grammarElement, int paramConfig) {
int old = removeLast(paramStack);
if (old != paramConfig) {
throw new IllegalStateException(paramConfig + "!=" + old);
}
removeLast(grammarElementsWithParams);
after(grammarElement);
}
public void after(EObject grammarElement) {
EObject foundGrammarElement = removeLast(grammarElements);
if (grammarElement != foundGrammarElement)
throw new IllegalStateException(
"expected element: '" + grammarElement + "', but was: '" + foundGrammarElement + "'");
if (grammarElement instanceof UnorderedGroup && indexToHandledElements != null) {
indexToHandledElements.removeAll(grammarElements.size());
} else if (!grammarElements.isEmpty()) {
int index = grammarElements.size() - 1;
if (grammarElements.get(index) instanceof UnorderedGroup) {
if (indexToHandledElements == null) {
indexToHandledElements = LinkedHashMultimap.create();
}
indexToHandledElements.put(index, (AbstractElement) grammarElement);
}
}
}
@Override
public void recover(IntStream stream, RecognitionException ex) {
if (recoveryListener != null)
recoveryListener.beginErrorRecovery();
removeUnexpectedElements();
if (ex instanceof FailedPredicateException && ex.token.getType() == Token.EOF) {
failedPredicateAtEOF = true;
}
super.recover(stream, ex);
if (recoveryListener != null)
recoveryListener.endErrorRecovery();
}
private void removeUnexpectedElements() {
int dropParamAt = -1;
if (!grammarElementsWithParams.isEmpty()) {
dropParamAt = getLast(grammarElementsWithParams);
}
while (stackSize < grammarElements.size()) {
removeLast(grammarElements);
if (dropParamAt == grammarElements.size()) {
removeLast(paramStack);
removeLast(grammarElementsWithParams);
if (!grammarElementsWithParams.isEmpty()) {
dropParamAt = getLast(grammarElementsWithParams);
}
}
}
}
private <T> T getLast(List<T> list) {
return list.get(list.size() - 1);
}
private <T> T removeLast(List<T> list) {
return list.remove(list.size() - 1);
}
@Override
public void emitErrorMessage(String msg) {
// don't call super, since it would do a plain vanilla
// System.err.println(msg);
}
/**
* @nooverride This method is not intended to be re-implemented or extended by clients.
* @noreference This method is not intended to be referenced by clients.
*/
public RecognizerSharedState getInternalRecognizerSharedState() {
return state;
}
protected abstract Grammar getGrammar();
protected int keepStackSize() {
int result = stackSize;
stackSize = grammarElements.size();
return result;
}
protected void restoreStackSize(int stackSize) {
if (!isBacktracking()) {
removeUnexpectedElements();
this.stackSize = stackSize;
}
}
protected boolean isBacktracking() {
return state.backtracking != 0;
}
protected abstract class StreamAdapter implements ObservableXtextTokenStream.StreamListener {
@Override
public void announceConsume() {
BaseInternalContentAssistParser.this.announceConsume();
}
@Override
public void announceMark(int marker) {
BaseInternalContentAssistParser.this.announceMark(marker);
}
@Override
public void announceRewind(int marker) {
BaseInternalContentAssistParser.this.announceRewind(marker);
}
}
protected void selectEofStrategy(int lookAhead) {
if (mismatch || !state.errorRecovery) {
selectEofStrategy();
} else if (strict && lookAhead == 1) {
delegate = createNoOpStrategy();
if (predictionLevel > 0) {
delegate = createPredictionStrategy();
}
} else {
selectEofStrategy();
}
}
protected void selectEofStrategy() throws UnsupportedOperationException {
if (mismatch) {
delegate = createMismatchStrategy();
} else if (!state.errorRecovery) {
if (marked > 0 && state.syntaxErrors > 0 && state.lastErrorIndex >= firstMarker) {
delegate = createNoOpStrategy();
return;
} else {
delegate = createNotErrorRecoveryStrategy();
}
} else {
delegate = createErrorRecoveryStrategy();
}
if (predictionLevel > 0) {
delegate = createPredictionStrategy();
}
}
protected StreamAdapter createNoOpStrategy() {
return new StreamAdapter() {
@Override
public void announceEof(int lookAhead) {
}
};
}
protected StreamAdapter createPredictionStrategy() {
return new StreamAdapter() {
private AbstractElement lastAddedElement;
private AbstractElement globalLastAddedElement;
private int lastKnownSyntaxErrors = Integer.MAX_VALUE;
private boolean wasMismatch = false;
private ObservableXtextTokenStream.StreamListener privateDelegate = delegate;
private IFollowElementFactory<FollowElement, LookAheadTerminal> followElementFactory;
private AbstractElement recovered;
{
followElementFactory = BaseInternalContentAssistParser.this.followElementFactory;
BaseInternalContentAssistParser.this.followElementFactory = new IFollowElementFactory<FollowElement, LookAheadTerminal>() {
@Override
public FollowElement createFollowElement(AbstractElement current, int lookAhead) {
if (lastKnownSyntaxErrors == Integer.MAX_VALUE || state.lastErrorIndex < 0) {
FollowElement result = followElementFactory.createFollowElement(current, lookAhead);
if (result != null) {
globalLastAddedElement = result.getGrammarElement();
if (lookAhead > 1 && isBacktracking() && lastKnownSyntaxErrors == Integer.MAX_VALUE) {
lastKnownSyntaxErrors = state.syntaxErrors;
}
}
return result;
}
return null;
}
};
}
@Override
public void announceEof(int lookAhead) {
try {
if (predictionLevel == 0) {
if (!wasMismatch && (!state.errorRecovery || !resyncing)) {
AbstractElement current = getCurrentGrammarElement();
if (current != null
&& (lastAddedElement == null || !EcoreUtil.isAncestor(current, lastAddedElement))) {
if (state.errorRecovery) {
if (!failedPredicateAtEOF
&& (globalLastAddedElement != current && (globalLastAddedElement == null
|| GrammarUtil.isOptionalCardinality(globalLastAddedElement)
|| GrammarUtil.isOneOrMoreCardinality(globalLastAddedElement)))) {
createAndAddFollowElement(current, lookAhead);
}
} else {
if (globalLastAddedElement != current
&& state.syntaxErrors <= lastKnownSyntaxErrors)
createAndAddFollowElement(current, lookAhead);
}
}
}
if (mismatch && !wasMismatch && !failedPredicateAtEOF) {
AbstractElement current = getCurrentGrammarElement();
if (recovered == null || recovered == current) {
if (current != null && (lastAddedElement == null
|| !EcoreUtil.isAncestor(current, lastAddedElement))) {
createAndAddFollowElement(current, lookAhead);
}
}
}
} else {
if (globalLastAddedElement != getCurrentGrammarElement())
privateDelegate.announceEof(lookAhead);
}
} finally {
wasMismatch |= mismatch;
if (getCurrentGrammarElement() != null && getCurrentGrammarElement() != globalLastAddedElement) {
if (state.errorRecovery && recovered == null) {
recovered = getCurrentGrammarElement();
}
}
}
}
protected void createAndAddFollowElement(AbstractElement current, int lookAhead) {
if (marked > 0)
lookAhead += lookAheadAddOn;
FollowElement followElement = followElementFactory.createFollowElement(current, lookAhead);
if (followElement != null) {
followElements.add(followElement);
lastAddedElement = current;
globalLastAddedElement = current;
}
}
};
}
protected StreamAdapter createErrorRecoveryStrategy() {
return new StreamAdapter() {
private AbstractElement lastAddedElement;
@Override
public void announceEof(int lookAhead) {
AbstractElement current = getCurrentGrammarElement();
if (current != null && (lastAddedElement == null || !EcoreUtil.isAncestor(current, lastAddedElement))) {
if (marked > 0)
lookAhead += lookAheadAddOn;
followElements.add(createFollowElement(current, lookAhead));
lastAddedElement = current;
}
}
};
}
protected StreamAdapter createNotErrorRecoveryStrategy() {
return new StreamAdapter() {
@Override
public void announceEof(int lookAhead) {
if (!state.errorRecovery && !mismatch && ((!isBacktracking() || marked > 0) || wasErrorCount <= 0)) {
AbstractElement current = getCurrentGrammarElement();
if (current != null) {
if (marked > 0)
lookAhead += lookAheadAddOn;
if (lookAhead <= getLookaheadThreshold())
followElements.add(createFollowElement(current, lookAhead));
}
}
}
};
}
protected StreamAdapter createMismatchStrategy() {
return new StreamAdapter() {
private boolean wasErrorRecovery = false;
@Override
public void announceEof(int lookAhead) {
wasErrorRecovery = wasErrorRecovery || state.errorRecovery;
if (!wasErrorRecovery && !mismatch) {
AbstractElement current = getCurrentGrammarElement();
if (current != null) {
if (marked > 0)
lookAhead += lookAheadAddOn;
followElements.add(createFollowElement(current, lookAhead));
}
}
}
};
}
@Override
public void beginResync() {
resyncing = true;
}
@Override
public void endResync() {
resyncing = false;
}
@Override
protected Object recoverFromMismatchedToken(IntStream input, int ttype, BitSet follow) throws RecognitionException {
try {
mismatch = true;
return super.recoverFromMismatchedToken(input, ttype, follow);
} finally {
mismatch = false;
}
}
@Override
public boolean mismatchIsMissingToken(IntStream input, BitSet follow) {
return false;
}
protected AbstractElement getCurrentGrammarElement() {
for (int i = grammarElements.size() - 1; i >= 0; i--) {
EObject result = grammarElements.get(i);
if (result instanceof AbstractElement)
return (AbstractElement) result;
}
return null;
}
protected FollowElement createFollowElement(AbstractElement current, int lookAhead) {
return followElementFactory.createFollowElement(current, lookAhead);
}
public abstract LookAheadTerminal createLookAheadTerminal(Token token);
@Override
public void announceEof(int lookAhead) {
if (delegate == null) {
selectEofStrategy(lookAhead);
if (strict) {
wasErrorCount = state.syntaxErrors;
}
}
if (inMismatchIsUnwantedToken)
return;
if (grammarElements.isEmpty() || delegate == null)
return;
if (strict) {
if (wasErrorCount != state.syntaxErrors)
return;
}
delegate.announceEof(lookAhead);
}
@Override
public void reportError(RecognitionException e) {
if (strict) {
if (state.errorRecovery) {
return;
}
if (e.index != input.size()) {
// don't count errors at EOF in strict mode
state.syntaxErrors++;
}
state.errorRecovery = true;
} else {
super.reportError(e);
}
}
@Override
public void announceConsume() {
if (marked <= 0)
localTrace.clear();
else
lookAheadAddOn++;
}
@Override
public boolean mismatchIsUnwantedToken(IntStream input, int ttype) {
try {
inMismatchIsUnwantedToken = true;
boolean result = super.mismatchIsUnwantedToken(input, ttype);
return result;
} finally {
inMismatchIsUnwantedToken = false;
}
}
@Override
public void announceRewind(int marker) {
int useLookAhead = -1;
if (marker != 0 && delegate == null && strict && predictionLevel != 0 && lookAheadAddOn > 0
&& state.syntaxErrors == 0 && input.index() == input.size() && marker + lookAheadAddOn <= input.size()
&& isBacktracking()) {
useLookAhead = lookAheadAddOn;
delegate = createNotErrorRecoveryStrategy();
wasErrorCount = state.syntaxErrors;
}
currentMarker = marker;
lookAheadAddOn = currentMarker - firstMarker;
if (useLookAhead != -1 && useLookAhead + firstMarker >= input.index()) {
announceEof(useLookAhead);
}
marked--;
}
@Override
public void announceMark(int marker) {
if (marked <= 0) {
marked++;
lookAheadAddOn = 0;
currentMarker = marker;
firstMarker = marker;
} else {
marked++;
currentMarker = marker;
}
}
public void beginDFAPrediction() {
predictionLevel++;
}
public boolean isDFAPrediction() {
return predictionLevel != 0;
}
public void endDFAPrediction() {
predictionLevel--;
}
public Set<FollowElement> getFollowElements() {
return followElements;
}
@Override
public Map<Integer, String> getTokenDefMap() {
String[] names = getTokenNames();
Map<Integer, String> result = Maps.newHashMapWithExpectedSize(names.length - Token.MIN_TOKEN_TYPE);
for (int i = Token.MIN_TOKEN_TYPE; i < names.length; i++) {
result.put(i, getValueForTokenName(names[i]));
}
return result;
}
protected String getValueForTokenName(String tokenName) {
return tokenName;
}
public List<EObject> getGrammarElements() {
return grammarElements;
}
public List<EObject> getLocalTrace() {
return localTrace;
}
public List<Integer> getParamStack() {
return paramStack;
}
public RecoveryListener getRecoveryListener() {
return recoveryListener;
}
public void setRecoveryListener(RecoveryListener recoveryListener) {
this.recoveryListener = recoveryListener;
}
public void setUnorderedGroupHelper(IUnorderedGroupHelper unorderedGroupHelper) {
this.unorderedGroupHelper = unorderedGroupHelper;
}
public IUnorderedGroupHelper getUnorderedGroupHelper() {
return unorderedGroupHelper;
}
public void setStrict(boolean strict) {
this.strict = strict;
}
protected static short[][] unpackEncodedStringArray(String[] arr) {
int numStates = arr.length;
short[][] result = new short[numStates][];
for (int i = 0; i < numStates; i++) {
result[i] = DFA.unpackEncodedString(arr[i]);
}
return result;
}
}

View file

@ -29,8 +29,8 @@ public class DFA extends org.antlr.runtime.DFA {
}
}
protected AbstractInternalContentAssistParser getRecognizer() {
return (AbstractInternalContentAssistParser) recognizer;
protected BaseInternalContentAssistParser<?, ?> getRecognizer() {
return (BaseInternalContentAssistParser<?, ?>) recognizer;
}
protected IUnorderedGroupHelper getUnorderedGroupHelper() {

View file

@ -11,6 +11,7 @@ import com.google.common.base.Objects;
import com.google.common.io.ByteStreams;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Module;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
@ -47,7 +48,7 @@ public class ServerLauncher {
ServerLauncher.launch(_name, args, _serverModule);
}
public static void launch(final String prefix, final String[] args, final com.google.inject.Module... modules) {
public static void launch(final String prefix, final String[] args, final Module... modules) {
final LaunchArgs launchArgs = ServerLauncher.createLaunchArgs(prefix, args);
final ServerLauncher launcher = Guice.createInjector(modules).<ServerLauncher>getInstance(ServerLauncher.class);
launcher.start(launchArgs);

View file

@ -13,6 +13,7 @@ import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.binder.AnnotatedBindingBuilder;
import java.io.File;
import java.io.FileWriter;
@ -195,9 +196,9 @@ public abstract class AbstractLanguageServerTest implements Endpoint {
}
}
protected com.google.inject.Module getServerModule() {
protected Module getServerModule() {
ServerModule _serverModule = new ServerModule();
final com.google.inject.Module _function = (Binder it) -> {
final Module _function = (Binder it) -> {
AnnotatedBindingBuilder<RequestManager> _bind = it.<RequestManager>bind(RequestManager.class);
_bind.toInstance(new RequestManager() {
@Override

View file

@ -12,6 +12,7 @@ import com.google.common.collect.Lists;
import com.google.inject.Binder;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provider;
import java.io.File;
import java.util.ArrayList;
@ -98,7 +99,7 @@ public class XtextGeneratorLanguage extends CompositeGeneratorFragment2 implemen
private ResourceSet resourceSet;
@Accessors
private com.google.inject.Module guiceModule = ((com.google.inject.Module) (Binder it) -> {
private Module guiceModule = ((Module) (Binder it) -> {
});
@Accessors
@ -419,11 +420,11 @@ public class XtextGeneratorLanguage extends CompositeGeneratorFragment2 implemen
}
@Pure
public com.google.inject.Module getGuiceModule() {
public Module getGuiceModule() {
return this.guiceModule;
}
public void setGuiceModule(final com.google.inject.Module guiceModule) {
public void setGuiceModule(final Module guiceModule) {
this.guiceModule = guiceModule;
}

View file

@ -12,6 +12,7 @@ import com.google.inject.Binder;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import com.google.inject.name.Names;
@ -1747,19 +1748,19 @@ public class XtextGeneratorTemplates {
_builder.append("try {");
_builder.newLine();
_builder.append("\t\t\t");
_builder.append(com.google.inject.Module.class, "\t\t\t");
_builder.append(Module.class, "\t\t\t");
_builder.append(" runtimeModule = getRuntimeModule(language);");
_builder.newLineIfNotEmpty();
_builder.append("\t\t\t");
_builder.append(com.google.inject.Module.class, "\t\t\t");
_builder.append(Module.class, "\t\t\t");
_builder.append(" sharedStateModule = getSharedStateModule();");
_builder.newLineIfNotEmpty();
_builder.append("\t\t\t");
_builder.append(com.google.inject.Module.class, "\t\t\t");
_builder.append(Module.class, "\t\t\t");
_builder.append(" uiModule = getUiModule(language);");
_builder.newLineIfNotEmpty();
_builder.append("\t\t\t");
_builder.append(com.google.inject.Module.class, "\t\t\t");
_builder.append(Module.class, "\t\t\t");
_builder.append(" mergedModule = ");
_builder.append(Modules2.class, "\t\t\t");
_builder.append(".mixin(runtimeModule, sharedStateModule, uiModule);");
@ -1791,7 +1792,7 @@ public class XtextGeneratorTemplates {
_builder.newLine();
_builder.append("\t");
_builder.append("protected ");
_builder.append(com.google.inject.Module.class, "\t");
_builder.append(Module.class, "\t");
_builder.append(" getRuntimeModule(String grammar) {");
_builder.newLineIfNotEmpty();
{
@ -1824,7 +1825,7 @@ public class XtextGeneratorTemplates {
_builder.newLine();
_builder.append("\t");
_builder.append("protected ");
_builder.append(com.google.inject.Module.class, "\t");
_builder.append(Module.class, "\t");
_builder.append(" getUiModule(String grammar) {");
_builder.newLineIfNotEmpty();
{
@ -1857,7 +1858,7 @@ public class XtextGeneratorTemplates {
_builder.newLine();
_builder.append("\t");
_builder.append("protected ");
_builder.append(com.google.inject.Module.class, "\t");
_builder.append(Module.class, "\t");
_builder.append(" getSharedStateModule() {");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");

View file

@ -13,6 +13,7 @@ import com.google.common.collect.Iterators;
import com.google.inject.Guice;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Module;
import com.google.inject.Singleton;
import com.google.inject.name.Names;
import java.io.InputStream;
@ -1342,7 +1343,7 @@ public class IdeaPluginGenerator extends AbstractStubGeneratingFragment {
_builder.append("();");
_builder.newLineIfNotEmpty();
_builder.append("\t\t");
_builder.append(com.google.inject.Module.class, "\t\t");
_builder.append(Module.class, "\t\t");
_builder.append(" mergedModule = ");
_builder.append(Modules2.class, "\t\t");
_builder.append(".mixin(runtimeModule, ideaModule);");