Search in sources :

Example 11 with FollowElement

use of org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement in project n4js by eclipse.

the class PatchedFollowElementComputer method computeFollowElements.

@Override
protected void computeFollowElements(FollowElementCalculator calculator, FollowElement element, Multimap<Integer, List<AbstractElement>> visited) {
    List<AbstractElement> currentState = Lists.newArrayList(element.getLocalTrace());
    currentState.add(element.getGrammarElement());
    if (!visited.put(element.getLookAhead(), currentState))
        return;
    if (element.getLookAhead() <= 1) {
        for (AbstractElement abstractElement : currentState) {
            Assignment ass = EcoreUtil2.getContainerOfType(abstractElement, Assignment.class);
            if (ass != null)
                calculator.doSwitch(ass);
            else {
                if (abstractElement instanceof UnorderedGroup && abstractElement == element.getGrammarElement()) {
                    calculator.doSwitch((UnorderedGroup) abstractElement, element.getHandledUnorderedGroupElements());
                } else {
                    calculator.doSwitch(abstractElement);
                    if (GrammarUtil.isOptionalCardinality(abstractElement)) {
                        EObject container = abstractElement.eContainer();
                        if (container instanceof Group) {
                            Group group = (Group) container;
                            int idx = group.getElements().indexOf(abstractElement);
                            if (idx == group.getElements().size() - 1) {
                                if (!currentState.contains(group) && GrammarUtil.isMultipleCardinality(group)) {
                                    calculator.doSwitch(group);
                                }
                            } else if (idx < group.getElements().size() - 1 && "?".equals(abstractElement.getCardinality())) {
                                // loops are fine
                                AbstractElement nextElement = group.getElements().get(idx + 1);
                                if (!currentState.contains(nextElement)) {
                                    calculator.doSwitch(nextElement);
                                }
                            }
                        }
                    } else if (isAlternativeWithEmptyPath(abstractElement)) {
                        EObject container = abstractElement.eContainer();
                        if (container instanceof Group) {
                            Group group = (Group) container;
                            int idx = group.getElements().indexOf(abstractElement);
                            if (!currentState.contains(group) && idx != group.getElements().size() - 1) {
                                AbstractElement next = group.getElements().get(idx + 1);
                                if (!currentState.contains(next)) {
                                    calculator.doSwitch(next);
                                }
                            }
                        }
                    }
                }
            }
        }
        // we need a synthetic rule call
        if (element.getTrace().equals(element.getLocalTrace())) {
            ParserRule parserRule = GrammarUtil.containingParserRule(element.getGrammarElement());
            if (parserRule != null) {
                RuleCall ruleCall = XtextFactory.eINSTANCE.createRuleCall();
                ruleCall.setRule(parserRule);
                calculator.doSwitch(ruleCall);
            }
        }
        return;
    }
    Collection<FollowElement> followElements = parser.getFollowElements(element);
    for (FollowElement newElement : followElements) {
        if (newElement.getLookAhead() != element.getLookAhead() || newElement.getGrammarElement() != element.getGrammarElement()) {
            if (newElement.getLookAhead() == element.getLookAhead()) {
                int originalTraceSize = element.getLocalTrace().size();
                List<AbstractElement> newTrace = newElement.getLocalTrace();
                if (newTrace.size() > originalTraceSize) {
                    if (Collections.indexOfSubList(element.getLocalTrace(), newTrace.subList(originalTraceSize, newTrace.size())) != -1) {
                        continue;
                    }
                }
            }
            computeFollowElements(calculator, newElement, visited);
        }
    }
}
Also used : Assignment(org.eclipse.xtext.Assignment) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) Group(org.eclipse.xtext.Group) ParserRule(org.eclipse.xtext.ParserRule) AbstractElement(org.eclipse.xtext.AbstractElement) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) EObject(org.eclipse.emf.ecore.EObject) RuleCall(org.eclipse.xtext.RuleCall) FollowElement(org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement)

Example 12 with FollowElement

use of org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement in project n4js by eclipse.

the class ContentAssistContextFactory method handleLastCompleteNodeIsAtEndOfDatatypeNode.

@Override
protected void handleLastCompleteNodeIsAtEndOfDatatypeNode() {
    String prefix = getPrefix(lastCompleteNode);
    INode previousNode = getLastCompleteNodeByOffset(rootNode, lastCompleteNode.getOffset());
    EObject previousModel = previousNode.getSemanticElement();
    INode currentDatatypeNode = getContainingDatatypeRuleNode(currentNode);
    Collection<FollowElement> followElements = getParser().getFollowElements(rootNode, 0, lastCompleteNode.getOffset(), true);
    int prevSize = contextBuilders.size();
    doCreateContexts(previousNode, currentDatatypeNode, prefix, previousModel, followElements);
    if (lastCompleteNode instanceof ILeafNode && lastCompleteNode.getGrammarElement() == null && contextBuilders.size() != prevSize) {
        handleLastCompleteNodeHasNoGrammarElement(contextBuilders.subList(prevSize, contextBuilders.size()), previousModel);
    }
}
Also used : INode(org.eclipse.xtext.nodemodel.INode) ILeafNode(org.eclipse.xtext.nodemodel.ILeafNode) EObject(org.eclipse.emf.ecore.EObject) FollowElement(org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement)

Example 13 with FollowElement

use of org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement in project n4js by eclipse.

the class ContentAssistContextFactory method handleLastCompleteNodeAsPartOfDatatypeNode.

@Override
protected void handleLastCompleteNodeAsPartOfDatatypeNode() {
    String prefix = getPrefix(datatypeNode);
    Collection<FollowElement> followElements = getParser().getFollowElements(rootNode, 0, datatypeNode.getOffset(), true);
    INode lastCompleteNodeBeforeDatatype = getLastCompleteNodeByOffset(rootNode, datatypeNode.getTotalOffset());
    doCreateContexts(lastCompleteNodeBeforeDatatype, datatypeNode, prefix, currentModel, followElements);
}
Also used : INode(org.eclipse.xtext.nodemodel.INode) FollowElement(org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement)

Aggregations

FollowElement (org.eclipse.xtext.ide.editor.contentassist.antlr.FollowElement)13 AbstractElement (org.eclipse.xtext.AbstractElement)3 Bug303200TestLanguageParser (org.eclipse.xtext.ui.tests.editor.contentassist.ide.contentassist.antlr.Bug303200TestLanguageParser)3 Test (org.junit.Test)3 Token (org.antlr.runtime.Token)2 TokenSource (org.antlr.runtime.TokenSource)2 EObject (org.eclipse.emf.ecore.EObject)2 ParserRule (org.eclipse.xtext.ParserRule)2 UnorderedGroup (org.eclipse.xtext.UnorderedGroup)2 INode (org.eclipse.xtext.nodemodel.INode)2 IUnorderedGroupHelper (org.eclipse.xtext.parser.antlr.IUnorderedGroupHelper)2 IOException (java.io.IOException)1 StringReader (java.io.StringReader)1 ArrayList (java.util.ArrayList)1 ANTLRStringStream (org.antlr.runtime.ANTLRStringStream)1 BaseRecognizer (org.antlr.runtime.BaseRecognizer)1 CommonToken (org.antlr.runtime.CommonToken)1 InternalFlexer (org.eclipse.xtend.core.parser.InternalFlexer)1 Assignment (org.eclipse.xtext.Assignment)1 Group (org.eclipse.xtext.Group)1