diff options
author | sboyko | 2016-02-05 08:39:33 +0000 |
---|---|---|
committer | sboyko | 2016-02-05 08:39:33 +0000 |
commit | bdeadf6d01add75b6e8a5751ef51418f8acaae55 (patch) | |
tree | 8adbcb0a8041795607ab4c9a1f03f6b0133b394f | |
parent | 688d9e40990ae14ffa0cde268a4ee7cc8018cf50 (diff) | |
download | org.eclipse.qvto-bdeadf6d01add75b6e8a5751ef51418f8acaae55.tar.gz org.eclipse.qvto-bdeadf6d01add75b6e8a5751ef51418f8acaae55.tar.xz org.eclipse.qvto-bdeadf6d01add75b6e8a5751ef51418f8acaae55.zip |
[487299] Diagnose ambiguity of operations calls that are invoked using
implicit source
4 files changed, 49 insertions, 15 deletions
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java index cca72f1ac..549f54c7a 100644 --- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java +++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/env/QvtEnvironmentBase.java @@ -37,6 +37,7 @@ import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtEnvironmentBase.CollisionStatus.CollisionKind; import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalParserUtil; import org.eclipse.m2m.internal.qvt.oml.ast.parser.QvtOperationalUtil; +import org.eclipse.m2m.internal.qvt.oml.ast.parser.ValidationMessages; import org.eclipse.m2m.internal.qvt.oml.compiler.BlackboxUnitResolver; import org.eclipse.m2m.internal.qvt.oml.expressions.ImperativeOperation; import org.eclipse.m2m.internal.qvt.oml.expressions.ImportKind; @@ -45,6 +46,7 @@ import org.eclipse.m2m.internal.qvt.oml.expressions.Module; import org.eclipse.m2m.internal.qvt.oml.expressions.ModuleImport; import org.eclipse.m2m.internal.qvt.oml.expressions.VarParameter; import org.eclipse.m2m.internal.qvt.oml.stdlib.QVTUMLReflection; +import org.eclipse.ocl.AmbiguousLookupException; import org.eclipse.ocl.LookupException; import org.eclipse.ocl.ecore.CallOperationAction; import org.eclipse.ocl.ecore.Constraint; @@ -180,10 +182,8 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT try { return tryLookupImplicitSourceForOperation(name, args); } catch(LookupException e) { - List<?> ambiguousMatches = e.getAmbiguousMatches(); - @SuppressWarnings("unchecked") - Variable<EClassifier, EParameter> result = ambiguousMatches.isEmpty() ? null : (Variable<EClassifier, EParameter>)ambiguousMatches.get(0); - return result; + // report resolution ambiguity + throw new RuntimeException(e); } } @@ -197,10 +197,11 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT return this.getInternalParent().lookupImplicitSourceForOperation(name, args); } + List<Variable<EClassifier, EParameter>> ambiguous = new LinkedList<Variable<EClassifier,EParameter>>(); for (QvtEnvironmentBase nextExtendedEnv : rootEnv.getAllExtendedModules()) { result = nextExtendedEnv.localLookupImplicitSourceForOperation(name, args); if(result != null) { - return result; + ambiguous.add(result); } } @@ -211,10 +212,15 @@ public abstract class QvtEnvironmentBase extends EcoreEnvironment implements QVT // this cannot be done transformations which has an explicit instance result = nextAccessedEnv.localLookupImplicitSourceForOperation(name, args); if(result != null) { - break; + ambiguous.add(result); } } - } + } + + if (ambiguous.size() > 1) { + throw new AmbiguousLookupException(ValidationMessages.AmbiguousImplicitSourceLookup, ambiguous); + } + result = ambiguous.isEmpty() ? null : ambiguous.get(0); } return result; diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java index fddee9e57..2cb1699a7 100644 --- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java +++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/QvtOperationalVisitorCS.java @@ -190,6 +190,7 @@ import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.SwitchExp; import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.TryExp; import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.VariableInitExp; import org.eclipse.m2m.qvt.oml.ecore.ImperativeOCL.WhileExp; +import org.eclipse.ocl.AmbiguousLookupException; import org.eclipse.ocl.Environment; import org.eclipse.ocl.Environment.Internal; import org.eclipse.ocl.LookupException; @@ -577,6 +578,14 @@ public class QvtOperationalVisitorCS return filteredMatches.get(0); } + String message = NLS.bind(ValidationMessages.AmbiguousOperationReference, formatMatches(env, filteredMatches)); + getEnvironment().analyzerWarning(message, "lookupOperation", problemNode); //$NON-NLS-1$" + return filteredMatches.get(0); + } + + private String formatMatches( + Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env, + List<?> filteredMatches) { StringBuffer buf = new StringBuffer(); try { int i = 0; @@ -596,10 +605,7 @@ public class QvtOperationalVisitorCS // Remark : safety measure, added in 2.0 RC1 buf.append("<null>"); //$NON-NLS-1$ } - - String message = NLS.bind(ValidationMessages.AmbiguousOperationReference, buf.toString()); - getEnvironment().analyzerWarning(message, "lookupOperation", problemNode); //$NON-NLS-1$" - return filteredMatches.get(0); + return buf.toString(); } @SuppressWarnings("unchecked") @@ -611,20 +617,38 @@ public class QvtOperationalVisitorCS return eType == env.getOCLStandardLibrary().getT2(); } + @SuppressWarnings("unchecked") @Override protected Variable<EClassifier, EParameter> lookupImplicitSourceForOperation( CSTNode cstNode, Environment<EPackage, EClassifier, EOperation, EStructuralFeature, EEnumLiteral, EParameter, EObject, CallOperationAction, SendSignalAction, Constraint, EClass, EObject> env, List<OCLExpression<EClassifier>> args, String operationName) { - Variable<EClassifier, EParameter> source = super.lookupImplicitSourceForOperation(cstNode, env, args, operationName); - if(source == null) { + Variable<EClassifier, EParameter> source = null; + try { + source = super.lookupImplicitSourceForOperation(cstNode, env, args, operationName); + } + catch (RuntimeException e) { + if (e.getCause() instanceof AmbiguousLookupException) { + List<?> ambiguousMatches = ((AmbiguousLookupException) e.getCause()).getAmbiguousMatches(); + + String message = NLS.bind(ValidationMessages.AmbiguousImplicitSourceReference, formatMatches(env, ambiguousMatches)); + ((QvtEnvironmentBase) env).analyzerWarning(message, "lookupImplicitSource", ((OperationCallExpCS) cstNode).getSimpleNameCS()); //$NON-NLS-1$" + + source = ambiguousMatches.isEmpty() ? null : (Variable<EClassifier, EParameter>) ambiguousMatches.get(0); + } + else { + throw e; + } + } + + if(source == null) { // FIXME - why is this done?, looks like a workaround for MDT OCL, // it's a legal contract for the lookupXXX operation to return null source = EcoreFactory.eINSTANCE.createVariable(); initASTMapping(env, source, cstNode); - } - return source; + } + return source; } private EClassifier visitTypeCSInModelType(TypeSpecCS typeSpecCS, ModelType modelType, diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java index af0ecd9f8..6aff9c9d8 100644 --- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java +++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.java @@ -26,7 +26,9 @@ public final class ValidationMessages extends NLS { public static String AmbiguousModuleReference; public static String AmbiguousOperationLookup; + public static String AmbiguousImplicitSourceLookup; public static String AmbiguousOperationReference; + public static String AmbiguousImplicitSourceReference; public static String BooleanTypeAssertConditionError; public static String DefaultConstructorNotDefinedImplicitUsed; public static String DeprecatedElement; diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties index fa074f8fe..ba7d8e08e 100644 --- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties +++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/ast/parser/ValidationMessages.properties @@ -14,7 +14,9 @@ ############################################################################### AmbiguousModuleReference=Ambiguous module reference ''{0}'' AmbiguousOperationLookup=Ambiguous operation lookup +AmbiguousImplicitSourceLookup=Ambiguous implicit source lookup AmbiguousOperationReference=Operation reference is ambiguous. Choosing first of {0} +AmbiguousImplicitSourceReference=Implicit source for operation is ambiguous. Choosing first of {0} nonModelTypeError=''{0}'' is an invalid type for created object. Must use a model element type #abstractTypeError=The class ''{0}'' is abstract. Must use a concrete class ReturnSubtypeMismatch=Return type of virtual operation ''{0}'' must be a subtype of ''{1}'' |