Search in sources :

Example 56 with AbstractElement

use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.

the class EntryPointFinder method findEntryPoint.

public ICompositeNode findEntryPoint(IParseResult parseResult, int offset) {
    ICompositeNode rootNode = parseResult.getRootNode();
    if (rootNode.getTotalLength() == offset) {
        return null;
    }
    ILeafNode leafNode = NodeModelUtils.findLeafNodeAtOffset(rootNode, offset);
    ICompositeNode parent = leafNode.getParent();
    ICompositeNode result = findEntryPoint(parent, offset);
    if (result != null) {
        EObject grammarElement = result.getGrammarElement();
        if (grammarElement instanceof AbstractElement) {
            return result;
        }
    }
    return null;
}
Also used : ILeafNode(org.eclipse.xtext.nodemodel.ILeafNode) AbstractElement(org.eclipse.xtext.AbstractElement) EObject(org.eclipse.emf.ecore.EObject) ICompositeNode(org.eclipse.xtext.nodemodel.ICompositeNode)

Example 57 with AbstractElement

use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.

the class EntryPointFinder method shouldUseParent.

protected boolean shouldUseParent(ICompositeNode result, int offset, ILeafNode leaf) {
    if (leaf.getTotalEndOffset() == offset) {
        return true;
    }
    if (result.getGrammarElement() instanceof RuleCall) {
        RuleCall rc = (RuleCall) result.getGrammarElement();
        if (!rc.getArguments().isEmpty()) {
            return true;
        }
        Assignment assignment = GrammarUtil.containingAssignment(rc);
        if (assignment != null && (GrammarUtil.isMultipleCardinality(assignment) || (assignment.eContainer() instanceof AbstractElement && GrammarUtil.isMultipleCardinality((AbstractElement) assignment.eContainer())))) {
            return true;
        }
    }
    return false;
}
Also used : Assignment(org.eclipse.xtext.Assignment) AbstractElement(org.eclipse.xtext.AbstractElement) RuleCall(org.eclipse.xtext.RuleCall)

Example 58 with AbstractElement

use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.

the class FollowElementCalculator method caseUnorderedGroup.

@Override
public Boolean caseUnorderedGroup(UnorderedGroup object) {
    if (object == this.group) {
        boolean more = true;
        for (AbstractElement element : object.getElements()) {
            if (handledAlternatives == null || !handledAlternatives.contains(element)) {
                this.group = null;
                more = doSwitch(element) && more;
                this.group = object;
            }
        }
        if (more && GrammarUtil.isMultipleCardinality(object)) {
            handledAlternatives = null;
            this.group = null;
            return caseUnorderedGroup(object);
        }
        return more || isOptional(object);
    } else {
        boolean more = true;
        for (AbstractElement element : object.getElements()) {
            more = doSwitch(element) && more;
        }
        return more || isOptional(object);
    }
}
Also used : AbstractElement(org.eclipse.xtext.AbstractElement)

Example 59 with AbstractElement

use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.

the class FollowElementComputer method computeFollowElements.

protected void computeFollowElements(FollowElementCalculator calculator, FollowElement element, Multimap<Integer, List<AbstractElement>> visited) {
    List<AbstractElement> currentState = Lists.newArrayList(element.getLocalTrace());
    if (currentState.isEmpty() || currentState.get(currentState.size() - 1) != element.getGrammarElement()) {
        currentState.add(element.getGrammarElement());
    }
    if (!visited.put(element.getLookAhead(), currentState))
        return;
    if (element.getLookAhead() <= 1) {
        List<Integer> paramStack = element.getParamStack();
        int paramIndex = computeParamStackOffset(currentState, paramStack);
        for (AbstractElement abstractElement : currentState) {
            paramIndex = setParamConfigAndUpdateOffset(calculator, paramStack, paramIndex, abstractElement);
            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 : Group(org.eclipse.xtext.Group) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) ParserRule(org.eclipse.xtext.ParserRule) AbstractElement(org.eclipse.xtext.AbstractElement) RuleCall(org.eclipse.xtext.RuleCall) Assignment(org.eclipse.xtext.Assignment) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) EObject(org.eclipse.emf.ecore.EObject)

Example 60 with AbstractElement

use of org.eclipse.xtext.AbstractElement in project xtext-core by eclipse.

the class RequiredRuleNameComputer method getRequiredRuleNames.

/**
 * Returns the names of parser rules that should be called in order to obtain the follow elements for the parser
 * call stack described by the given param.
 */
public String[][] getRequiredRuleNames(Param param) {
    if (isFiltered(param)) {
        return EMPTY_ARRAY;
    }
    AbstractElement elementToParse = param.elementToParse;
    String ruleName = param.ruleName;
    if (ruleName == null) {
        return getRequiredRuleNames(param, elementToParse);
    }
    return getAdjustedRequiredRuleNames(param, elementToParse, ruleName);
}
Also used : AbstractElement(org.eclipse.xtext.AbstractElement)

Aggregations

AbstractElement (org.eclipse.xtext.AbstractElement)126 EObject (org.eclipse.emf.ecore.EObject)39 AbstractRule (org.eclipse.xtext.AbstractRule)34 StringConcatenation (org.eclipse.xtend2.lib.StringConcatenation)31 RuleCall (org.eclipse.xtext.RuleCall)26 ParserRule (org.eclipse.xtext.ParserRule)18 Grammar (org.eclipse.xtext.Grammar)17 EList (org.eclipse.emf.common.util.EList)15 Assignment (org.eclipse.xtext.Assignment)15 Test (org.junit.Test)14 Group (org.eclipse.xtext.Group)13 UnorderedGroup (org.eclipse.xtext.UnorderedGroup)13 List (java.util.List)12 ArrayList (java.util.ArrayList)11 XtextResource (org.eclipse.xtext.resource.XtextResource)11 Action (org.eclipse.xtext.Action)10 TerminalRule (org.eclipse.xtext.TerminalRule)10 Alternatives (org.eclipse.xtext.Alternatives)9 EClassifier (org.eclipse.emf.ecore.EClassifier)8 InternalEObject (org.eclipse.emf.ecore.InternalEObject)8