Search in sources :

Example 71 with RuleCall

use of org.eclipse.xtext.RuleCall 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 72 with RuleCall

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

the class OverriddenValueInspector method checkAssignment.

private void checkAssignment(AbstractElement object, String feature) {
    if (assignedFeatures.containsKey(feature)) {
        Collection<AbstractElement> sources = Lists.newArrayList(assignedFeatures.get(feature));
        assignedFeatures.replaceValues(feature, Collections.<AbstractElement>emptyList());
        if (sources != null && sources.equals(Collections.singletonList(object))) {
            if (getNestingLevel() == 0 && fragmentStack.isEmpty()) {
                if (object instanceof RuleCall) {
                    acceptWarning("The fragment will possibly override the assigned value of feature '" + feature + "' it is used inside of a loop.", object, null);
                } else {
                    acceptWarning("The assigned value of feature '" + feature + "' will possibly override itself because it is used inside of a loop.", object, null);
                }
            }
        } else {
            if (sources != null) {
                if (getNestingLevel() == 0 && fragmentStack.isEmpty()) {
                    for (AbstractElement source : sources) {
                        acceptWarning("The possibly assigned value of feature '" + feature + "' may be overridden by subsequent assignments.", source, null);
                    }
                }
            }
            if (getNestingLevel() == 0 && fragmentStack.isEmpty()) {
                if (object instanceof RuleCall) {
                    acceptWarning("The fragment will potentially override the possibly assigned value of feature '" + feature + "'.", object, null);
                } else {
                    acceptWarning("This assignment will override the possibly assigned value of feature '" + feature + "'.", object, null);
                }
            }
        }
    } else {
        assignedFeatures.put(feature, object);
    }
}
Also used : AbstractElement(org.eclipse.xtext.AbstractElement) RuleCall(org.eclipse.xtext.RuleCall)

Example 73 with RuleCall

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

the class XtextLinker method setDefaultValueImpl.

@Override
protected void setDefaultValueImpl(EObject obj, EReference ref, IDiagnosticProducer producer) {
    if (XtextPackage.eINSTANCE.getTypeRef_Metamodel() == ref) {
        final TypeRef typeRef = (TypeRef) obj;
        final String typeRefName = GrammarUtil.getTypeRefName(typeRef);
        final List<EObject> metamodels = XtextMetamodelReferenceHelper.findBestMetamodelForType(typeRef, "", typeRefName, scopeProvider.getScope(typeRef, ref));
        if (metamodels.isEmpty() || metamodels.size() > 1)
            producer.addDiagnostic(new DiagnosticMessage("Cannot find meta model for type '" + typeRefName + "'", Severity.ERROR, null));
        else
            typeRef.setMetamodel((AbstractMetamodelDeclaration) metamodels.get(0));
    } else if (XtextPackage.eINSTANCE.getCrossReference_Terminal() == ref) {
        AbstractRule rule = GrammarUtil.findRuleForName(GrammarUtil.getGrammar(obj), "ID");
        if (rule == null)
            producer.addDiagnostic(new DiagnosticMessage("Cannot resolve implicit reference to rule 'ID'", Severity.ERROR, null));
        else {
            RuleCall call = XtextFactory.eINSTANCE.createRuleCall();
            call.setRule(rule);
            ((CrossReference) obj).setTerminal(call);
        }
    } else if (XtextPackage.eINSTANCE.getNamedArgument_Parameter() == ref) {
        final NamedArgument argument = (NamedArgument) obj;
        if (!argument.isCalledByName()) {
            RuleCall ruleCall = EcoreUtil2.getContainerOfType(argument, RuleCall.class);
            AbstractRule calledRule = ruleCall.getRule();
            if (!(calledRule instanceof ParserRule)) {
                producer.addDiagnostic(new DiagnosticMessage("Arguments can only be used with parser rules.", Severity.ERROR, null));
                return;
            }
            if (!calledRule.eIsProxy()) {
                ParserRule casted = (ParserRule) calledRule;
                int idx = ruleCall.getArguments().indexOf(argument);
                if (idx < casted.getParameters().size()) {
                    argument.setParameter(casted.getParameters().get(idx));
                    return;
                } else if (casted.getParameters().size() == 0) {
                    producer.addDiagnostic(new DiagnosticMessage("Rule " + calledRule.getName() + " has no arguments.", Severity.ERROR, null));
                } else {
                    String message = "Invalid number of arguments for rule " + calledRule.getName() + ", expecting " + casted.getParameters().size() + " but was " + (idx + 1);
                    producer.addDiagnostic(new DiagnosticMessage(message, Severity.ERROR, null));
                }
            }
        }
    } else {
        super.setDefaultValueImpl(obj, ref, producer);
    }
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) DiagnosticMessage(org.eclipse.xtext.diagnostics.DiagnosticMessage) TypeRef(org.eclipse.xtext.TypeRef) EObject(org.eclipse.emf.ecore.EObject) AbstractMetamodelDeclaration(org.eclipse.xtext.AbstractMetamodelDeclaration) NamedArgument(org.eclipse.xtext.NamedArgument) AbstractRule(org.eclipse.xtext.AbstractRule) RuleCall(org.eclipse.xtext.RuleCall)

Example 74 with RuleCall

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

the class XtextScopeProvider method getScope.

@Override
public IScope getScope(final EObject context, EReference reference) {
    if (reference == XtextPackage.eINSTANCE.getTypeRef_Classifier()) {
        if (context instanceof TypeRef) {
            final TypeRef typeRef = (TypeRef) context;
            final AbstractMetamodelDeclaration metaModel = typeRef.getMetamodel();
            if (metaModel != null) {
                EPackage pack = metaModel.getEPackage();
                if (pack != null)
                    return createClassifierScope(pack.getEClassifiers());
            } else {
                return createReferencedPackagesScope(GrammarUtil.getGrammar(context));
            }
        } else {
            return createReferencedPackagesScope(GrammarUtil.getGrammar(context));
        }
        return IScope.NULLSCOPE;
    }
    if (reference == XtextPackage.eINSTANCE.getEnumLiteralDeclaration_EnumLiteral()) {
        final EnumRule rule = GrammarUtil.containingEnumRule(context);
        if (rule.getType() != null && rule.getType().getClassifier() != null && rule.getType().getClassifier() instanceof EEnum) {
            return createEnumLiteralsScope((EEnum) rule.getType().getClassifier());
        }
        return IScope.NULLSCOPE;
    }
    if (reference == XtextPackage.eINSTANCE.getGrammar_UsedGrammars()) {
        return globalScopeProvider.getScope(context.eResource(), reference, new Predicate<IEObjectDescription>() {

            @Override
            public boolean apply(IEObjectDescription input) {
                return !input.getEObjectURI().equals(EcoreUtil.getURI(context));
            }
        });
    }
    if (reference == XtextPackage.eINSTANCE.getRuleCall_Rule()) {
        return createScope(context.eResource(), reference.getEReferenceType(), new SuperCallScope(context));
    }
    if (reference == XtextPackage.eINSTANCE.getParameterReference_Parameter()) {
        ParserRule rule = GrammarUtil.containingParserRule(context);
        if (rule == null) {
            return IScope.NULLSCOPE;
        }
        return Scopes.scopeFor(rule.getParameters());
    }
    if (reference == XtextPackage.eINSTANCE.getNamedArgument_Parameter()) {
        RuleCall ruleCall = EcoreUtil2.getContainerOfType(context, RuleCall.class);
        if (ruleCall == null) {
            return IScope.NULLSCOPE;
        }
        AbstractRule referencedRule = ruleCall.getRule();
        if (referencedRule instanceof ParserRule) {
            return Scopes.scopeFor(((ParserRule) referencedRule).getParameters());
        }
        return IScope.NULLSCOPE;
    }
    return createScope(context.eResource(), reference.getEReferenceType(), IScope.NULLSCOPE);
}
Also used : EnumRule(org.eclipse.xtext.EnumRule) ParserRule(org.eclipse.xtext.ParserRule) TypeRef(org.eclipse.xtext.TypeRef) EEnum(org.eclipse.emf.ecore.EEnum) AbstractMetamodelDeclaration(org.eclipse.xtext.AbstractMetamodelDeclaration) AbstractRule(org.eclipse.xtext.AbstractRule) RuleCall(org.eclipse.xtext.RuleCall) EPackage(org.eclipse.emf.ecore.EPackage) IEObjectDescription(org.eclipse.xtext.resource.IEObjectDescription)

Example 75 with RuleCall

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

the class XtextTransientValueService method isTransient.

@Override
public boolean isTransient(EObject owner, EStructuralFeature feature, int index) {
    if (feature == XtextPackage.eINSTANCE.getTypeRef_Metamodel()) {
        final TypeRef typeRef = (TypeRef) owner;
        final AbstractMetamodelDeclaration m = typeRef.getMetamodel();
        if (m == null || Strings.isEmpty(m.getAlias()))
            return true;
    } else if (feature == XtextPackage.eINSTANCE.getAbstractRule_Type()) {
        final AbstractRule rule = (AbstractRule) owner;
        if (rule instanceof ParserRule || rule instanceof EnumRule) {
            final TypeRef returnType = rule.getType();
            if (returnType == null || returnType.getClassifier() == null)
                return true;
            else if (rule.getName().equals(returnType.getClassifier().getName())) {
                return isTransient(returnType, XtextPackage.eINSTANCE.getTypeRef_Metamodel(), -1);
            } else if (GrammarUtil.isDatatypeRule(rule)) {
                return NodeModelUtils.getNode(returnType) == null;
            }
        } else if (rule instanceof TerminalRule) {
            final TypeRef returnType = rule.getType();
            return ((TerminalRule) rule).isFragment() || returnType == null || GrammarUtil.findEString(GrammarUtil.getGrammar(owner)).equals(rule.getType().getClassifier());
        }
    } else if (feature == XtextPackage.eINSTANCE.getCrossReference_Terminal()) {
        final CrossReference ref = (CrossReference) owner;
        if (ref.getTerminal() instanceof RuleCall && ((RuleCall) ref.getTerminal()).getRule() != null && "ID".equals(((RuleCall) ref.getTerminal()).getRule().getName()))
            return true;
    } else if (feature == XtextPackage.eINSTANCE.getEnumLiteralDeclaration_Literal()) {
        final EnumLiteralDeclaration decl = (EnumLiteralDeclaration) owner;
        return decl.getEnumLiteral() != null && decl.getLiteral() != null && Strings.equal(decl.getLiteral().getValue(), decl.getEnumLiteral().getName());
    } else if (feature == XtextPackage.eINSTANCE.getRuleCall_ExplicitlyCalled()) {
        return true;
    } else if (feature == XtextPackage.eINSTANCE.getNamedArgument_Parameter()) {
        return !((NamedArgument) owner).isCalledByName();
    }
    return super.isTransient(owner, feature, index);
}
Also used : ParserRule(org.eclipse.xtext.ParserRule) EnumRule(org.eclipse.xtext.EnumRule) EnumLiteralDeclaration(org.eclipse.xtext.EnumLiteralDeclaration) TypeRef(org.eclipse.xtext.TypeRef) CrossReference(org.eclipse.xtext.CrossReference) AbstractMetamodelDeclaration(org.eclipse.xtext.AbstractMetamodelDeclaration) TerminalRule(org.eclipse.xtext.TerminalRule) NamedArgument(org.eclipse.xtext.NamedArgument) AbstractRule(org.eclipse.xtext.AbstractRule) RuleCall(org.eclipse.xtext.RuleCall)

Aggregations

RuleCall (org.eclipse.xtext.RuleCall)95 ParserRule (org.eclipse.xtext.ParserRule)41 AbstractRule (org.eclipse.xtext.AbstractRule)36 EObject (org.eclipse.emf.ecore.EObject)33 Test (org.junit.Test)33 Grammar (org.eclipse.xtext.Grammar)28 AbstractElement (org.eclipse.xtext.AbstractElement)26 Assignment (org.eclipse.xtext.Assignment)22 TerminalRule (org.eclipse.xtext.TerminalRule)19 Action (org.eclipse.xtext.Action)17 CrossReference (org.eclipse.xtext.CrossReference)13 Group (org.eclipse.xtext.Group)13 TypeRef (org.eclipse.xtext.TypeRef)13 UnorderedGroup (org.eclipse.xtext.UnorderedGroup)13 ArrayList (java.util.ArrayList)11 StringConcatenation (org.eclipse.xtend2.lib.StringConcatenation)11 InternalEObject (org.eclipse.emf.ecore.InternalEObject)10 Keyword (org.eclipse.xtext.Keyword)10 EClass (org.eclipse.emf.ecore.EClass)9 EnumRule (org.eclipse.xtext.EnumRule)9