Search in sources :

Example 1 with XtextSwitch

use of org.eclipse.xtext.util.XtextSwitch in project xtext-core by eclipse.

the class Xtext2EcoreTransformer method deriveFeatures.

private Xtext2EcoreInterpretationContext deriveFeatures(final Xtext2EcoreInterpretationContext context, AbstractElement element) {
    XtextSwitch<Xtext2EcoreInterpretationContext> visitor = new XtextSwitch<Xtext2EcoreInterpretationContext>() {

        /*
			 * Used for Alternatives and UnorderedGroups
			 */
        @Override
        public Xtext2EcoreInterpretationContext caseCompoundElement(CompoundElement object) {
            List<Xtext2EcoreInterpretationContext> contexts = new ArrayList<Xtext2EcoreInterpretationContext>();
            for (AbstractElement group : object.getElements()) {
                contexts.add(deriveFeatures(context, group));
            }
            Xtext2EcoreInterpretationContext result = context;
            if (!contexts.isEmpty()) {
                if (GrammarUtil.isOptionalCardinality(object)) {
                    contexts.add(0, result);
                } else {
                    result = contexts.get(0);
                }
                result = result.mergeSpawnedContexts(contexts);
            }
            return result;
        }

        @Override
        public Xtext2EcoreInterpretationContext caseAssignment(Assignment object) {
            try {
                context.addFeature(object);
            } catch (TransformationException ex) {
                reportError(ex);
            }
            return context;
        }

        @Override
        public Xtext2EcoreInterpretationContext caseGroup(Group object) {
            return visitElements(object, object.getElements());
        }

        private Xtext2EcoreInterpretationContext visitElements(AbstractElement caller, List<AbstractElement> elementsToProcess) {
            Xtext2EcoreInterpretationContext result = deriveFeatures(context.spawnContextForGroup(), elementsToProcess);
            if (GrammarUtil.isMultipleCardinality(caller)) {
                result = deriveFeatures(result.spawnContextForGroup(), elementsToProcess);
            }
            if (GrammarUtil.isOptionalCardinality(caller)) {
                result = result.mergeSpawnedContexts(Arrays.asList(context, result));
            }
            return result;
        }

        @Override
        public Xtext2EcoreInterpretationContext caseAlternatives(Alternatives object) {
            List<Xtext2EcoreInterpretationContext> contexts = newArrayList();
            if (GrammarUtil.isOptionalCardinality(object)) {
                contexts.add(context);
            }
            for (AbstractElement alternative : object.getElements()) {
                contexts.add(deriveFeatures(context.spawnContextForGroup(), alternative));
            }
            Xtext2EcoreInterpretationContext result = context.mergeSpawnedContexts(contexts);
            if (GrammarUtil.isMultipleCardinality(object)) {
                for (AbstractElement alternative : object.getElements()) {
                    deriveFeatures(result.spawnContextForGroup(), alternative);
                }
            }
            return result;
        }

        @Override
        public Xtext2EcoreInterpretationContext caseRuleCall(RuleCall object) {
            AbstractRule calledRule = object.getRule();
            if (isWildcardFragment(calledRule)) {
                AbstractElement ruleBody = calledRule.getAlternatives();
                if (ruleBody != null) {
                    return visitElements(object, Collections.singletonList(ruleBody));
                }
                return context;
            }
            if (isParserRuleFragment(calledRule)) {
                return context;
            }
            if (!GrammarUtil.isOptionalCardinality(object)) {
                // announced during the first iteration
                if (calledRule != null && calledRule instanceof ParserRule && !GrammarUtil.isDatatypeRule((ParserRule) calledRule)) {
                    try {
                        EClassifierInfo eClassifierInfo = findOrCreateEClassifierInfo(calledRule);
                        return context.spawnContextWithCalledRule(eClassifierInfo, object);
                    } catch (TransformationException e) {
                        reportError(e);
                    }
                }
            }
            return context;
        }

        @Override
        public Xtext2EcoreInterpretationContext caseAction(Action object) {
            try {
                TypeRef actionTypeRef = object.getType();
                EClassifierInfo actionType = findOrCreateEClassifierInfo(actionTypeRef, null, true);
                Xtext2EcoreInterpretationContext ctx = context.spawnContextWithReferencedType(actionType, object);
                if (object.getFeature() != null) {
                    ctx.addFeature(object.getFeature(), context, GrammarUtil.isMultipleAssignment(object), true, object);
                }
                return ctx;
            } catch (TransformationException e) {
                reportError(e);
            }
            return context;
        }

        @Override
        public Xtext2EcoreInterpretationContext defaultCase(EObject object) {
            return context;
        }
    };
    return visitor.doSwitch(element);
}
Also used : Group(org.eclipse.xtext.Group) ParserRule(org.eclipse.xtext.ParserRule) Action(org.eclipse.xtext.Action) AbstractElement(org.eclipse.xtext.AbstractElement) TypeRef(org.eclipse.xtext.TypeRef) ArrayList(java.util.ArrayList) Alternatives(org.eclipse.xtext.Alternatives) RuleCall(org.eclipse.xtext.RuleCall) Assignment(org.eclipse.xtext.Assignment) EObject(org.eclipse.emf.ecore.EObject) InternalEObject(org.eclipse.emf.ecore.InternalEObject) List(java.util.List) ArrayList(java.util.ArrayList) XtextSwitch(org.eclipse.xtext.util.XtextSwitch) CompoundElement(org.eclipse.xtext.CompoundElement) AbstractRule(org.eclipse.xtext.AbstractRule)

Example 2 with XtextSwitch

use of org.eclipse.xtext.util.XtextSwitch in project dsl-devkit by dsldevkit.

the class GeneratorUtil method collectInstantiatedTypes.

/**
 * Collects instantiated EClasses for a grammar and all included grammar recursively.
 *
 * @param grammar
 *          Xtext grammar
 * @param result
 *          set to add instantiated types to
 */
private static void collectInstantiatedTypes(final Grammar grammar, final Set<EClass> result) {
    XtextSwitch<Void> xtextSwitch = new XtextSwitch<Void>() {

        @Override
        public Void caseParserRule(final ParserRule object) {
            EClassifier eClassifier = object.getType().getClassifier();
            if (eClassifier instanceof EClass) {
                result.add((EClass) eClassifier);
            }
            return null;
        }

        @Override
        public Void caseAction(final Action object) {
            EClassifier eClassifier = object.getType().getClassifier();
            result.add((EClass) eClassifier);
            return null;
        }
    };
    for (TreeIterator<EObject> it = EcoreUtil.getAllProperContents(grammar, false); it.hasNext(); ) {
        xtextSwitch.doSwitch(it.next());
    }
    for (Grammar includedGrammar : grammar.getUsedGrammars()) {
        collectInstantiatedTypes(includedGrammar, result);
    }
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) EClass(org.eclipse.emf.ecore.EClass) Action(org.eclipse.xtext.Action) EObject(org.eclipse.emf.ecore.EObject) EClassifier(org.eclipse.emf.ecore.EClassifier) Grammar(org.eclipse.xtext.Grammar) XtextSwitch(org.eclipse.xtext.util.XtextSwitch)

Example 3 with XtextSwitch

use of org.eclipse.xtext.util.XtextSwitch 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) {
            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 4 with XtextSwitch

use of org.eclipse.xtext.util.XtextSwitch 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.", object, 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)

Aggregations

Action (org.eclipse.xtext.Action)4 ParserRule (org.eclipse.xtext.ParserRule)4 XtextSwitch (org.eclipse.xtext.util.XtextSwitch)4 AbstractElement (org.eclipse.xtext.AbstractElement)3 Alternatives (org.eclipse.xtext.Alternatives)3 Assignment (org.eclipse.xtext.Assignment)3 Group (org.eclipse.xtext.Group)3 RuleCall (org.eclipse.xtext.RuleCall)3 EObject (org.eclipse.emf.ecore.EObject)2 AbstractRule (org.eclipse.xtext.AbstractRule)2 TerminalRule (org.eclipse.xtext.TerminalRule)2 UnorderedGroup (org.eclipse.xtext.UnorderedGroup)2 ArrayList (java.util.ArrayList)1 List (java.util.List)1 EClass (org.eclipse.emf.ecore.EClass)1 EClassifier (org.eclipse.emf.ecore.EClassifier)1 InternalEObject (org.eclipse.emf.ecore.InternalEObject)1 CompoundElement (org.eclipse.xtext.CompoundElement)1 Grammar (org.eclipse.xtext.Grammar)1 TypeRef (org.eclipse.xtext.TypeRef)1