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;
}
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);
}
}
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);
}
}
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);
}
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);
}
Aggregations