From ca7ff6d5d499067c7abe5d6536598e70d793d37b Mon Sep 17 00:00:00 2001 From: aclement Date: Mon, 5 Apr 2010 19:37:01 +0000 Subject: [PATCH] refactored generic type handling --- ...5ReflectionBasedReferenceTypeDelegate.java | 46 +++++--- .../weaver/BoundedReferenceTypeTestCase.java | 77 ++++++------- .../TypeVariableReferenceTypeTestCase.java | 64 ++++++++--- .../aspectj/weaver/TypeVariableTestCase.java | 105 ++++++++---------- 4 files changed, 165 insertions(+), 127 deletions(-) diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java index cdf100cff..8ddfbe803 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java @@ -69,11 +69,13 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR this.typeConverter = new JavaLangTypeToResolvedTypeConverter(aWorld); } + @Override public ReferenceType buildGenericType() { return (ReferenceType) UnresolvedType.forGenericTypeVariables(getResolvedTypeX().getSignature(), getTypeVariables()) .resolve(getWorld()); } + @Override public AnnotationAJ[] getAnnotations() { // AMC - we seem not to need to implement this method... // throw new UnsupportedOperationException( @@ -83,6 +85,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR return super.getAnnotations(); } + @Override public ResolvedType[] getAnnotationTypes() { if (annotations == null) { annotations = annotationFinder.getAnnotations(getBaseClass(), getWorld()); @@ -90,17 +93,20 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR return annotations; } + @Override public boolean hasAnnotation(UnresolvedType ofType) { ResolvedType[] myAnns = getAnnotationTypes(); ResolvedType toLookFor = ofType.resolve(getWorld()); for (int i = 0; i < myAnns.length; i++) { - if (myAnns[i] == toLookFor) + if (myAnns[i] == toLookFor) { return true; + } } return false; } // use the MAP to ensure that any aj-synthetic fields are filtered out + @Override public ResolvedMember[] getDeclaredFields() { if (fields == null) { Field[] reflectFields = this.myType.getDeclaredFields(); @@ -113,14 +119,16 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR return fields; } + @Override public String getDeclaredGenericSignature() { if (this.genericSignature == null && isGeneric()) { // BUG? what the hell is this doing - see testcode in MemberTestCase15.testMemberSignatureCreation() and run it - // off a Reflection World + // off a Reflection World } return genericSignature; } + @Override public ResolvedType[] getDeclaredInterfaces() { if (superInterfaces == null) { Type[] genericInterfaces = getBaseClass().getGenericInterfaces(); @@ -130,22 +138,26 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR } // If the superclass is null, return Object - same as bcel does + @Override public ResolvedType getSuperclass() { if (superclass == null && getBaseClass() != Object.class) {// superclass // of Object // is null Type t = this.getBaseClass().getGenericSuperclass(); - if (t != null) + if (t != null) { superclass = typeConverter.fromType(t); - if (t == null) + } + if (t == null) { superclass = getWorld().resolve(UnresolvedType.OBJECT); + } } return superclass; } + @Override public TypeVariable[] getTypeVariables() { - TypeVariable[] workInProgressSetOfVariables = (TypeVariable[]) getResolvedTypeX().getWorld() - .getTypeVariablesCurrentlyBeingProcessed(getBaseClass()); + TypeVariable[] workInProgressSetOfVariables = getResolvedTypeX().getWorld().getTypeVariablesCurrentlyBeingProcessed( + getBaseClass()); if (workInProgressSetOfVariables != null) { return workInProgressSetOfVariables; } @@ -162,12 +174,11 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR for (int i = 0; i < tVars.length; i++) { TypeVariableReferenceType tvrt = ((TypeVariableReferenceType) typeConverter.fromType(tVars[i])); TypeVariable tv = tvrt.getTypeVariable(); - rTypeVariables[i].setUpperBound(tv.getUpperBound()); - rTypeVariables[i].setAdditionalInterfaceBounds(tv.getAdditionalInterfaceBounds()); + rTypeVariables[i].setSuperclass(tv.getSuperclass()); + rTypeVariables[i].setAdditionalInterfaceBounds(tv.getSuperInterfaces()); rTypeVariables[i].setDeclaringElement(tv.getDeclaringElement()); rTypeVariables[i].setDeclaringElementKind(tv.getDeclaringElementKind()); rTypeVariables[i].setRank(tv.getRank()); - rTypeVariables[i].setLowerBound(tv.getLowerBound()); } this.typeVariables = rTypeVariables; this.getResolvedTypeX().getWorld().forgetTypeVariablesCurrentlyBeingProcessed(getBaseClass()); @@ -177,6 +188,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR // overrides super method since by using the MAP we can filter out advice // methods that really shouldn't be seen in this list + @Override public ResolvedMember[] getDeclaredMethods() { if (methods == null) { Method[] reflectMethods = this.myType.getDeclaredMethods(); @@ -198,8 +210,9 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR */ public ResolvedType getGenericResolvedType() { ResolvedType rt = getResolvedTypeX(); - if (rt.isParameterizedType() || rt.isRawType()) + if (rt.isParameterizedType() || rt.isRawType()) { return rt.getGenericType(); + } return rt; } @@ -234,6 +247,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR return ret; } + @Override public ResolvedMember[] getDeclaredPointcuts() { if (pointcuts == null) { Pointcut[] pcs = this.myType.getDeclaredPointcuts(); @@ -306,20 +320,23 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR return null; } + @Override public boolean isAnnotation() { return getBaseClass().isAnnotation(); } + @Override public boolean isAnnotationStyleAspect() { return getBaseClass().isAnnotationPresent(Aspect.class); } + @Override public boolean isAnnotationWithRuntimeRetention() { - if (!isAnnotation()) + if (!isAnnotation()) { return false; + } if (getBaseClass().isAnnotationPresent(Retention.class)) { - Retention retention = (Retention) getBaseClass().getAnnotation( - Retention.class); + Retention retention = (Retention) getBaseClass().getAnnotation(Retention.class); RetentionPolicy policy = retention.value(); return policy == RetentionPolicy.RUNTIME; } else { @@ -327,14 +344,17 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends ReflectionBasedR } } + @Override public boolean isAspect() { return this.myType.isAspect(); } + @Override public boolean isEnum() { return getBaseClass().isEnum(); } + @Override public boolean isGeneric() { // return false; // for now return getBaseClass().getTypeParameters().length > 0; diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/BoundedReferenceTypeTestCase.java b/weaver5/java5-testsrc/org/aspectj/weaver/BoundedReferenceTypeTestCase.java index b46a5a6a6..403b2ecb1 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/BoundedReferenceTypeTestCase.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/BoundedReferenceTypeTestCase.java @@ -11,10 +11,10 @@ * ******************************************************************/ package org.aspectj.weaver; -import org.aspectj.weaver.bcel.BcelWorld; - import junit.framework.TestCase; +import org.aspectj.weaver.bcel.BcelWorld; + public class BoundedReferenceTypeTestCase extends TestCase { ReferenceType javaLangClass; @@ -22,84 +22,85 @@ public class BoundedReferenceTypeTestCase extends TestCase { BoundedReferenceType extendsClass; BoundedReferenceType superClass; BoundedReferenceType extendsWithExtras; - + public void testSignature() { String extendsSig = extendsClass.getSignature(); - assertEquals("+Ljava/lang/Class;",extendsSig); - assertEquals("-Ljava/lang/Class;",superClass.getSignature()); + assertEquals("+Ljava/lang/Class;", extendsSig); + assertEquals("-Ljava/lang/Class;", superClass.getSignature()); } - + public void testExtendsBounds() { - assertFalse("has no lower bound",extendsClass.hasLowerBound()); - assertNull("no lower bound",extendsClass.getLowerBound()); - assertEquals(javaLangClass,extendsClass.getUpperBound()); - assertEquals("no interface bounds",0,extendsClass.getInterfaceBounds().length); + assertFalse("has no lower bound", extendsClass.hasLowerBound()); + assertNull("no lower bound", extendsClass.getLowerBound()); + assertEquals(javaLangClass, extendsClass.getUpperBound()); + assertEquals("no interface bounds", 0, extendsClass.getAdditionalBounds().length); } - + public void testSuperBounds() { - assertTrue("has lower bound",superClass.hasLowerBound()); - assertEquals(javaLangClass,superClass.getLowerBound()); - assertEquals("Ljava/lang/Object;",superClass.getUpperBound().getSignature()); - assertEquals("no interface bounds",0,superClass.getInterfaceBounds().length); + assertTrue("has lower bound", superClass.hasLowerBound()); + assertEquals(javaLangClass, superClass.getLowerBound()); + assertEquals("Ljava/lang/Object;", superClass.getUpperBound().getSignature()); + assertEquals("no interface bounds", 0, superClass.getAdditionalBounds().length); } - + public void testIsExtends() { - assertTrue(extendsClass.isExtends); - assertFalse(superClass.isExtends); + assertTrue(extendsClass.kind == BoundedReferenceType.EXTENDS); + assertFalse(superClass.kind == BoundedReferenceType.EXTENDS); } - + public void testIsSuper() { - assertTrue(superClass.isSuper); - assertFalse(extendsClass.isSuper); + assertTrue(superClass.kind == BoundedReferenceType.SUPER); + assertFalse(extendsClass.kind == BoundedReferenceType.SUPER); } - + public void testGetDeclaredInterfacesNoAdditions() { ResolvedType[] rt1 = extendsClass.getDeclaredInterfaces(); ResolvedType[] rt2 = javaLangClass.getDeclaredInterfaces(); - assertEquals("same length",rt1.length,rt2.length); + assertEquals("same length", rt1.length, rt2.length); for (int i = 0; i < rt2.length; i++) { - assertEquals("same methods",rt1[i],rt2[i]); + assertEquals("same methods", rt1[i], rt2[i]); } } - + public void testGetDeclaredInterfacesWithInterfaceBounds() { ResolvedType[] rt1 = extendsWithExtras.getDeclaredInterfaces(); ResolvedType[] rt2 = javaLangClass.getDeclaredInterfaces(); - assertEquals("one extra interface",rt1.length,rt2.length + 1); + assertEquals("one extra interface", rt1.length, rt2.length + 1); for (int i = 0; i < rt2.length; i++) { - assertEquals("same methods",rt1[i],rt2[i]); + assertEquals("same methods", rt1[i], rt2[i]); } - assertEquals("Ljava/util/List;",rt1[rt1.length-1].getSignature()); + assertEquals("Ljava/util/List;", rt1[rt1.length - 1].getSignature()); } - - // all other methods in signature are delegated to upper bound... + + // all other methods in signature are delegated to upper bound... // representative test public void testGetDeclaredMethodsExtends() { ResolvedMember[] rm1 = extendsClass.getDeclaredMethods(); ResolvedMember[] rm2 = javaLangClass.getDeclaredMethods(); - assertEquals("same length",rm1.length,rm2.length); + assertEquals("same length", rm1.length, rm2.length); for (int i = 0; i < rm2.length; i++) { - assertEquals("same methods",rm1[i],rm2[i]); + assertEquals("same methods", rm1[i], rm2[i]); } } public void testGetDeclaredMethodsSuper() { ResolvedMember[] rm1 = superClass.getDeclaredMethods(); ResolvedMember[] rm2 = javaLangObject.getDeclaredMethods(); - assertEquals("same length",rm1.length,rm2.length); + assertEquals("same length", rm1.length, rm2.length); for (int i = 0; i < rm2.length; i++) { - assertEquals("same methods",rm1[i],rm2[i]); + assertEquals("same methods", rm1[i], rm2[i]); } } + @Override protected void setUp() throws Exception { super.setUp(); BcelWorld world = new BcelWorld(); javaLangClass = (ReferenceType) world.resolve(UnresolvedType.forName("java/lang/Class")); javaLangObject = (ReferenceType) world.resolve(UnresolvedType.OBJECT); - extendsClass = new BoundedReferenceType(javaLangClass,true,world); - superClass = new BoundedReferenceType(javaLangClass,false,world); - extendsWithExtras = new BoundedReferenceType(javaLangClass,true,world, - new ReferenceType[] {(ReferenceType)world.resolve(UnresolvedType.forName("java/util/List"))}); + extendsClass = new BoundedReferenceType(javaLangClass, true, world); + superClass = new BoundedReferenceType(javaLangClass, false, world); + extendsWithExtras = new BoundedReferenceType(javaLangClass, true, world, new ReferenceType[] { (ReferenceType) world + .resolve(UnresolvedType.forName("java/util/List")) }); } } diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java b/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java index 15edbae4b..367a4fc93 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableReferenceTypeTestCase.java @@ -11,39 +11,71 @@ * ******************************************************************/ package org.aspectj.weaver; -import org.aspectj.weaver.bcel.BcelWorld; - import junit.framework.TestCase; +import org.aspectj.weaver.bcel.BcelWorld; + /** * @author colyer - * + * */ public class TypeVariableReferenceTypeTestCase extends TestCase { ReferenceType javaLangClass; + ReferenceType jlNumber; ReferenceType javaLangObject; BoundedReferenceType extendsClass; BoundedReferenceType superClass; BoundedReferenceType extendsWithExtras; BcelWorld world; - - public void testConstructionByNameAndVariable() { - TypeVariable tv = new TypeVariable("T",javaLangClass); - TypeVariableReferenceType tvrt = new TypeVariableReferenceType(tv,world); - assertEquals("T",tvrt.getTypeVariable().getName()); - assertEquals(javaLangClass,tvrt.getUpperBound()); - } - + + @Override protected void setUp() throws Exception { super.setUp(); - world = new BcelWorld(); + world = new BcelWorld("../bin"); + world.setBehaveInJava5Way(true); javaLangClass = (ReferenceType) world.resolve(UnresolvedType.forName("java/lang/Class")); + jlNumber = (ReferenceType) world.resolve(UnresolvedType.forSignature("Ljava/lang/Number;")); javaLangObject = (ReferenceType) world.resolve(UnresolvedType.OBJECT); - extendsClass = new BoundedReferenceType(javaLangClass,true,world); - superClass = new BoundedReferenceType(javaLangClass,false,world); - extendsWithExtras = new BoundedReferenceType(javaLangClass,true,world, - new ReferenceType[] {(ReferenceType)world.resolve(UnresolvedType.forName("java/util/List"))}); + extendsClass = new BoundedReferenceType(javaLangClass, true, world); + superClass = new BoundedReferenceType(javaLangClass, false, world); + extendsWithExtras = new BoundedReferenceType(javaLangClass, true, world, new ReferenceType[] { (ReferenceType) world + .resolve(UnresolvedType.forName("java/util/List")) }); + } + + public void testConstructionByNameAndVariable() { + TypeVariable tv = new TypeVariable("T", javaLangClass); + TypeVariableReferenceType tvrt = new TypeVariableReferenceType(tv, world); + assertEquals("T", tvrt.getTypeVariable().getName()); + assertEquals(javaLangClass, tvrt.getTypeVariable().getUpperBound()); + } + + public void testBounds() { + // Load up the testclass from below + ResolvedType testerClass = world.resolve(Tester1.class.getName()); + ResolvedType genericTesterClass = testerClass.getGenericType(); + + // Check the declaration type variable + TypeVariable[] typevars = genericTesterClass.getTypeVariables(); + TypeVariable typevar = typevars[0]; + assertEquals(jlNumber, typevar.getUpperBound()); + assertEquals("T", typevar.getName()); + ResolvedMember member = genericTesterClass.getDeclaredMethods()[1]; + + // getParameterTypes() returning the erased parameter + UnresolvedType param = member.getParameterTypes()[0]; + assertEquals(jlNumber, param); + + // Check the type variable reference + TypeVariableReferenceType tvReference = (TypeVariableReferenceType) member.getGenericParameterTypes()[0]; + assertEquals("T", tvReference.getTypeVariableName()); + assertEquals(jlNumber, tvReference.getUpperBound()); + assertEquals(jlNumber, tvReference.getDelegate().getResolvedTypeX()); + } + + class Tester1 { + public void method(T t) { + } } } diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableTestCase.java b/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableTestCase.java index ec2547acd..8ef8f70c1 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableTestCase.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/TypeVariableTestCase.java @@ -11,104 +11,88 @@ * ******************************************************************/ package org.aspectj.weaver; -import org.aspectj.weaver.bcel.BcelWorld; - import junit.framework.TestCase; +import org.aspectj.weaver.bcel.BcelWorld; + public class TypeVariableTestCase extends TestCase { - + private UnresolvedType javaLangNumber; private UnresolvedType javaLangDouble; private UnresolvedType javaUtilList; private UnresolvedType javaIoSerializable; private World world; - - public void testDefaultBounds() { + + public void testName() { TypeVariable tv = new TypeVariable("T"); - assertEquals("Object",UnresolvedType.OBJECT,tv.getUpperBound()); - assertEquals("no additional bounds",0,tv.getAdditionalInterfaceBounds().length); - assertNull("no lower bound",tv.getLowerBound()); + assertEquals("T", tv.getName()); } - - public void testName() { + + public void testDefaultBounds() { TypeVariable tv = new TypeVariable("T"); - assertEquals("T",tv.getName()); + assertEquals("Object", UnresolvedType.OBJECT, tv.getFirstBound()); + assertNull(tv.getUpperBound()); + assertEquals("no additional bounds", 0, tv.getSuperInterfaces().length); } - + public void testUpperBound() { - TypeVariable tv = new TypeVariable("N",javaLangNumber); - assertEquals("java.lang.Number",javaLangNumber,tv.getUpperBound()); + TypeVariable tv = new TypeVariable("N", javaLangNumber); + assertEquals("java.lang.Number", javaLangNumber, tv.getUpperBound()); } - + public void testAdditionalUpperBounds() { - TypeVariable tv = new TypeVariable("E",UnresolvedType.OBJECT,new UnresolvedType[] {javaUtilList}); - assertEquals("1 additional bound",1,tv.getAdditionalInterfaceBounds().length); - assertEquals("java.util.List",javaUtilList,tv.getAdditionalInterfaceBounds()[0]); - } - - public void testLowerBound() { - TypeVariable tv = new TypeVariable("X",UnresolvedType.OBJECT,new UnresolvedType[0],javaLangDouble); - assertEquals("java.lang.Double",javaLangDouble,tv.getLowerBound()); + TypeVariable tv = new TypeVariable("E", UnresolvedType.OBJECT, new UnresolvedType[] { javaUtilList }); + assertEquals("1 additional bound", 1, tv.getSuperInterfaces().length); + assertEquals("java.util.List", javaUtilList, tv.getSuperInterfaces()[0]); + + tv = new TypeVariable("E", null, new UnresolvedType[] { javaUtilList }); + assertEquals("1 additional bound", 1, tv.getSuperInterfaces().length); + assertEquals("java.util.List", javaUtilList, tv.getSuperInterfaces()[0]); } - + public void testResolution() { - TypeVariable tv = new TypeVariable( - "T", - javaLangNumber, - new UnresolvedType[] {javaUtilList}, - javaLangDouble - ); + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaUtilList }); tv.resolve(world); - assertEquals("resolved number",javaLangNumber.resolve(world),tv.getUpperBound()); - assertEquals("resolved list",javaUtilList.resolve(world), - tv.getAdditionalInterfaceBounds()[0]); - assertEquals("resolved double",javaLangDouble.resolve(world),tv.getLowerBound()); + assertEquals("resolved number", javaLangNumber.resolve(world), tv.getUpperBound()); + assertEquals("resolved list", javaUtilList.resolve(world), tv.getSuperInterfaces()[0]); } - + public void testBindWithoutResolve() { TypeVariable tv = new TypeVariable("X"); try { tv.canBeBoundTo(null); - fail ("Should throw illegal state exception"); - } catch (IllegalStateException ex) {} + fail("Should throw illegal state exception"); + } catch (IllegalStateException ex) { + } } - + public void testCanBindToUpperMatch() { - TypeVariable tv = new TypeVariable("X",javaLangNumber); + TypeVariable tv = new TypeVariable("X", javaLangNumber); tv.resolve(world); assertTrue(tv.canBeBoundTo(javaLangDouble.resolve(world))); } - + public void testCanBindToUpperFail() { - TypeVariable tv = new TypeVariable("X",javaLangNumber); + TypeVariable tv = new TypeVariable("X", javaLangNumber); tv.resolve(world); - assertFalse(tv.canBeBoundTo(UnresolvedType.OBJECT.resolve(world))); + assertFalse(tv.canBeBoundTo(UnresolvedType.OBJECT.resolve(world))); } - + public void testCanBindToInterfaceMatch() { - TypeVariable tv = new TypeVariable("T",javaLangNumber,new UnresolvedType[] {javaIoSerializable}); + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaIoSerializable }); tv.resolve(world); assertTrue(tv.canBeBoundTo(javaLangDouble.resolve(world))); } - + public void testCanBindToInterfaceFail() { - TypeVariable tv = new TypeVariable("T",javaLangNumber,new UnresolvedType[] {javaUtilList}); + TypeVariable tv = new TypeVariable("T", javaLangNumber, new UnresolvedType[] { javaUtilList }); tv.resolve(world); - assertFalse(tv.canBeBoundTo(javaLangDouble.resolve(world))); + assertFalse(tv.canBeBoundTo(javaLangDouble.resolve(world))); } - - public void testCanBindToLowerMatch() { - TypeVariable tv = new TypeVariable("T",javaLangNumber,new UnresolvedType[0],javaLangDouble); - tv.resolve(world); - assertTrue(tv.canBeBoundTo(javaLangNumber.resolve(world))); - } - - public void testCanBindToLowerFail() { - TypeVariable tv = new TypeVariable("T",javaLangNumber,new UnresolvedType[0],javaLangNumber); - tv.resolve(world); - assertFalse(tv.canBeBoundTo(javaLangDouble.resolve(world))); - } - + + // --- + + @Override protected void setUp() throws Exception { super.setUp(); javaLangNumber = UnresolvedType.forSignature("Ljava/lang/Number;"); @@ -118,6 +102,7 @@ public class TypeVariableTestCase extends TestCase { world = new BcelWorld(); } + @Override protected void tearDown() throws Exception { super.tearDown(); } -- 2.39.5