diff --git a/plugins/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/antlr/internal/AbstractInternalContentAssistParser.java b/plugins/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/antlr/internal/AbstractInternalContentAssistParser.java index 31f5478b4..0d0e0c0a2 100644 --- a/plugins/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/antlr/internal/AbstractInternalContentAssistParser.java +++ b/plugins/org.eclipse.xtext.ide/src/org/eclipse/xtext/ide/editor/contentassist/antlr/internal/AbstractInternalContentAssistParser.java @@ -45,6 +45,9 @@ 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 */ @@ -111,6 +114,7 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme protected final List grammarElements; protected final List localTrace; protected final List paramStack; + protected final List grammarElementsWithParams; protected int stackSize; protected final Set followElements; protected ObservableXtextTokenStream.StreamListener delegate; @@ -136,6 +140,7 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme this.grammarElements = new ArrayList(); this.localTrace = new ArrayList(); this.paramStack = new ArrayList(); + this.grammarElementsWithParams = new ArrayList(); this.followElements = new LinkedHashSetWithoutNull(); } @@ -145,6 +150,7 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme this.localTrace = new ArrayList(); this.followElements = new LinkedHashSetWithoutNull(); this.paramStack = new ArrayList(); + this.grammarElementsWithParams = new ArrayList(); } /** @@ -178,17 +184,20 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme public void before(EObject grammarElement, int paramConfig) { before(grammarElement); paramStack.add(paramConfig); + grammarElementsWithParams.add(stackSize); } public void after(EObject grammarElement, int paramConfig) { - int old = paramStack.remove(paramStack.size() - 1); + int old = removeLast(paramStack); if (old != paramConfig) { throw new IllegalStateException(paramConfig + "!=" + old); } + removeLast(grammarElementsWithParams); + after(grammarElement); } public void after(EObject grammarElement) { - EObject foundGrammarElement = grammarElements.remove(grammarElements.size() - 1); + EObject foundGrammarElement = removeLast(grammarElements); if (grammarElement != foundGrammarElement) throw new IllegalStateException("expected element: '" + grammarElement + "', but was: '" + foundGrammarElement + "'"); @@ -219,8 +228,24 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme } private void removeUnexpectedElements() { - while (stackSize < grammarElements.size()) - grammarElements.remove(grammarElements.size() - 1); + int dropParamAt = -1; + if (!grammarElementsWithParams.isEmpty()) { + dropParamAt = grammarElementsWithParams.get(grammarElementsWithParams.size() - 1); + } + while (stackSize < grammarElements.size()) { + removeLast(grammarElements); + if (dropParamAt == grammarElements.size()) { + removeLast(paramStack); + removeLast(grammarElementsWithParams); + if (!grammarElementsWithParams.isEmpty()) { + dropParamAt = grammarElementsWithParams.get(grammarElementsWithParams.size() - 1); + } + } + } + } + + private T removeLast(List list) { + return list.remove(list.size() - 1); } @Override @@ -679,10 +704,7 @@ public abstract class AbstractInternalContentAssistParser extends Parser impleme public void setStrict(boolean strict) { this.strict = strict; } - - /** - * @since 2.9 - */ + protected static short[][] unpackEncodedStringArray(String[] arr) { int numStates = arr.length; short[][] result = new short[numStates][];