@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 boolean isNegativePatternCall(PatternCall call) { return (call.eContainer() instanceof PatternCompositionConstraint && ((PatternCompositionConstraint) call .eContainer()).isNegative()); }
@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); } } }
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); } }
@Check public void checkApplicabilityOfTransitiveClosureInPatternCall(PatternCall call) { final Pattern patternRef = call.getPatternRef(); final EObject eContainer = call.eContainer(); if (patternRef != null && call.isTransitive()) { if (patternRef.getParameters() != null) { final int arity = patternRef.getParameters().size();
protected String getFormattedArgumentsList(PatternCall call) { StringBuilder builder = new StringBuilder(); for (Iterator<ValueReference> iter = call.getParameters().iterator(); iter.hasNext();) { ValueReference parameter = iter.next(); builder.append(getConstantAsString(parameter)); if (iter.hasNext()) { builder.append(", "); } } return builder.toString(); }
private String prettyPrintPatternCall(PatternCall call) { return (isNegativePatternCall(call) ? "neg " : "") + call.getPatternRef().getName(); }
@Check public void checkRecursivePatternCall(PatternCall call) { Map<PatternCall, Set<PatternCall>> graph = cache.get(call.eResource(), call.eResource(), new CallGraphProvider( call.eResource())); LinkedList<PatternCall> result = dfsCheckCycle(call, graph); if (result != null) { StringBuffer buffer = new StringBuffer(); boolean first = true; for (PatternCall elem : result) { if (first) { first = false; } else { buffer.append(" -> "); } buffer.append(prettyPrintPatternCall(elem)); } if (isNegativePatternCall(call)) { error(String.format(RECURSIVE_PATTERN_CALL, buffer.toString()), call, PatternLanguagePackage.Literals.PATTERN_CALL__PATTERN_REF, IssueCodes.RECURSIVE_PATTERN_CALL); } else { warning(String.format(RECURSIVE_PATTERN_CALL, buffer.toString()), call, PatternLanguagePackage.Literals.PATTERN_CALL__PATTERN_REF, IssueCodes.RECURSIVE_PATTERN_CALL); } } }
/** * @param valueReference * @return all variables from the ValueReference object. (Either referenced directly, or referenced throught an * AggregatedValue.) */ public static Set<Variable> getVariablesFromValueReference(ValueReference valueReference) { Set<Variable> resultSet = new HashSet<Variable>(); if (valueReference != null) { if (valueReference instanceof VariableValue) { resultSet.add(((VariableValue) valueReference).getValue().getVariable()); } else if (valueReference instanceof AggregatedValue) { AggregatedValue aggregatedValue = (AggregatedValue) valueReference; for (ValueReference valueReferenceInner : aggregatedValue.getCall().getParameters()) { for (Variable variable : getVariablesFromValueReference(valueReferenceInner)) { resultSet.add(variable); } } } else if (valueReference instanceof FunctionEvaluationValue) { FunctionEvaluationValue eval = (FunctionEvaluationValue) valueReference; final List<Variable> usedVariables = CorePatternLanguageHelper.getUsedVariables(eval.getExpression(), containerPatternBody(eval).getVariables()); resultSet.addAll(usedVariables); } } return resultSet; }
/** 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; }
/** * 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); } } } }
for (ValueReference valueReferenceInner : aggregatedValue.getCall().getParameters()) { for (Variable variable : getUnnamedVariablesFromValueReference(valueReferenceInner, false)) { if (variable.getName().startsWith("_")) {
@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; } }
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; }
for (ValueReference valueReference : patternCompositionConstraint.getCall().getParameters()) { resultList.addAll(getUnnamedVariablesFromValueReference(valueReference, false));
@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); } } } }
PatternCall patternCall = patternCompositionConstraint.getCall(); int parameterIndex = 0; for (ValueReference valueReference : patternCall.getParameters()) { if (valueReference instanceof VariableValue) { VariableValue variableValue = (VariableValue) valueReference; VariableReference variableReference = variableValue.getValue(); if (isEqualVariables(variable, variableReference)) { Pattern pattern = patternCall.getPatternRef(); EList<Variable> parameters = pattern.getParameters();
if (!patternCompositionConstraint.isNegative()) { for (ValueReference valueReference : patternCompositionConstraint.getCall().getParameters()) { if (!isValueReferenceComputed(valueReference)) { positiveVariables.addAll(CorePatternLanguageHelper for (ValueReference valueReference : patternCompositionConstraint.getCall().getParameters()) { generalVariables.addAll(CorePatternLanguageHelper .getVariablesFromValueReference(valueReference)); if (!patternCompositionConstraint.isNegative()) { for (ValueReference valueReference : patternCompositionConstraint.getCall().getParameters()) { addPositiveVariablesFromValueReference(unnamedRunningVariables, justPositiveUnionFindForVariables, positiveVariables, valueReference);