package org.aspectj.systemtest.ajc150; import java.io.File; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import junit.framework.Test; import org.aspectj.apache.bcel.classfile.Attribute; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Signature; import org.aspectj.apache.bcel.util.ClassPath; import org.aspectj.apache.bcel.util.SyntheticRepository; import org.aspectj.testing.XMLBasedAjcTestCase; import org.aspectj.tools.ajc.Ajc; import org.aspectj.util.LangUtil; public class GenericsTests extends XMLBasedAjcTestCase { /*========================================== * Generics test plan for pointcuts. * * handler PASS * - does not permit type var spec * - does not permit generic type (fail with type not found) * - does not permit parameterized types * if PASS * - does not permit type vars * cflow PASS * - does not permit type vars * cflowbelow PASS * - does not permit type vars * @this PASS * - does not permit type vars PASS * - does not permit parameterized type PASS * @target PASS * - does not permit type vars PASS * - does not permit parameterized type PASS * @args PASS * - does not permit type vars PASS * - does not permit parameterized type PASS * @annotation PASS * - does not permit type vars PASS * - does not permit parameterized type PASS * @within, @within code - as above PASS * annotation type pattern with generic and parameterized types PASS * - just make sure that annotation interfaces can never be generic first! VERIFIED * - @Foo should fail PASS * - @Foo should fail PASS * - @(Foo || Bar) should fail DEFERRED (not critical) * staticinitialization PASS * - error on parameterized type PASS N/A * - permit parameterized type + PASS N/A * - matching with parameterized type + N/A * - wrong number of parameters in parameterized type PASS N/A * - generic type with one type parameter N/A * - generic type with n type parameters N/A * - generic type with bounds [extends, extends + i/f's] N/A * - generic type with wrong number of type params N/A * - wildcards in bounds N/A * within PASS * - as above, but allows parameterized type (disallowed in simplified plan) * - wildcards in type parameters N/A * this PASS * - no type vars * - parameterized types - disallowed in simplification plan * - implements * - instanceof * target PASS * - as this * args * - args(List) matches List, List, List PASS * - args(List) -> invalid absolute type T * - args(List) matches List but not List PASS * - args(List) matches List with unchecked warning PASS * - args(List) matches List with unchecked warning PASS * - args(List) matches List, List, List with unchecked warning PASS * matches List PASS, List PASS(with warning) * - args(List) matches List, List, List, ... PASS * - args(List, List, not List PASS * matches List, List with unchecked warning PASS * - args(List) matches List, List * does not match List * matches List, List with unchecked warning * matches List * matches List with unchecked warning * matches List with unchecked warning * get & set PASS * - parameterized declaring type PASS * - generic declaring type PASS * - field type is type variable PASS * - field type is parameterized PASS * initialization, preinitialization PASS * - generic declaring type PASS * - type variables as params PASS * - parameterized types as params PASS * - no join points for init, preinit of parameterized types (as per staticinit) PASS * withincode PASS * - no generic or parameterized declaring type patterns PASS * - no parameterized throws patterns PASS * - return type as type variable PASS * - return type as parameterized type PASS * - parameter as type variable PASS * - parameter as parameterized type PASS * - no join points within bridge methods PASS * execution PASS * - no generic or parameterized declaring type patterns PASS * - no parameterized throws patterns PASS * - return type as type variable PASS * - return type as parameterized type PASS * - parameter as type variable PASS * - parameter as parameterized type PASS * - no join points for bridge methods PASS * call PASS * - no generic or parameterized declaring type patterns PASS * - no parameterized throws patterns PASS * - return type as type variable PASS * - return type as parameterized type PASS * - parameter as type variable PASS * - parameter as parameterized type PASS * - calls to a bridge methods PASS * after throwing - can't use parameterized type pattern * after returning - same as for args */ /* ========================================== * Generics test plan for ITDs. * * think about: * - 'visibility' default/private/public * - static/nonstatic * - parameterized ITDs (methods/ctors/fields) * - ITD target: interface/class/aspect * - multiple type variables * - constructor ITDs, method ITDs * - ITDs sharing type variables with generic types * - relating to above point, this makes generic ITD fields possible * - signature attributes for generic ITDs (required? required only for public ITDs?) * - binary weaving when target type changes over time (might start out 'simple' then sometime later be 'generic') * - bridge methods - when to create them * - multiple 'separate' ITDs in a file that share a type variable by 'name' * - wildcards '?' 'extends' 'super' '&' * - do type variables assigned to members need to persist across serialization * - recursive type variable definitions eg. > * - super/extends with parameterized types > * - multiple ITDs defined in one type that reuse type variable letters, specifying different bounds * - generic aspects * * PASS parsing generic ITDs * PASS generic methods * PASS generic constructors * PASS ITD visibility * PASS static/nonstatic * PASS parameterizedITDs * PASS differing targets (interface/class/aspect) * PASS multiple type variables in an ITD * PASS parsing ITDs that share type variables with target type * PASS using type variables from the target type in your field ITD * PASS using type variables from the target type in your method ITD (but no type vars of your own) * PASS using type variables from the target type in your ctor ITD (but no type vars of your own) * PASS using type variables from the target type and having your own too (methods) * PASS using type variables from the target type and having your own too (ctors) * PASS reusing type variable letter but differing spec across multiple ITDs in one aspect * PASS wildcards * PASS recursive type variable definitions * PASS generic aspects * PASS parameterizing ITDs with type variables * PASS using type variables from the target type in your *STATIC* ITD (field/method/ctor) (error scenario) * PASS basic binary weaving of generic itds * * TODO generic aspect binary weaving (or at least multi source file weaving) * TODO binary weaving with changing types (moving between generic and simple) * TODO bridge method creation (also relates to covariance overrides..) * TODO exotic class/interface bounds ('? extends List','? super anything') * TODO signature attributes for generic ITDs (public only?) * */ public static Test suite() { return XMLBasedAjcTestCase.loadSuite(GenericsTests.class); } protected File getSpecFile() { return new File("../tests/src/org/aspectj/systemtest/ajc150/ajc150.xml"); } public void testITDReturningParameterizedType() { runTest("ITD with parameterized type"); } public void testPR91267_1() { runTest("NPE using generic methods in aspects 1"); } public void testParameterizedTypeAndAroundAdvice_PR115250() { runTest("parameterized type and around advice"); } public void testParameterizedTypeAndAroundAdvice_PR115250_2() { runTest("parameterized type and around advice - 2"); } public void testPR91267_2() { runTest("NPE using generic methods in aspects 2"); } public void testPR91053() { runTest("Generics problem with Set"); } public void testPR87282() { runTest("Compilation error on generic member introduction"); } public void testGenericsOverrides_1() { runTest("generics and ITD overrides - 1"); } public void testGenericsOverrides_2() { runTest("generics and ITD overrides - 2"); } public void testGenericsOverrides_3() { runTest("generics and ITD overrides - 3"); } public void testGenericsOverrides_4() { runTest("generics and ITD overrides - 4"); } public void testSelfBoundGenerics_pr117296() { runTest("self bounding generic types"); } public void testPR88606() { runTest("Parameterized types on introduced fields not correctly recognized"); } public void testPR97763() { runTest("ITD method with generic arg"); } public void testGenericsBang_pr95993() { runTest("NPE at ClassScope.java:660 when compiling generic class"); } // generic aspects public void testPR96220_GenericAspects1() {runTest("generic aspects - 1");} public void testPR96220_GenericAspects2() {runTest("generic aspects - 2");} public void testPR96220_GenericAspects3() {runTest("generic aspects - 3");} public void testGenericAspects4() {runTest("generic aspects - 4");} public void testGenericAspects5() {runTest("generic aspects - 5 (ajdk)");} // in separate files public void testGenericAspects6() {runTest("generic aspects - 6 (ajdk)");} // all in one file public void testTypeVariablesInDeclareWarning() { runTest("generic aspect with declare warning using type vars");} public void testTypeVariablesInExecutionAdvice() { runTest("generic aspect with execution advice using type vars");} public void testTypeVariablesInAnonymousPointcut() { runTest("generic aspect with anonymous pointcut");} public void testDeclareParentWithParameterizedInterface() { runTest("generic aspect declare parents"); } public void testDeclareSoftInGenericAspect() { runTest("generic aspect declare soft"); } ////////////////////////////////////////////////////////////////////////////// // Generic/Parameterized ITDs - includes scenarios from developers notebook // ////////////////////////////////////////////////////////////////////////////// // parsing of generic ITD members public void testParseItdNonStaticMethod() {runTest("Parsing generic ITDs - 1");} public void testParseItdStaticMethod() {runTest("Parsing generic ITDs - 2");} public void testParseItdCtor() {runTest("Parsing generic ITDs - 3");} public void testParseItdComplexMethod() {runTest("Parsing generic ITDs - 4");} public void testParseItdSharingVars1() {runTest("Parsing generic ITDs - 5");} public void testParseItdSharingVars2() {runTest("Parsing generic ITDs - 6");} // non static public void testGenericMethodITD1() {runTest("generic method itd - 1");} // ... (List) public void testGenericMethodITD2() {runTest("generic method itd - 2");} // ... (List) called incorrectly public void testGenericMethodITD3() {runTest("generic method itd - 3");} // ... (List,List) public void testGenericMethodITD4() {runTest("generic method itd - 4");} // ... (List,List) public void testGenericMethodITD5() {runTest("generic method itd - 5");} // ... (List,List) called incorrectly public void testGenericMethodITD6() {runTest("generic method itd - 6");} // ... (List) public void testGenericMethodITD7() {runTest("generic method itd - 7"); } // ... (List,List) public void testGenericMethodITD8() {runTest("generic method itd - 8"); } // ... (List,List) called incorrectly public void testGenericMethodITD9() {runTest("generic method itd - 9"); } // > ... (List) public void testGenericMethodITD10() {runTest("generic method itd - 10");} // > ... (List) called incorrectly public void testGenericMethodITD11() {runTest("generic method itd - 11");} // > ... (List) public void testGenericMethodITD12() {runTest("generic method itd - 12");} // > ... (List) called incorrectly public void testGenericMethodITD13() {runTest("generic method itd - 13");} // > ... (List) called correctly in a clever way ;) public void testGenericMethodITD14() {runTest("generic method itd - 14");} // > ... (List) called incorrectly in a clever way public void testGenericMethodITD15() {runTest("generic method itd - 15");} // > ... (List) called correctly in a clever way // generic ctors public void testGenericCtorITD1() {runTest("generic ctor itd - 1");} // new(List) public void testGenericCtorITD2() {runTest("generic ctor itd - 2");} // new(List,List) public void testGenericCtorITD3() {runTest("generic ctor itd - 3");} // new(List,Comparator) // parameterized ITDs public void testParameterizedMethodITD1() {runTest("parameterized method itd - 1");} // (List) public void testParameterizedMethodITD2() {runTest("parameterized method itd - 2");} // (List) called incorrectly public void testParameterizedMethodITD3() {runTest("parameterized method itd - 3");} // (List) called incorrectly public void testParameterizedMethodITD4() {runTest("parameterized method itd - 4");} // (List) // differing visibilities public void testPublicITDs() {runTest("public itds");} public void testPublicITDsErrors() {runTest("public itds with errors");} public void testPrivateITDs() {runTest("private itds");} public void testPackageITDs() {runTest("package itds");} // targetting different types (interface/class/aspect) public void testTargettingInterface() {runTest("targetting interface");} public void testTargettingAspect() {runTest("targetting aspect");} public void testTargettingClass() {runTest("targetting class");} // using a type variable from the target generic type in your ITD public void testFieldITDsUsingTargetTypeVars1() {runTest("field itd using type variable from target type - 1");} public void testFieldITDsUsingTargetTypeVars2() {runTest("field itd using type variable from target type - 2");} public void testFieldITDsUsingTargetTypeVars3() {runTest("field itd using type variable from target type - 3");} public void testFieldITDsUsingTargetTypeVars4() {runTest("field itd using type variable from target type - 4");} public void testFieldITDsUsingTargetTypeVars5() {runTest("field itd using type variable from target type - 5");} public void testFieldITDsUsingTargetTypeVars6() {runTest("field itd using type variable from target type - 6");} public void testFieldITDsUsingTargetTypeVars7() {runTest("field itd using type variable from target type - 7");} public void testFieldITDsUsingTargetTypeVars8() {runTest("field itd using type variable from target type - 8");} public void testFieldITDsUsingTargetTypeVars9() {runTest("field itd using type variable from target type - 9");} public void testFieldITDsUsingTargetTypeVars10(){runTest("field itd using type variable from target type -10");} public void testFieldITDsUsingTargetTypeVars11(){runTest("field itd using type variable from target type -11");} public void testFieldITDsUsingTargetTypeVars12(){runTest("field itd using type variable from target type -12");} public void testFieldITDsUsingTargetTypeVars13(){runTest("field itd using type variable from target type -13");} public void testFieldITDsUsingTargetTypeVars14(){runTest("field itd using type variable from target type -14");} public void testFieldITDsUsingTargetTypeVars15(){runTest("field itd using type variable from target type -15");} public void testFieldITDsUsingTargetTypeVars16(){runTest("field itd using type variable from target type -16");} public void testFieldITDsUsingTargetTypeVars17(){runTest("field itd using type variable from target type -17");} public void testMethodITDsUsingTargetTypeVarsA1() {runTest("method itd using type variable from target type - A1");} public void testMethodITDsUsingTargetTypeVarsA2() {runTest("method itd using type variable from target type - A2");} public void testMethodITDsUsingTargetTypeVarsA3() {runTest("method itd using type variable from target type - A3");} public void testMethodITDsUsingTargetTypeVarsA4() {runTest("method itd using type variable from target type - A4");} public void testMethodITDsUsingTargetTypeVarsB1() {runTest("method itd using type variable from target type - B1");} public void testMethodITDsUsingTargetTypeVarsC1() {runTest("method itd using type variable from target type - C1");} public void testMethodITDsUsingTargetTypeVarsD1() {runTest("method itd using type variable from target type - D1");} public void testMethodITDsUsingTargetTypeVarsE1() {runTest("method itd using type variable from target type - E1");} public void testMethodITDsUsingTargetTypeVarsF1() {runTest("method itd using type variable from target type - F1");} public void testMethodITDsUsingTargetTypeVarsG1() {runTest("method itd using type variable from target type - G1");} public void testMethodITDsUsingTargetTypeVarsH1() {runTest("method itd using type variable from target type - H1");} public void testMethodITDsUsingTargetTypeVarsI1() {runTest("method itd using type variable from target type - I1");} public void testMethodITDsUsingTargetTypeVarsI2() {runTest("method itd using type variable from target type - I2");} public void testMethodITDsUsingTargetTypeVarsJ1() {runTest("method itd using type variable from target type - J1");} public void testMethodITDsUsingTargetTypeVarsK1() {runTest("method itd using type variable from target type - K1");} public void testMethodITDsUsingTargetTypeVarsL1() {runTest("method itd using type variable from target type - L1");} public void testMethodITDsUsingTargetTypeVarsM1() {runTest("method itd using type variable from target type - M1");} public void testMethodITDsUsingTargetTypeVarsM2() {runTest("method itd using type variable from target type - M2");} public void testMethodITDsUsingTargetTypeVarsN1() {runTest("method itd using type variable from target type - N1");} public void testMethodITDsUsingTargetTypeVarsO1() {runTest("method itd using type variable from target type - O1");} public void testMethodITDsUsingTargetTypeVarsO2() {runTest("method itd using type variable from target type - O2");} public void testMethodITDsUsingTargetTypeVarsP1() {runTest("method itd using type variable from target type - P1");} public void testMethodITDsUsingTargetTypeVarsQ1() {runTest("method itd using type variable from target type - Q1");} public void testCtorITDsUsingTargetTypeVarsA1() {runTest("ctor itd using type variable from target type - A1");} public void testCtorITDsUsingTargetTypeVarsB1() {runTest("ctor itd using type variable from target type - B1");} public void testCtorITDsUsingTargetTypeVarsC1() {runTest("ctor itd using type variable from target type - C1");} public void testCtorITDsUsingTargetTypeVarsD1() {runTest("ctor itd using type variable from target type - D1");} public void testCtorITDsUsingTargetTypeVarsE1() {runTest("ctor itd using type variable from target type - E1");} public void testCtorITDsUsingTargetTypeVarsF1() {runTest("ctor itd using type variable from target type - F1");} public void testCtorITDsUsingTargetTypeVarsG1() {runTest("ctor itd using type variable from target type - G1");} public void testCtorITDsUsingTargetTypeVarsH1() {runTest("ctor itd using type variable from target type - H1");} public void testCtorITDsUsingTargetTypeVarsI1() {runTest("ctor itd using type variable from target type - I1");} public void testSophisticatedAspectsA() {runTest("uberaspects - A");} public void testSophisticatedAspectsB() {runTest("uberaspects - B");} public void testSophisticatedAspectsC() {runTest("uberaspects - C");} public void testSophisticatedAspectsD() {runTest("uberaspects - D");} public void testSophisticatedAspectsE() {runTest("uberaspects - E");} public void testSophisticatedAspectsF() {runTest("uberaspects - F");} public void testSophisticatedAspectsG() {runTest("uberaspects - G");} public void testSophisticatedAspectsH() {runTest("uberaspects - H");} public void testSophisticatedAspectsI() {runTest("uberaspects - I");} public void testSophisticatedAspectsJ() {runTest("uberaspects - J");} //public void testSophisticatedAspectsK() {runTest("uberaspects - K");} // FIXME asc bounds testing is tough! public void testSophisticatedAspectsK2(){runTest("uberaspects - K2");} public void testSophisticatedAspectsL() {runTest("uberaspects - L");} public void testSophisticatedAspectsM() {runTest("uberaspects - M");} public void testSophisticatedAspectsN() {runTest("uberaspects - N");} public void testSophisticatedAspectsO() {runTest("uberaspects - O");} public void testSophisticatedAspectsP() {runTest("uberaspects - P");} public void testSophisticatedAspectsQ() {runTest("uberaspects - Q");} public void testSophisticatedAspectsR() {runTest("uberaspects - R");} public void testSophisticatedAspectsS() {runTest("uberaspects - S");} public void testSophisticatedAspectsT() {runTest("uberaspects - T");} public void testSophisticatedAspectsU() {runTest("uberaspects - U");} // includes nasty casts public void testSophisticatedAspectsV() {runTest("uberaspects - V");} // casts are gone public void testSophisticatedAspectsW() {runTest("uberaspects - W");} public void testSophisticatedAspectsX() {runTest("uberaspects - X");} // from the AJDK public void testSophisticatedAspectsY() {runTest("uberaspects - Y");} // pointcut matching public void testSophisticatedAspectsZ() {runTest("uberaspects - Z");} // FIXME asc these two tests have peculiar error messages - generic aspect related // public void testItdUsingTypeParameter() {runTest("itd using type parameter");} // public void testItdIncorrectlyUsingTypeParameter() {runTest("itd incorrectly using type parameter");} public void testUsingSameTypeVariable() {runTest("using same type variable in ITD");} public void testBinaryWeavingITDsA() {runTest("binary weaving ITDs - A");} public void testBinaryWeavingITDsB() {runTest("binary weaving ITDs - B");} public void testBinaryWeavingITDs1() {runTest("binary weaving ITDs - 1");} public void testBinaryWeavingITDs2() {runTest("binary weaving ITDs - 2");} public void testBinaryWeavingITDs3() {runTest("binary weaving ITDs - 3");} public void testGenericITFSharingTypeVariable() {runTest("generic intertype field declaration, sharing type variable");} // general tests ... usually just more complex scenarios public void testReusingTypeVariableLetters() {runTest("reusing type variable letters");} public void testMultipleGenericITDsInOneFile() {runTest("multiple generic itds in one file");} public void testItdNonStaticMember() {runTest("itd of non static member");} public void testItdStaticMember() {runTest("itd of static member");} public void testStaticGenericMethodITD() {runTest("static generic method itd");} public void testAtOverride0() {runTest("atOverride used with ITDs");} public void testAtOverride1() {runTest("atOverride used with ITDs - 1");} public void testAtOverride2() {runTest("atOverride used with ITDs - 2");} public void testAtOverride3() {runTest("atOverride used with ITDs - 3");} public void testAtOverride4() {runTest("atOverride used with ITDs - 4");} public void testAtOverride5() {runTest("atOverride used with ITDs - 5");} public void testAtOverride6() {runTest("atOverride used with ITDs - 6");} public void testAtOverride7() {runTest("atOverride used with ITDs - 7");} // bridge methods public void testITDBridgeMethodsCovariance1() {runTest("bridging with covariance 1 - normal");} public void testITDBridgeMethodsCovariance2() {runTest("bridging with covariance 1 - itd");} public void testITDBridgeMethods1Normal() {runTest("basic bridging with type vars - 1 - normal");} public void testITDBridgeMethods1Itd() {runTest("basic bridging with type vars - 1 - itd");} public void testITDBridgeMethods2Normal() {runTest("basic bridging with type vars - 2 - normal");} public void testITDBridgeMethods2Itd() {runTest("basic bridging with type vars - 2 - itd");} public void testITDBridgeMethodsPr91381() {runTest("Abstract intertype method and covariant returns");} // Just normal source compile of two types with a method override between them public void testGenericITDsBridgeMethods1() { runTest("bridge methods - 1"); checkMethodsExist("Sub1",new String[]{ "java.lang.Integer Sub1.m()", "java.lang.Object Sub1.m() [BridgeMethod]"}); } // Now the same thing but the aspect (which doesn't do much!) is binary woven in. public void testGenericITDsBridgeMethods1binary() { runTest("bridge methods - 1 - binary"); checkMethodsExist("Sub1",new String[]{ "java.lang.Integer Sub1.m()", "java.lang.Object Sub1.m() [BridgeMethod]"}); } // Now the method is put into the superclass via ITD - there should be a bridge method in the subclass public void testGenericITDsBridgeMethods2() { runTest("bridge methods - 2"); checkMethodsExist("Sub2",new String[]{ "java.lang.Integer Sub2.m()", "java.lang.Object Sub2.m() [BridgeMethod]"}); } // Now the superclass ITD is done with binary weaving so the weaver (rather than compiler) has to create the bridge method public void testGenericITDsBridgeMethods2binary() { runTest("bridge methods - 2 - binary"); checkMethodsExist("Sub2",new String[]{ "java.lang.Integer Sub2.m()", "java.lang.Object Sub2.m() [BridgeMethod]"}); } // Now the method is put into the subclass via ITD - there should be a bridge method alongside it in the subclass public void testGenericITDsBridgeMethods3() { runTest("bridge methods - 3"); checkMethodsExist("Sub3",new String[]{ "java.lang.Integer Sub3.m()", "java.lang.Object Sub3.m() [BridgeMethod]"}); } // Now the subclass ITD is done with binary weaving - the weaver should create the necessary bridge method public void testGenericITDsBridgeMethods3binary() { runTest("bridge methods - 3 - binary"); checkMethodsExist("Sub3",new String[]{ "java.lang.Integer Sub3.m()", "java.lang.Object Sub3.m() [BridgeMethod]"}); } // Now the two types are disconnected until the aspect supplies a declare parents relationship - // the bridge method should still be created in the subtype public void testGenericITDSBridgeMethods4() { runTest("bridge methods - 4"); checkMethodsExist("Sub4",new String[]{ "java.lang.Integer Sub4.m()", "java.lang.Object Sub4.m() [BridgeMethod]"}); } // now the aspect doing the decp between the types is applied via binary weaving - weaver should create the bridge method public void testGenericITDSBridgeMethods4binary() { runTest("bridge methods - 4 - binary"); checkMethodsExist("Sub4",new String[]{ "java.lang.Integer Sub4.m()", "java.lang.Object Sub4.m() [BridgeMethod]"}); } public void testBinaryBridgeMethodsOne() { runTest("binary bridge methods - one"); checkMethodsExist("OneB",new String[]{ "java.lang.Number OneB.firstMethod() [BridgeMethod]", "java.lang.Integer OneB.firstMethod()", "void OneB.secondMethod(java.lang.Number) [BridgeMethod]", "void OneB.secondMethod(java.lang.Integer)", "void OneB.thirdMethod(java.lang.Number,java.lang.Number) [BridgeMethod]", "void OneB.thirdMethod(java.lang.Integer,java.lang.Integer)", "void OneB.fourthMethod(java.util.List)", "java.lang.Number OneB.fifthMethod(java.lang.Number,java.util.List) [BridgeMethod]", "java.lang.Integer OneB.fifthMethod(java.lang.Integer,java.util.List)" }); } public void testBinaryBridgeMethodsTwo() { runTest("binary bridge methods - two"); checkMethodsExist("TwoB",new String[]{ "java.lang.Number TwoB.firstMethod(java.io.Serializable) [BridgeMethod]", "java.lang.Integer TwoB.firstMethod(java.lang.String)" }); } public void testBinaryBridgeMethodsThree() { runTest("binary bridge methods - three"); checkMethodsExist("ThreeB",new String[]{ "java.lang.Number ThreeB.m() [BridgeMethod]", "java.lang.Double ThreeB.m()" }); } public void testGenericITDsBridgeMethodsPR91381() {runTest("abstract intertype methods and covariant returns");} public void testGenericITDsBridgeMethodsPR91381_2() {runTest("abstract intertype methods and covariant returns - error");} // ---------------------------------------------------------------------------------------- // generic declare parents tests // ---------------------------------------------------------------------------------------- public void testPR96220_GenericDecp() { runTest("generic decp - simple"); checkOneSignatureAttribute(ajc,"Basic"); verifyClassSignature(ajc,"Basic","Ljava/lang/Object;LJ;LI;"); } // Both the existing type decl and the one adding via decp are parameterized public void testGenericDecpMultipleVariantsOfAParameterizedType1() { runTest("generic decp - implementing two variants #1"); } // Existing type decl is raw and the one added via decp is parameterized public void testGenericDecpMultipleVariantsOfAParameterizedType2() { runTest("generic decp - implementing two variants #2"); } // Existing type decl is parameterized and the one added via decp is raw public void testGenericDecpMultipleVariantsOfAParameterizedType3() { runTest("generic decp - implementing two variants #3"); } // decp is parameterized but it does match the one already on the type public void testGenericDecpMultipleVariantsOfAParameterizedType4() { runTest("generic decp - implementing two variants #4"); } // same as above four tests for binary weaving public void testGenericDecpMultipleVariantsOfAParameterizedType1_binaryWeaving() { runTest("generic decp binary - implementing two variants #1"); } public void testGenericDecpMultipleVariantsOfAParameterizedType2_binaryWeaving() { runTest("generic decp binary - implementing two variants #2"); } // Existing type decl is parameterized and the one added via decp is raw public void testGenericDecpMultipleVariantsOfAParameterizedType3_binaryWeaving() { runTest("generic decp binary - implementing two variants #3"); } // decp is parameterized but it does match the one already on the type public void testGenericDecpMultipleVariantsOfAParameterizedType4_binaryWeaving() { runTest("generic decp binary - implementing two variants #4"); } public void testGenericDecpParameterized() { runTest("generic decp - with parameterized on the target"); checkOneSignatureAttribute(ajc,"Basic6"); verifyClassSignature(ajc,"Basic6","Ljava/lang/Object;LI;LK;"); } public void testGenericDecpIncorrectNumberOfTypeParams() { runTest("generic decp - incorrect number of type parameters"); } public void testGenericDecpSpecifyingBounds() { runTest("generic decp - specifying bounds"); } public void testGenericDecpViolatingBounds() { runTest("generic decp - specifying bounds but breaking them"); } // need separate compilation test to verify signatures are ok // // public void testIllegalGenericDecp() { // runTest("illegal generic decp"); // } // // public void testPR95992_TypeResolvingProblemWithGenerics() { // runTest("Problems resolving type name inside generic class"); // } // -- Pointcut tests... public void testHandlerWithGenerics() { runTest("handler pcd and generics / type vars"); } public void testPointcutsThatDontAllowTypeVars() { runTest("pointcuts that dont allow type vars"); } public void testParameterizedTypesInAtPCDs() { runTest("annotation pcds with parameterized types"); } public void testAnnotationPatternsWithParameterizedTypes() { runTest("annotation patterns with parameterized types"); } public void testStaticInitializationWithParameterizedTypes() { runTest("staticinitialization and parameterized types"); } // no longer a valid test with generics simplication // public void testStaticInitializationMatchingWithParameterizedTypes() { // runTest("staticinitialization and parameterized type matching"); // } // no longer a valid test in simplified design // public void testStaticInitializationWithGenericTypes() { // runTest("staticinitialization with generic types"); // } // no longer a valid test in simplified design // public void testStaticInitializationWithGenericTypesAdvanced() { // runTest("staticinitialization with generic types - advanced"); // } public void testWithinPointcutErrors() { runTest("within pcd with various parameterizations and generic types - errors"); } public void testWithinPointcutWarnings() { runTest("within pcd with various parameterizations and generic types - warnings"); } public void testThisTargetPointcutErrors() { runTest("this and target with various parameterizations and generic types - errors"); } public void testThisTargetPointcutRuntime() { runTest("this and target with various parameterizations and generic types - runtime"); } public void testInitAndPreInitPointcutErrors() { runTest("init and preinit with parameterized declaring types"); } public void testInitAndPreInitPointcutMatchingWithGenericDeclaringTypes() { runTest("init and preinit with raw declaring type pattern"); } public void testInitAndPreInitPointcutMatchingWithParameterizedParameterTypes() { runTest("init and preinit with parameterized parameter types"); } public void testWithinCodePointcutErrors() { runTest("withincode with various parameterizations and generic types - errors"); } public void testWithinCodeMatching() { runTest("withincode with various parameterizations and generic types - matching"); } public void testWithinCodeOverrideMatchingWithGenericMembers() { runTest("withincode with overriding of inherited generic members"); } public void testExecutionWithRawType() { runTest("execution pcd with raw type matching"); } public void testExecutionWithRawSignature() { runTest("execution pcd with raw signature matching"); } public void testExecutionPointcutErrors() { runTest("execution with various parameterizations and generic types - errors"); } public void testExecutionMatching() { runTest("execution with various parameterizations and generic types - matching"); } public void testExecutionOverrideMatchingWithGenericMembers() { runTest("execution with overriding of inherited generic members"); } public void testCallPointcutErrors() { runTest("call with various parameterizations and generic types - errors"); } public void testCallMatching() { runTest("call with various parameterizations and generic types - matching"); } public void testCallOverrideMatchingWithGenericMembers() { runTest("call with overriding of inherited generic members"); } public void testCallWithBridgeMethods() { runTest("call with bridge methods"); } public void testGetAndSetPointcutErrors() { runTest("get and set with various parameterizations and generic types - errors"); } public void testGetAndSetPointcutMatchingWithGenericAndParameterizedTypes() { runTest("get and set with various parameterizations and generic declaring types"); } public void testGetAndSetPointcutMatchingWithGenericAndParameterizedFieldTypes() { runTest("get and set with various parameterizations and generic field types"); } public void testArgsWithRawType() { runTest("args with raw type and generic / parameterized sigs"); } public void testArgsParameterizedType() { runTest("args with parameterized type and generic / parameterized sigs"); } public void testArgsParameterizedAndWildcards() { runTest("args with parameterized type and wildcards"); } public void testArgsWithWildcardVar() { runTest("args with generic wildcard"); } public void testArgsWithWildcardExtendsVar() { runTest("args with generic wildcard extends"); } public void testArgsWithWildcardSuperVar() { runTest("args with generic wildcard super"); } public void testGenericMethodMatching() { runTest("generic method matching"); } public void testGenericWildcardsInSignatureMatching() { runTest("generic wildcards in signature matching"); } public void testAfterThrowing() { runTest("after throwing with parameterized throw type"); } public void testAfterReturningWithRawType() { runTest("after returning with raw type and generic / parameterized sigs"); } public void testAfterReturningParameterizedType() { runTest("after returning with parameterized type and generic / parameterized sigs"); } public void testAfterReturningParameterizedAndWildcards() { runTest("after returning with parameterized type and wildcards"); } public void testAfterReturningWithWildcardVar() { runTest("after returning with generic wildcard"); } public void testAfterReturningWithWildcardExtendsVar() { runTest("after returning with generic wildcard extends"); } public void testAfterReturningWithWildcardSuperVar() { runTest("after returning with generic wildcard super"); } public void testAJDKErasureMatchingExamples() { runTest("ajdk notebook: erasure matching examples"); } public void testAJDKParameterizedMatchingSimpleExamples() { runTest("ajdk notebook: simple parameterized type matching examples"); } public void testAJDKMixedTypeVarsAndParametersExample() { runTest("ajdk notebook: mixed parameterized types and generic methods"); } public void testAJDKSignatureAndWildcardExamples() { runTest("ajdk notebook: signature matching with generic wildcards"); } public void testAJDKBridgeMethodExamples() { runTest("ajdk notebook: bridge method examples"); } public void testAJDKArgsExamples() { runTest("ajdk notebook: args examples"); } public void testAJDKArgsAndWildcardsExamples() { runTest("ajdk notebook: args and wildcards examples"); } public void testAJDKAfterReturningExamples() { runTest("ajdk notebook: after returning examples"); } public void testAJDKPointcutInGenericClassExample() { runTest("ajdk notebook: pointcut in generic class example"); } // TESTS for generic abstract aspects that get extended and parameterized... public void testStaticPointcutParameterization() { runTest("static pointcut parameterization suite"); } public void testDynamicPointcutParameterization() { runTest("dynamic pointcut parameterization suite"); } public void testReferenceToPointcutInGenericClass() { runTest("reference to pointcut in generic class"); } public void testReferenceToPointcutInGenericClass2() { runTest("reference to non-parameterized pointcut in generic class"); } public void testDeclareParentsParameterized() { runTest("declare parents parameterized"); } public void testDeclarePrecedenceParameterized() { runTest("declare precedence parameterized"); } public void testDeclareAnnotationParameterized() { runTest("declare annotation parameterized"); } public void testMultiLevelGenericAspects() { runTest("multi-level generic abstract aspects"); } // --- helpers /** * When a class has been written to the sandbox directory, you can ask this method to * verify it contains a particular set of methods. Typically this is used to verify that * bridge methods have been created. */ public void checkMethodsExist(String classname,String[] methods) { Set methodsFound = new HashSet(); StringBuffer debugString = new StringBuffer(); try { ClassLoader cl = new URLClassLoader(new URL[]{ajc.getSandboxDirectory().toURL()}); Class clz = Class.forName(classname,false,cl); java.lang.reflect.Method[] ms = clz.getDeclaredMethods(); if (ms!=null) { for (int i =0;i "+debugString); } } StringBuffer unexpectedMethods = new StringBuffer(); if (!methodsFound.isEmpty()) { for (Iterator iter = methodsFound.iterator(); iter.hasNext();) { String element = (String) iter.next(); unexpectedMethods.append("[").append(element).append("]"); } fail("These methods weren't expected: "+unexpectedMethods); } } /** * Use 1.5 API isBridge if available. * See JLS3 15.12.4.5 Create Frame, Synchronize, Transfer Control */ public static boolean isBridge(java.lang.reflect.Method m) { // why not importing java.lang.reflect.Method? No BCEL clash? if (!LangUtil.is15VMOrGreater()) { return false; } try { final Class[] noparms = new Class[0]; java.lang.reflect.Method isBridge = java.lang.reflect.Method.class.getMethod("isBridge", noparms); Boolean result = (Boolean) isBridge.invoke(m, new Object[0]); return result.booleanValue(); } catch (Throwable t) { return false; } } public static JavaClass getClass(Ajc ajc, String classname) { try { ClassPath cp = new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator + System.getProperty("java.class.path")); SyntheticRepository sRepos = SyntheticRepository.getInstance(cp); JavaClass clazz = sRepos.loadClass(classname); return clazz; } catch (ClassNotFoundException e) { fail("Couldn't find class "+classname+" in the sandbox directory."); } return null; } public static Signature getClassSignature(Ajc ajc,String classname) { JavaClass clazz = getClass(ajc,classname); Signature sigAttr = null; Attribute[] attrs = clazz.getAttributes(); for (int i = 0; i < attrs.length; i++) { Attribute attribute = attrs[i]; if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute; } return sigAttr; } public static void checkOneSignatureAttribute(Ajc ajc,String classname) { JavaClass clazz = getClass(ajc,classname); Signature sigAttr = null; Attribute[] attrs = clazz.getAttributes(); int signatureCount = 0; StringBuffer sb = new StringBuffer(); for (int i = 0; i < attrs.length; i++) { Attribute attribute = attrs[i]; if (attribute.getName().equals("Signature")) { signatureCount++; sb.append("\n"+((Signature)attribute).getSignature()); } } if (signatureCount>1) fail("Should be only one signature attribute but found "+signatureCount+sb.toString()); } // Check the signature attribute on a class is correct public static void verifyClassSignature(Ajc ajc,String classname,String sig) { Signature sigAttr = getClassSignature(ajc,classname); assertTrue("Failed to find signature attribute for class "+classname,sigAttr!=null); assertTrue("Expected signature to be '"+sig+"' but was '"+sigAttr.getSignature()+"'", sigAttr.getSignature().equals(sig)); } private static String stringify(Class[] clazzes) { if (clazzes==null) return ""; StringBuffer sb = new StringBuffer(); for (int i = 0; i < clazzes.length; i++) { if (i>0) sb.append(","); sb.append(clazzes[i].getName()); } return sb.toString(); } }