[566230] Check argument types when resolving blackbox operations
diff --git a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
index 6a128d0..ce19784 100644
--- a/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
+++ b/plugins/org.eclipse.m2m.qvt.oml/src/org/eclipse/m2m/internal/qvt/oml/blackbox/java/Java2QVTTypeResolver.java
@@ -8,7 +8,7 @@
*
* Contributors:
* Borland Software Corporation - initial API and implementation
- * Christopher Gerking - bugs 326871, 400233, 427237, 566216
+ * Christopher Gerking - bugs 326871, 400233, 427237, 566216, 566230
*******************************************************************************/
package org.eclipse.m2m.internal.qvt.oml.blackbox.java;
@@ -17,6 +17,7 @@
import java.lang.reflect.TypeVariable;
import java.util.Collection;
import java.util.Comparator;
+import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
@@ -26,9 +27,11 @@
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;
import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EGenericType;
import org.eclipse.emf.ecore.EOperation;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.ETypeParameter;
import org.eclipse.emf.ecore.EcoreFactory;
import org.eclipse.m2m.internal.qvt.oml.NLS;
import org.eclipse.m2m.internal.qvt.oml.ast.env.QvtOperationalModuleEnv;
@@ -162,7 +165,7 @@
return resolveCollectionType(CollectionKind.COLLECTION_LITERAL, actualElementType, relationship);
}
- return lookupByInstanceClass(parameterizedType);
+ return lookupByInstanceClass(parameterizedType, relationship);
}
@@ -280,12 +283,42 @@
return from != null && to != null && to.isAssignableFrom(from);
}
- private EClassifier lookupByInstanceClass(ParameterizedType type) {
+ private EClassifier lookupByInstanceClass(ParameterizedType type, int relationship) {
assert type != null;
Type rawType = type.getRawType();
+ EClassifier rawClassifier = toEClassifier(rawType, relationship);
- return toEClassifier(rawType, Java2QVTTypeResolver.STRICT_TYPE);
+ if (rawClassifier != null) {
+ Iterator<ETypeParameter> typeParameters = rawClassifier.getETypeParameters().iterator();
+
+ for (Type argumentType : type.getActualTypeArguments()) {
+ if (argumentType instanceof Class<?>) {
+ EClassifier argumentClassifier = lookupByInstanceClass((Class<?>) argumentType, relationship);
+
+ if (argumentClassifier != null && typeParameters.hasNext()) {
+ ETypeParameter typeParameter = typeParameters.next();
+ for (EGenericType genericType : typeParameter.getEBounds()) {
+ EClassifier genericClassifier = genericType.getEClassifier();
+ Class<?> genericInstanceClass = genericClassifier.getInstanceClass();
+
+ if ((relationship & ALLOW_SUBTYPE) == ALLOW_SUBTYPE) {
+ if(!isAssignableFromTo((Class<?>) argumentType, genericInstanceClass)) {
+ return null;
+ }
+ }
+ if ((relationship & ALLOW_SUPERTYPE) == ALLOW_SUPERTYPE) {
+ if(!isAssignableFromTo(genericInstanceClass, (Class<?>) argumentType)) {
+ return null;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return rawClassifier;
}
private EClassifier asEClassifier(Class<?> javaClass) {