@Check public void checkPatternCallParameters(PatternCall call) { if (call.getPatternRef() != null && call.getPatternRef().getName() != null && call.getParameters() != null) { final int definitionParameterSize = call.getPatternRef().getParameters().size(); final int callParameterSize = call.getParameters().size(); if (definitionParameterSize != callParameterSize) { error("The pattern " + getFormattedPattern(call.getPatternRef()) + " is not applicable for the arguments(" + getFormattedArgumentsList(call) + ")", PatternLanguagePackage.Literals.PATTERN_CALL__PATTERN_REF, IssueCodes.WRONG_NUMBER_PATTERNCALL_PARAMETER); } } }
private String prettyPrintPatternCall(PatternCall call) { return (isNegativePatternCall(call) ? "neg " : "") + call.getPatternRef().getName(); }
/** Finds all patterns referenced from the given pattern. */ public static Set<Pattern> getReferencedPatterns(Pattern sourcePattern) { Set<Pattern> result = new HashSet<Pattern>(); TreeIterator<EObject> eAllContents = sourcePattern.eAllContents(); while (eAllContents.hasNext()) { EObject element = eAllContents.next(); if (element instanceof PatternCall) { PatternCall call = (PatternCall) element; final Pattern patternRef = call.getPatternRef(); if (patternRef != null) { result.add(patternRef); } } } return result; }
@Check public void checkPrivatePatternCall(PatternCall call) { final Pattern calledPattern = call.getPatternRef(); if (calledPattern != null) { if (Iterables.any(calledPattern.getModifiers(), new Predicate<Modifiers>() { @Override public boolean apply(Modifiers input) { return input.isPrivate(); } }) && calledPattern.eResource() != call.eResource()) { error(String.format("The pattern %s is not visible.", getFormattedPattern(calledPattern)), PatternLanguagePackage.Literals.PATTERN_CALL__PATTERN_REF, IssueCodes.PRIVATE_PATTERN_CALLED); } } }
@Override public Map<PatternCall, Set<PatternCall>> get() { Map<PatternCall, Set<PatternCall>> graph = new HashMap<PatternCall, Set<PatternCall>>(); TreeIterator<EObject> resourceIterator = resource.getAllContents(); while (resourceIterator.hasNext()) { EObject resourceContent = resourceIterator.next(); if (resourceContent instanceof PatternCall) { PatternCall source = (PatternCall) resourceContent; Set<PatternCall> targets = new TreeSet<PatternCall>(patternCallComparator); graph.put(source, targets); TreeIterator<EObject> headIterator = source.getPatternRef().eAllContents(); while (headIterator.hasNext()) { EObject headContent = headIterator.next(); if (headContent instanceof PatternCall) { PatternCall target = (PatternCall) headContent; targets.add(target); } } } } return graph; } }
@SuppressWarnings("restriction") @Check public void checkPatternImports(XImportSection section) { if (!isIgnored(IMPORT_UNUSED)) { final Set<Pattern> usedPatterns = Sets.newHashSet(); final UnmodifiableIterator<PatternCall> it = Iterators.filter(section.eResource().getAllContents(), PatternCall.class); while (it.hasNext()) { PatternCall call = it.next(); usedPatterns.add(call.getPatternRef()); } for (PatternImport decl : section.getPatternImport()) { if (!usedPatterns.contains(decl.getPattern())) { warning("The import '" + CorePatternLanguageHelper.getFullyQualifiedName(decl.getPattern()) + "' is never used.", decl, null, IMPORT_UNUSED); } } } }
private String aggregate(AggregatedValue reference, PatternModelAcceptor<?> acceptor) throws SpecificationBuilderException { String resultVariableName = acceptor.createVirtualVariable(); PatternCall call = reference.getCall(); Pattern patternRef = call.getPatternRef(); List<String> variableNames = getVariableNames(call.getParameters(), acceptor); AggregatorExpression aggregator = reference.getAggregator(); if (aggregator instanceof CountAggregator) { acceptor.acceptPatternMatchCounter(variableNames, patternRef, resultVariableName); } else { throw new SpecificationBuilderException("Unsupported aggregator expression type {1} in pattern {2}.", new String[] { aggregator.eClass().getName(), patternFQN }, "Unsupported aggregator expression", pattern); } return resultVariableName; }
/** * This validator checks if the literal or computational values match the pattern call's type. * * @param patternCall */ @Check public void checkForWrongLiteralAndComputationValuesInPatternCalls(PatternCall patternCall) { if (patternCall.getParameters().size() != patternCall.getPatternRef().getParameters().size()) { //This kind of error is detected in another place, however it throws an exception during literal checks return; } // Find and neg find (including count find as well) for (ValueReference valueReference : patternCall.getParameters()) { if (valueReference instanceof LiteralValueReference || valueReference instanceof ComputationValue) { Pattern pattern = patternCall.getPatternRef(); Variable variable = pattern.getParameters().get(patternCall.getParameters().indexOf(valueReference)); EClassifier typeClassifier = emfTypeProvider.getClassifierForVariable(variable); EClassifier inputClassifier = emfTypeProvider .getClassifierForLiteralComputationEnumValueReference(valueReference); if (!isCompatibleClassifiers(typeClassifier, inputClassifier)) { final String typeClassifierName = typeClassifier == null ? "(unknown)" : typeClassifier.getInstanceClassName(); error("The type inferred from the called pattern (" + typeClassifierName + ") is different from the input literal/computational value (" + inputClassifier.getInstanceClassName() + ").", patternCall, null, EMFIssueCodes.LITERAL_OR_COMPUTATION_TYPE_MISMATCH_IN_PATTERN_CALL); } } } }
@Check public void checkApplicabilityOfTransitiveClosureInPatternCall(PatternCall call) { final Pattern patternRef = call.getPatternRef(); final EObject eContainer = call.eContainer(); if (patternRef != null && call.isTransitive()) {
VariableReference variableReference = variableValue.getValue(); if (isEqualVariables(variable, variableReference)) { Pattern pattern = patternCall.getPatternRef(); EList<Variable> parameters = pattern.getParameters();
private void gatherCompositionConstraint(PatternCompositionConstraint constraint, PatternModelAcceptor<?> acceptor) throws SpecificationBuilderException { PatternCall call = constraint.getCall(); Pattern patternRef = call.getPatternRef(); List<String> variableNames = getVariableNames(call.getParameters(), acceptor); if (!call.isTransitive()) { if (constraint.isNegative()) acceptor.acceptNegativePatternCall(variableNames, patternRef); else acceptor.acceptPositivePatternCall(variableNames, patternRef); } else { if (call.getParameters().size() != 2) throw new SpecificationBuilderException( "Transitive closure of {1} in pattern {2} is unsupported because called pattern is not binary.", new String[] { CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN }, "Transitive closure only supported for binary patterns.", pattern); else if (constraint.isNegative()) throw new SpecificationBuilderException("Unsupported negated transitive closure of {1} in pattern {2}", new String[] { CorePatternLanguageHelper.getFullyQualifiedName(patternRef), patternFQN }, "Unsupported negated transitive closure", pattern); else acceptor.acceptBinaryTransitiveClosure(variableNames, patternRef); } }