Search in sources :

Example 21 with Group

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

the class ConcreteSyntaxConstraintProvider method createSummarizedAssignments.

protected List<ISyntaxConstraint> createSummarizedAssignments(CompoundElement group, List<AbstractElement> candidates, EClass semanticType, boolean optional) {
    Multimap<String, Assignment> feature2ass = HashMultimap.create();
    Multimap<String, AbstractElement> feature2child = HashMultimap.create();
    for (AbstractElement c : candidates) {
        TreeIterator<EObject> i = EcoreUtil2.eAll(c);
        while (i.hasNext()) {
            EObject obj = i.next();
            if (obj instanceof RuleCall || obj instanceof Action || obj instanceof Alternatives)
                return Lists.newArrayList();
            else if (obj instanceof Group) {
                Set<String> names = Sets.newHashSet();
                for (Assignment ass : EcoreUtil2.getAllContentsOfType(obj, Assignment.class)) names.add(ass.getFeature());
                if (names.size() > 1)
                    i.prune();
            } else if (obj instanceof Assignment) {
                Assignment a = (Assignment) obj;
                feature2ass.put(a.getFeature(), a);
                feature2child.put(a.getFeature(), c);
                i.prune();
            }
        }
    }
    List<ISyntaxConstraint> result = Lists.newArrayList();
    for (Map.Entry<String, Collection<Assignment>> ent : feature2ass.asMap().entrySet()) {
        if (ent.getValue().size() < 2 || feature2child.get(ent.getKey()).size() < 2)
            continue;
        int required = 0, multiplies = 0;
        for (Assignment assignment : ent.getValue()) {
            AbstractElement e = assignment;
            while (e != group) if (isMultipleCardinality(e)) {
                multiplies++;
                break;
            } else
                e = (AbstractElement) e.eContainer();
            e = assignment;
            while (e != group) if (isOptionalCardinality(e))
                break;
            else
                e = (AbstractElement) e.eContainer();
            if (e == group)
                required++;
        }
        if (required > 1 || multiplies < 1)
            continue;
        candidates.removeAll(feature2child.get(ent.getKey()));
        optional = optional || required < 1;
        result.add(createElement(ConstraintType.ASSIGNMENT, ent.getValue().iterator().next(), semanticType, true, optional));
    }
    return result;
}
Also used : UnorderedGroup(org.eclipse.xtext.UnorderedGroup) Group(org.eclipse.xtext.Group) Action(org.eclipse.xtext.Action) HashSet(java.util.HashSet) Set(java.util.Set) AbstractElement(org.eclipse.xtext.AbstractElement) Alternatives(org.eclipse.xtext.Alternatives) RuleCall(org.eclipse.xtext.RuleCall) Assignment(org.eclipse.xtext.Assignment) EObject(org.eclipse.emf.ecore.EObject) Collection(java.util.Collection) Map(java.util.Map)

Example 22 with Group

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

the class XtextValidator method checkCurrentMustBeUnassigned.

private void checkCurrentMustBeUnassigned(final AbstractElement element) {
    final ParserRule rule = GrammarUtil.containingParserRule(element);
    if (GrammarUtil.isDatatypeRule(rule))
        return;
    XtextSwitch<Boolean> visitor = new XtextSwitch<Boolean>() {

        private boolean isNull = !rule.isFragment();

        @Override
        public Boolean caseAbstractElement(AbstractElement object) {
            return isNull;
        }

        @Override
        public Boolean caseAlternatives(Alternatives object) {
            final boolean wasIsNull = isNull;
            boolean localIsNull = wasIsNull;
            for (AbstractElement element : object.getElements()) {
                isNull = wasIsNull;
                localIsNull &= doSwitch(element);
            }
            isNull = localIsNull;
            return isNull;
        }

        @Override
        public Boolean caseUnorderedGroup(UnorderedGroup object) {
            final boolean wasIsNull = isNull;
            boolean localIsNull = wasIsNull;
            for (AbstractElement element : object.getElements()) {
                isNull = wasIsNull;
                localIsNull |= doSwitch(element);
            }
            isNull = localIsNull;
            return isNull;
        }

        @Override
        public Boolean caseAssignment(Assignment object) {
            isNull = false;
            return isNull;
        }

        @Override
        public Boolean caseGroup(Group object) {
            for (AbstractElement element : object.getElements()) doSwitch(element);
            return isNull;
        }

        @Override
        public Boolean caseAction(Action object) {
            if (object == element) {
                if (!(isNull && !isMany(object))) {
                    error("An unassigned action is not allowed, when the 'current' was already created.", object, null);
                    checkDone();
                }
            }
            isNull = false;
            return isNull;
        }

        @Override
        public Boolean caseRuleCall(RuleCall object) {
            if (object == element) {
                AbstractRule calledRule = object.getRule();
                if (calledRule instanceof ParserRule && ((ParserRule) calledRule).isFragment()) {
                    isNull = false;
                    return isNull;
                }
                if (!(isNull && !isMany(object))) {
                    error("An unassigned rule call is not allowed, when the 'current' was already created.", object, null);
                    checkDone();
                }
            }
            return doSwitch(object.getRule());
        }

        @Override
        public Boolean caseParserRule(ParserRule object) {
            isNull = GrammarUtil.isDatatypeRule(object);
            return isNull;
        }

        @Override
        public Boolean caseTerminalRule(TerminalRule object) {
            isNull = true;
            return isNull;
        }

        public boolean isMany(AbstractElement element) {
            return GrammarUtil.isMultipleCardinality(element) || ((element.eContainer() instanceof AbstractElement) && isMany((AbstractElement) element.eContainer()));
        }
    };
    visitor.doSwitch(rule.getAlternatives());
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) Group(org.eclipse.xtext.Group) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) Action(org.eclipse.xtext.Action) AbstractElement(org.eclipse.xtext.AbstractElement) Alternatives(org.eclipse.xtext.Alternatives) RuleCall(org.eclipse.xtext.RuleCall) Assignment(org.eclipse.xtext.Assignment) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) XtextSwitch(org.eclipse.xtext.util.XtextSwitch) TerminalRule(org.eclipse.xtext.TerminalRule) AbstractRule(org.eclipse.xtext.AbstractRule)

Example 23 with Group

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

the class XtextValidator method checkAssignedActionAfterAssignment.

@Check
public void checkAssignedActionAfterAssignment(final Action action) {
    if (action.getFeature() != null) {
        ParserRule rule = GrammarUtil.containingParserRule(action);
        if (rule.isFragment() && !rule.isWildcard()) {
            error("An action is not allowed in fragments.", action, null);
            return;
        }
        XtextSwitch<Boolean> visitor = new XtextSwitch<Boolean>() {

            private boolean assignedActionAllowed = false;

            @Override
            public Boolean caseAbstractElement(AbstractElement object) {
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseAlternatives(Alternatives object) {
                boolean wasActionAllowed = assignedActionAllowed;
                boolean localActionAllowed = true;
                for (AbstractElement element : object.getElements()) {
                    assignedActionAllowed = wasActionAllowed;
                    localActionAllowed &= doSwitch(element);
                }
                assignedActionAllowed = wasActionAllowed || (localActionAllowed && !GrammarUtil.isOptionalCardinality(object));
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseUnorderedGroup(UnorderedGroup object) {
                boolean wasActionAllowed = assignedActionAllowed;
                boolean localActionAllowed = false;
                for (AbstractElement element : object.getElements()) {
                    assignedActionAllowed = wasActionAllowed;
                    localActionAllowed |= doSwitch(element);
                }
                assignedActionAllowed = wasActionAllowed || (localActionAllowed && !GrammarUtil.isOptionalCardinality(object));
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseAssignment(Assignment object) {
                assignedActionAllowed = assignedActionAllowed || !GrammarUtil.isOptionalCardinality(object);
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseGroup(Group object) {
                boolean wasAssignedActionAllowed = assignedActionAllowed;
                for (AbstractElement element : object.getElements()) doSwitch(element);
                assignedActionAllowed = wasAssignedActionAllowed || (assignedActionAllowed && !GrammarUtil.isOptionalCardinality(object));
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseAction(Action object) {
                if (object == action) {
                    if (!assignedActionAllowed) {
                        error("An action is not allowed in fragments and when the current may still be unassigned.", null);
                        checkDone();
                    }
                }
                assignedActionAllowed = true;
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseRuleCall(RuleCall object) {
                if (object.getRule() == null)
                    return assignedActionAllowed;
                assignedActionAllowed = assignedActionAllowed || doSwitch(object.getRule()) && !GrammarUtil.isOptionalCardinality(object);
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseParserRule(ParserRule object) {
                assignedActionAllowed = !GrammarUtil.isDatatypeRule(object) && !object.isFragment();
                return assignedActionAllowed;
            }

            @Override
            public Boolean caseTerminalRule(TerminalRule object) {
                return assignedActionAllowed;
            }
        };
        visitor.doSwitch(rule.getAlternatives());
    }
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) Group(org.eclipse.xtext.Group) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) Action(org.eclipse.xtext.Action) AbstractElement(org.eclipse.xtext.AbstractElement) Alternatives(org.eclipse.xtext.Alternatives) RuleCall(org.eclipse.xtext.RuleCall) Assignment(org.eclipse.xtext.Assignment) UnorderedGroup(org.eclipse.xtext.UnorderedGroup) XtextSwitch(org.eclipse.xtext.util.XtextSwitch) TerminalRule(org.eclipse.xtext.TerminalRule) Check(org.eclipse.xtext.validation.Check)

Example 24 with Group

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

the class AntlrContentAssistGrammarGenerator method ruleImpl.

protected CharSequence ruleImpl(final Group it, final Grammar grammar, final AntlrOptions options, final int index) {
    StringConcatenation _builder = new StringConcatenation();
    String _contentAssistRuleName = AntlrGrammarGenUtil.getContentAssistRuleName(GrammarUtil.containingRule(it));
    _builder.append(_contentAssistRuleName);
    _builder.append("__");
    String _gaElementIdentifier = this._grammarAccessExtensions.gaElementIdentifier(AntlrGrammarGenUtil.<Group>getOriginalElement(it));
    _builder.append(_gaElementIdentifier);
    _builder.append("__");
    _builder.append(index);
    _builder.newLineIfNotEmpty();
    _builder.append("\t");
    _builder.append("@init {");
    _builder.newLine();
    _builder.append("\t\t");
    _builder.append("int stackSize = keepStackSize();");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("}");
    _builder.newLine();
    _builder.append(":");
    _builder.newLine();
    _builder.append("\t");
    String _contentAssistRuleName_1 = AntlrGrammarGenUtil.getContentAssistRuleName(GrammarUtil.containingRule(it));
    _builder.append(_contentAssistRuleName_1, "\t");
    _builder.append("__");
    String _gaElementIdentifier_1 = this._grammarAccessExtensions.gaElementIdentifier(AntlrGrammarGenUtil.<Group>getOriginalElement(it));
    _builder.append(_gaElementIdentifier_1, "\t");
    _builder.append("__");
    _builder.append(index, "\t");
    _builder.append("__Impl");
    _builder.newLineIfNotEmpty();
    {
        int _size = it.getElements().size();
        boolean _greaterThan = (_size > (index + 1));
        if (_greaterThan) {
            _builder.append("\t");
            String _contentAssistRuleName_2 = AntlrGrammarGenUtil.getContentAssistRuleName(GrammarUtil.containingRule(it));
            _builder.append(_contentAssistRuleName_2, "\t");
            _builder.append("__");
            String _gaElementIdentifier_2 = this._grammarAccessExtensions.gaElementIdentifier(AntlrGrammarGenUtil.<Group>getOriginalElement(it));
            _builder.append(_gaElementIdentifier_2, "\t");
            _builder.append("__");
            _builder.append((index + 1), "\t");
            _builder.newLineIfNotEmpty();
        }
    }
    _builder.append(";");
    _builder.newLine();
    _builder.append("finally {");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("restoreStackSize(stackSize);");
    _builder.newLine();
    _builder.append("}");
    _builder.newLine();
    _builder.newLine();
    String _contentAssistRuleName_3 = AntlrGrammarGenUtil.getContentAssistRuleName(GrammarUtil.containingRule(it));
    _builder.append(_contentAssistRuleName_3);
    _builder.append("__");
    String _gaElementIdentifier_3 = this._grammarAccessExtensions.gaElementIdentifier(AntlrGrammarGenUtil.<Group>getOriginalElement(it));
    _builder.append(_gaElementIdentifier_3);
    _builder.append("__");
    _builder.append(index);
    _builder.append("__Impl");
    _builder.newLineIfNotEmpty();
    _builder.append("\t");
    _builder.append("@init {");
    _builder.newLine();
    _builder.append("\t\t");
    _builder.append("int stackSize = keepStackSize();");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("}");
    _builder.newLine();
    _builder.append(":");
    _builder.newLine();
    String _ebnf = this.ebnf(it.getElements().get(index), options, false);
    _builder.append(_ebnf);
    _builder.newLineIfNotEmpty();
    _builder.append(";");
    _builder.newLine();
    _builder.append("finally {");
    _builder.newLine();
    _builder.append("\t");
    _builder.append("restoreStackSize(stackSize);");
    _builder.newLine();
    _builder.append("}");
    _builder.newLine();
    _builder.newLine();
    {
        int _size_1 = it.getElements().size();
        boolean _greaterThan_1 = (_size_1 > (index + 1));
        if (_greaterThan_1) {
            CharSequence _ruleImpl = this.ruleImpl(it, grammar, options, (index + 1));
            _builder.append(_ruleImpl);
            _builder.newLineIfNotEmpty();
        }
    }
    return _builder;
}
Also used : UnorderedGroup(org.eclipse.xtext.UnorderedGroup) Group(org.eclipse.xtext.Group) StringConcatenation(org.eclipse.xtend2.lib.StringConcatenation)

Example 25 with Group

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

the class XtextParserTest method testParseCrossRef.

@Test
public void testParseCrossRef() throws Exception {
    Grammar model = (Grammar) getModel("grammar foo with org.eclipse.xtext.common.Terminals " + "generate foo 'bar' as boo " + "Model returns boo::Model : 'a' stuff+=Stuff*; " + "Stuff returns boo::Stuff : 'stuff' name=ID refersTo=[boo::Stuff];");
    AbstractRule rule = model.getRules().get(1);
    Group group = (Group) rule.getAlternatives();
    Assignment assignment = (Assignment) group.getElements().get(2);
    CrossReference reference = (CrossReference) assignment.getTerminal();
    assertEquals("boo", reference.getType().getMetamodel().getAlias());
    // assertWithXtend("'boo'", "eAllContents.typeSelect(xtext::CrossReference).first().type.metamodel.alias", model);
    assertEquals("Stuff", reference.getType().getClassifier().getName());
// assertWithXtend("'Stuff'", "eAllContents.typeSelect(xtext::CrossReference).first().type.classifier.name", model);
}
Also used : Assignment(org.eclipse.xtext.Assignment) Group(org.eclipse.xtext.Group) CrossReference(org.eclipse.xtext.CrossReference) Grammar(org.eclipse.xtext.Grammar) AbstractRule(org.eclipse.xtext.AbstractRule) Test(org.junit.Test)

Aggregations

Group (org.eclipse.xtext.Group)34 AbstractElement (org.eclipse.xtext.AbstractElement)16 RuleCall (org.eclipse.xtext.RuleCall)16 UnorderedGroup (org.eclipse.xtext.UnorderedGroup)15 Test (org.junit.Test)14 AbstractRule (org.eclipse.xtext.AbstractRule)13 Assignment (org.eclipse.xtext.Assignment)13 ParserRule (org.eclipse.xtext.ParserRule)13 EObject (org.eclipse.emf.ecore.EObject)10 Grammar (org.eclipse.xtext.Grammar)10 Alternatives (org.eclipse.xtext.Alternatives)9 Action (org.eclipse.xtext.Action)6 Parameter (org.eclipse.xtext.Parameter)5 TerminalRule (org.eclipse.xtext.TerminalRule)5 CompoundElement (org.eclipse.xtext.CompoundElement)4 ArrayList (java.util.ArrayList)3 Keyword (org.eclipse.xtext.Keyword)3 NamedArgument (org.eclipse.xtext.NamedArgument)3 ParameterReference (org.eclipse.xtext.ParameterReference)3 XtextSwitch (org.eclipse.xtext.util.XtextSwitch)3