@Check(CheckType.NORMAL) public void checkVariableNames(PatternBody body) { for (Variable var1 : body.getVariables()) { Variable otherVar = null; for (Variable var2 : body.getVariables()) { if (isNamedSingleUse(var1) && var1.getSimpleName().substring(1).equals(var2.getName())) { otherVar = var2; } } if (otherVar != null) { if (var1.eContainer() instanceof PatternBody && !var1.getReferences().isEmpty()) { // Local variables do not have source location warning(String.format( "Dubius variable naming: Single use variable %s shares its name with the variable %s", var1.getSimpleName(), otherVar.getSimpleName()), var1.getReferences().get(0), PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VARIABLE, IssueCodes.DUBIUS_VARIABLE_NAME); } else { warning(String.format( "Dubius variable naming: Single use variable %s shares its name with the variable %s", var1.getSimpleName(), otherVar.getSimpleName()), var1, PatternLanguagePackage.Literals.VARIABLE__NAME, IssueCodes.DUBIUS_VARIABLE_NAME); } } } }
@Override public EClassifier getClassifierForVariable(Variable variable) { if (!variable.eIsProxy()) { EObject container = variable.eContainer(); if (container instanceof Pattern) { return getClassifierForParameterVariable((Pattern) container, variable, 0); } else if (container instanceof PatternBody) { return getClassifierForVariableWithPatternBody((PatternBody) container, variable, 0, null); } } return null; }
@Check public void checkMissingParameterTypes(Variable variable) { if (variable.eContainer() instanceof Pattern && variable.getType() == null) { Pattern pattern = (Pattern) variable.eContainer(); Set<EClassifier> possibleTypes = Sets.newHashSet(); for (PatternBody body : pattern.getBodies()) { possibleTypes.addAll(emfTypeProvider.getIrreducibleClassifiersForVariableInBody(body, variable)); } Iterable<String> typeNames = Iterables.transform(Iterables.filter(possibleTypes, EClass.class), new Function<EClassifier, String>() { @Override public String apply(EClassifier input) { final String name = input.getName(); return (Strings.isEmpty(name)) ? "" : name; } }); String[] issueData = Iterables.toArray(typeNames, String.class); if (issueData.length > 0) { warning("Type not defined for variable " + variable.getName(), PatternLanguagePackage.Literals.VARIABLE__NAME, EMFIssueCodes.MISSING_PARAMETER_TYPE, issueData); } } }
private JvmTypeReference getTypeReferenceForTypeName(String typeName, EObject context) { JvmTypeReference typeRef = typeReferences.getTypeForName(typeName, context); JvmTypeReference typeReference = primitives.asWrapperTypeIfPrimitive(typeRef); if (typeReference == null) { EObject errorContext = context; String contextName = context.toString(); if (context instanceof Variable && ((Variable)context).eContainer() instanceof PatternBody && ((Variable)context).getReferences().size() > 0) { contextName = ((Variable)context).getName(); errorContext = ((Variable)context).getReferences().get(0); } errorFeedback.reportError( errorContext, String.format( "Cannot resolve corresponding Java type for variable %s. Are the required bundle dependencies set?", contextName), EMFPatternLanguageJvmModelInferrer.INVALID_TYPEREF_CODE, Severity.WARNING, IErrorFeedback.JVMINFERENCE_ERROR_TYPE); } return typeReference; }
@Override public String apply(Variable variable) { return variable.getName(); } });
warning(String.format( "Local variable '%s' is referenced only once. Is it mistyped? Start its name with '_' if intentional.", var.getName()), var.getReferences().get(0), PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VAR, IssueCodes.LOCAL_VARIABLE_REFERENCED_ONCE); } else if (individualCounter.getReferenceCount() > 1 && isNamedSingleUse(var)) { for (VariableReference ref : var.getReferences()) { error(String.format("Named single-use variable %s used multiple times.", var.getName()), ref, PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VAR, IssueCodes.ANONYM_VARIABLE_MULTIPLE_REFERENCE); error(String.format( "Local variable '%s' appears in read-only context(s) only, thus its value cannot be determined.", var.getName()), var, PatternLanguagePackage.Literals.VARIABLE__NAME, IssueCodes.LOCAL_VARIABLE_READONLY); } else if (individualCounter.getReferenceCount(ReferenceType.NEGATIVE) == 1 warning(String.format( "Local variable '%s' will be quantified because it is used only here. Acknowledge this by prefixing its name with '_'.", var.getName()), var.getReferences().get(0), PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VAR, IssueCodes.LOCAL_VARIABLE_QUANTIFIED_REFERENCE); error(String.format( "Local variable '%s' has no positive reference, thus its value cannot be determined.", var.getName()), var.getReferences().get(0), PatternLanguagePackage.Literals.VARIABLE_REFERENCE__VAR, IssueCodes.LOCAL_VARIABLE_NO_POSITIVE_REFERENCE);
private void preprocessParameters(final PatternBody body, PatternModelAcceptor<?> acceptor) { EList<Variable> parameters = pattern.getParameters(); for (Variable variable : parameters) { if (variable.getType() != null && variable.getType() instanceof ClassType) { EClassifier classifier = ((ClassType) variable.getType()).getClassname(); IInputKey inputKey = classifierToInputKey(classifier); acceptor.acceptTypeConstraint(ImmutableList.of(variable.getName()), inputKey); } } acceptor.acceptExportedParameters(parameters); }
@Override public IInputKey getDeclaredType(Variable var) { final Type type = var.getType(); if (type != null) { return typeSystem.extractTypeDescriptor(type); } else { return null; } }
/** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Variable getReferredParam() { if (referredParam != null && referredParam.eIsProxy()) { InternalEObject oldReferredParam = (InternalEObject)referredParam; referredParam = (Variable)eResolveProxy(oldReferredParam); if (referredParam != oldReferredParam) { if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.RESOLVE, PatternLanguagePackage.PARAMETER_REF__REFERRED_PARAM, oldReferredParam, referredParam)); } } return referredParam; }
@Override public JvmTypeReference getVariableType(final Variable variable) { return cache.get(variable, variable.eResource(), new Provider<JvmTypeReference>(){ @Override public JvmTypeReference get() { return doGetVariableType(variable); } }); }
/** * @param varName * @return */ private static Variable initializeLocalVariable(String varName) { Variable decl; decl = PatternLanguageFactory.eINSTANCE.createVariable(); decl.setName(varName); return decl; }
@Override public String apply(final Variable it) { return it.getName(); } };
StringBuilder sb = new StringBuilder(); sb.append("Variable "); sb.append(variable.getName()); sb.append(" has a type "); sb.append(classifierNamesSet.iterator().next()); .getReferences().get(0), null, EMFIssueCodes.VARIABLE_TYPE_MULTIPLE_DECLARATION); } else { EClassifier explicitType = emfTypeProvider.getExplicitClassifierForPatternParameterVariable(variable); warning("Ambiguous variable type defintions: " + classifierNamesSet + ", the parameter type (" + explicitType.getName() + ") is used now.", variable .getReferences().get(0), null, EMFIssueCodes.VARIABLE_TYPE_INVALID_WARNING); } else { boolean isParameter = false; for (Variable parameter : pattern.getParameters()) { if (parameter.getName().equals(variable.getName())) { isParameter = true; + ", type cannot be selected. Please specify the one to be used as the parameter type" + " by adding it to the parameter definition.", variable.getReferences().get(0), null, EMFIssueCodes.VARIABLE_TYPE_INVALID_ERROR); } else { error("Inconsistent variable type defintions: " + classifierNamesSet + ", type cannot be selected.", variable.getReferences().get(0), null, EMFIssueCodes.VARIABLE_TYPE_INVALID_ERROR);
public VariableReferenceCount(Set<Variable> variables, boolean parameter) { this.variables = variables; this.parameter = parameter; for (ReferenceType type : ReferenceType.values()) { counters.put(type, 0); } for (Variable variable : variables) { if (variable instanceof ParameterRef && ((ParameterRef) variable).getReferredParam().getType() != null) { counters.put(ReferenceType.POSITIVE, 1); } } }
/** * <!-- begin-user-doc --> * <!-- end-user-doc --> * @generated */ public Variable getVariable_() { if (variable != null && variable.eIsProxy()) { InternalEObject oldVariable = (InternalEObject)variable; variable = (Variable)eResolveProxy(oldVariable); if (variable != oldVariable) { if (eNotificationRequired()) eNotify(new ENotificationImpl(this, Notification.RESOLVE, PatternLanguagePackage.VARIABLE_REFERENCE__VARIABLE, oldVariable, variable)); } } return variable; }
public String apply(final Variable var) { return var.getName(); } });
@Override public EClassifier getExplicitClassifierForPatternParameterVariable(Variable variable) { if (variable instanceof ParameterRef) { Variable referredParameter = ((ParameterRef) variable).getReferredParam(); return getClassifierForType(referredParameter.getType()); } else { return getClassifierForType(variable.getType()); } }
/** * The parameter's type must be the same or more specific than the type inferred from the pattern's body. This * warning usually arises when we have more pattern bodies, which contains different type definitions for the same * parameter. In a case like this the common parameter's type is the most specific common supertype of the * respective calculated types in the bodies. * * @param pattern */ @Check(/*CheckType.NORMAL*/) public void checkPatternParametersType(Pattern pattern) { for (Variable variable : pattern.getParameters()) { EClassifier classifierCorrect = emfTypeProvider.getClassifierForVariable(variable); EClassifier classifierDefined = emfTypeProvider.getClassifierForType(variable.getType()); if (classifierCorrect == null || classifierDefined == null || classifierDefined.equals(classifierCorrect)) { // Either correct - they are the same, or other validator returns the type error return; } else { if (classifierCorrect instanceof EClass && classifierDefined instanceof EClass) { if (((EClass) classifierDefined).getEAllSuperTypes().contains(classifierCorrect)) { // Correct the defined is more specific than what the pattern needs return; } } // OK, issue warning now warning(String.format( "Inconsistent parameter type definition, should be %s based on the pattern definition", classifierCorrect.getName()), variable, null, EMFIssueCodes.PARAMETER_TYPE_INVALID); } } }
@Override public String apply(Variable var) { return var.getName(); } });