diff options
author | acolyer <acolyer> | 2005-07-20 12:35:59 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2005-07-20 12:35:59 +0000 |
commit | 1bff115da676c633a85085d9da8e468b53f4049a (patch) | |
tree | 2255a753c29f65c96cff3a6e94c6c4d901a1c923 | |
parent | aaa349d1543fbad515ff4fce869799fac591118d (diff) | |
download | aspectj-1bff115da676c633a85085d9da8e468b53f4049a.tar.gz aspectj-1bff115da676c633a85085d9da8e468b53f4049a.zip |
ensure that when parameterizing a member, we handle any types that are themselves parameterized (eg. a return type List<N> should turn to List<String> when parameterized with String).
5 files changed, 60 insertions, 4 deletions
diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index c34ef714c..94b0583bf 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -374,9 +374,10 @@ public class ResolvedMember extends Member implements IHasPosition, AnnotatedEle return aType; // if the type variable comes from the method (and not the type) thats OK } return (UnresolvedType) typeVariableMap.get(variableName); - } else { - return aType; - } + } else if (aType.isParameterizedType()) { + return aType.parameterize(typeVariableMap); + } + return aType; } diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 60600da5c..045377922 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -21,6 +21,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.aspectj.bridge.IMessage; @@ -1408,6 +1409,35 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return this; } + /** + * Iff I am a parameterized type, and any of my parameters are type variable + * references, return a version with those type parameters replaced in accordance + * with the passed bindings. + */ + public UnresolvedType parameterize(Map typeBindings) { + if (!isParameterizedType()) throw new IllegalStateException("Can't parameterize a type that is not a parameterized type"); + boolean workToDo = false; + for (int i = 0; i < typeParameters.length; i++) { + if (typeParameters[i].isTypeVariable()) { + workToDo = true; + } + } + if (!workToDo) { + return this; + } else { + UnresolvedType[] newTypeParams = new UnresolvedType[typeParameters.length]; + for (int i = 0; i < newTypeParams.length; i++) { + newTypeParams[i] = typeParameters[i]; + if (newTypeParams[i].isTypeVariable()) { + TypeVariableReferenceType tvrt = (TypeVariableReferenceType) newTypeParams[i]; + UnresolvedType binding = (UnresolvedType) typeBindings.get(tvrt.getTypeVariable().getName()); + if (binding != null) newTypeParams[i] = binding; + } + } + return TypeFactory.createParameterizedType(getGenericType(), newTypeParams, getWorld()); + } + } + public boolean hasParameterizedSuperType() { getParameterizedSuperTypes(); return parameterizedSuperTypes.length > 0; diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 06fcf1874..6accec459 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -20,6 +20,7 @@ import java.io.IOException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.aspectj.apache.bcel.classfile.GenericSignatureParser; import org.aspectj.apache.bcel.classfile.Signature; @@ -215,6 +216,15 @@ public class UnresolvedType { } /** + * Return a version of this parameterized type in which any type parameters + * that are type variable references are replaced by their matching type variable + * binding. + */ + public UnresolvedType parameterize(Map typeBindings) { + throw new UnsupportedOperationException("resolve this type first"); + } + + /** * protected constructor for use only within UnresolvedType hierarchy. Use * one of the UnresolvedType.forXXX static methods for normal creation of * TypeXs. diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 602e16b64..901e05711 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -114,6 +114,7 @@ public abstract class World implements Dump.INode { // if we already have an rtx, don't re-resolve it public ResolvedType resolve(ResolvedType ty) { + if (ty.isTypeVariable()) return ty; // until type variables have proper sigs... ResolvedType resolved = typeMap.get(ty.getSignature()); if (resolved == null) { typeMap.put(ty.getSignature(), ty); diff --git a/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java b/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java index 71a640caa..77379318d 100644 --- a/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/ParameterizedReferenceTypeTestCase.java @@ -58,10 +58,24 @@ public class ParameterizedReferenceTypeTestCase extends TestCase { } + public void testDeclaredMethodWithParameterizedReturnType() { + ResolvedMember[] methods = listOfString.getDeclaredMethods(); + ResolvedMember iterator = null; + for (int i = 0; i < methods.length; i++) { + if (methods[i].getName().equals("iterator")) { + iterator = methods[i]; + break; + } + } + UnresolvedType returnType = iterator.getReturnType(); + assertEquals("Pjava/util/Iterator<Ljava/lang/String;>;",returnType.getSignature()); + + } + protected void setUp() throws Exception { super.setUp(); world = new BcelWorld(); listOfString = (ReferenceType) - TypeFactory.createTypeFromSignature("Ljava/util/List<Ljava/lang/String;>;").resolve(world); + TypeFactory.createTypeFromSignature("Pjava/util/List<Ljava/lang/String;>;").resolve(world); } } |