Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

GenericsTests.java 44KB

před 19 roky
před 19 roky
před 18 roky
před 19 roky
před 19 roky
před 19 roky
před 19 roky
před 18 roky
před 18 roky
před 18 roky
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. package org.aspectj.systemtest.ajc150;
  2. import java.io.File;
  3. import java.net.MalformedURLException;
  4. import java.net.URL;
  5. import java.net.URLClassLoader;
  6. import java.util.HashSet;
  7. import java.util.Set;
  8. import org.aspectj.apache.bcel.classfile.Attribute;
  9. import org.aspectj.apache.bcel.classfile.JavaClass;
  10. import org.aspectj.apache.bcel.classfile.Signature;
  11. import org.aspectj.apache.bcel.util.ClassPath;
  12. import org.aspectj.apache.bcel.util.SyntheticRepository;
  13. import org.aspectj.testing.XMLBasedAjcTestCase;
  14. import org.aspectj.tools.ajc.Ajc;
  15. import org.aspectj.util.LangUtil;
  16. import junit.framework.Test;
  17. public class GenericsTests extends XMLBasedAjcTestCase {
  18. /*==========================================
  19. * Generics test plan for pointcuts.
  20. *
  21. * handler PASS
  22. * - does not permit type var spec
  23. * - does not permit generic type (fail with type not found)
  24. * - does not permit parameterized types
  25. * if PASS
  26. * - does not permit type vars
  27. * cflow PASS
  28. * - does not permit type vars
  29. * cflowbelow PASS
  30. * - does not permit type vars
  31. * @this PASS
  32. * - does not permit type vars PASS
  33. * - does not permit parameterized type PASS
  34. * @target PASS
  35. * - does not permit type vars PASS
  36. * - does not permit parameterized type PASS
  37. * @args PASS
  38. * - does not permit type vars PASS
  39. * - does not permit parameterized type PASS
  40. * @annotation PASS
  41. * - does not permit type vars PASS
  42. * - does not permit parameterized type PASS
  43. * @within, @within code - as above PASS
  44. * annotation type pattern with generic and parameterized types PASS
  45. * - just make sure that annotation interfaces can never be generic first! VERIFIED
  46. * - @Foo<T> should fail PASS
  47. * - @Foo<String> should fail PASS
  48. * - @(Foo || Bar<T>) should fail DEFERRED (not critical)
  49. * staticinitialization PASS
  50. * - error on parameterized type PASS N/A
  51. * - permit parameterized type + PASS N/A
  52. * - matching with parameterized type + N/A
  53. * - wrong number of parameters in parameterized type PASS N/A
  54. * - generic type with one type parameter N/A
  55. * - generic type with n type parameters N/A
  56. * - generic type with bounds [extends, extends + i/f's] N/A
  57. * - generic type with wrong number of type params N/A
  58. * - wildcards in bounds N/A
  59. * within PASS
  60. * - as above, but allows parameterized type (disallowed in simplified plan)
  61. * - wildcards in type parameters N/A
  62. * this PASS
  63. * - no type vars
  64. * - parameterized types - disallowed in simplification plan
  65. * - implements
  66. * - instanceof
  67. * target PASS
  68. * - as this
  69. * args
  70. * - args(List) matches List, List<T>, List<String> PASS
  71. * - args(List<T>) -> invalid absolute type T
  72. * - args(List<String>) matches List<String> but not List<Number> PASS
  73. * - args(List<String>) matches List with unchecked warning PASS
  74. * - args(List<String>) matches List<?> with unchecked warning PASS
  75. * - args(List<Double>) matches List, List<?>, List<? extends Number> with unchecked warning PASS
  76. * matches List<Double> PASS, List<? extends Double> PASS(with warning)
  77. * - args(List<?>) matches List, List<String>, List<?>, ... PASS
  78. * - args(List<? extends Number) matches List<Number>, List<Double>, not List<String> PASS
  79. * matches List, List<?> with unchecked warning PASS
  80. * - args(List<? super Number>) matches List<Object>, List<Number>
  81. * does not match List<Double>
  82. * matches List, List<?> with unchecked warning
  83. * matches List<? super Number>
  84. * matches List<? extends Object> with unchecked warning
  85. * matches List<? extends Number> with unchecked warning
  86. * get & set PASS
  87. * - parameterized declaring type PASS
  88. * - generic declaring type PASS
  89. * - field type is type variable PASS
  90. * - field type is parameterized PASS
  91. * initialization, preinitialization PASS
  92. * - generic declaring type PASS
  93. * - type variables as params PASS
  94. * - parameterized types as params PASS
  95. * - no join points for init, preinit of parameterized types (as per staticinit) PASS
  96. * withincode PASS
  97. * - no generic or parameterized declaring type patterns PASS
  98. * - no parameterized throws patterns PASS
  99. * - return type as type variable PASS
  100. * - return type as parameterized type PASS
  101. * - parameter as type variable PASS
  102. * - parameter as parameterized type PASS
  103. * - no join points within bridge methods PASS
  104. * execution PASS
  105. * - no generic or parameterized declaring type patterns PASS
  106. * - no parameterized throws patterns PASS
  107. * - return type as type variable PASS
  108. * - return type as parameterized type PASS
  109. * - parameter as type variable PASS
  110. * - parameter as parameterized type PASS
  111. * - no join points for bridge methods PASS
  112. * call PASS
  113. * - no generic or parameterized declaring type patterns PASS
  114. * - no parameterized throws patterns PASS
  115. * - return type as type variable PASS
  116. * - return type as parameterized type PASS
  117. * - parameter as type variable PASS
  118. * - parameter as parameterized type PASS
  119. * - calls to a bridge methods PASS
  120. * after throwing - can't use parameterized type pattern
  121. * after returning - same as for args
  122. */
  123. /* ==========================================
  124. * Generics test plan for ITDs.
  125. *
  126. * think about:
  127. * - 'visibility' default/private/public
  128. * - static/nonstatic
  129. * - parameterized ITDs (methods/ctors/fields)
  130. * - ITD target: interface/class/aspect
  131. * - multiple type variables
  132. * - constructor ITDs, method ITDs
  133. * - ITDs sharing type variables with generic types
  134. * - relating to above point, this makes generic ITD fields possible
  135. * - signature attributes for generic ITDs (required? required only for public ITDs?)
  136. * - binary weaving when target type changes over time (might start out 'simple' then sometime later be 'generic')
  137. * - bridge methods - when to create them
  138. * - multiple 'separate' ITDs in a file that share a type variable by 'name'
  139. * - wildcards '?' 'extends' 'super' '&'
  140. * - do type variables assigned to members need to persist across serialization
  141. * - recursive type variable definitions eg. <R extends Comparable<? super R>>
  142. * - super/extends with parameterized types <? extends List<String>>
  143. * - multiple ITDs defined in one type that reuse type variable letters, specifying different bounds
  144. * - generic aspects
  145. *
  146. * PASS parsing generic ITDs
  147. * PASS generic methods
  148. * PASS generic constructors
  149. * PASS ITD visibility
  150. * PASS static/nonstatic
  151. * PASS parameterizedITDs
  152. * PASS differing targets (interface/class/aspect)
  153. * PASS multiple type variables in an ITD
  154. * PASS parsing ITDs that share type variables with target type
  155. * PASS using type variables from the target type in your field ITD
  156. * PASS using type variables from the target type in your method ITD (but no type vars of your own)
  157. * PASS using type variables from the target type in your ctor ITD (but no type vars of your own)
  158. * PASS using type variables from the target type and having your own too (methods)
  159. * PASS using type variables from the target type and having your own too (ctors)
  160. * PASS reusing type variable letter but differing spec across multiple ITDs in one aspect
  161. * PASS wildcards
  162. * PASS recursive type variable definitions
  163. * PASS generic aspects
  164. * PASS parameterizing ITDs with type variables
  165. * PASS using type variables from the target type in your *STATIC* ITD (field/method/ctor) (error scenario)
  166. * PASS basic binary weaving of generic itds
  167. *
  168. * TODO generic aspect binary weaving (or at least multi source file weaving)
  169. * TODO binary weaving with changing types (moving between generic and simple)
  170. * TODO bridge method creation (also relates to covariance overrides..)
  171. * TODO exotic class/interface bounds ('? extends List<String>','? super anything')
  172. * TODO signature attributes for generic ITDs (public only?)
  173. *
  174. */
  175. public static Test suite() {
  176. return XMLBasedAjcTestCase.loadSuite(GenericsTests.class);
  177. }
  178. protected File getSpecFile() {
  179. return getClassResource("ajc150.xml");
  180. }
  181. public void testITDReturningParameterizedType() {
  182. runTest("ITD with parameterized type");
  183. }
  184. public void testPR91267_1() {
  185. runTest("NPE using generic methods in aspects 1");
  186. }
  187. public void testParameterizedTypeAndAroundAdvice_PR115250() {
  188. runTest("parameterized type and around advice");
  189. }
  190. public void testParameterizedTypeAndAroundAdvice_PR115250_2() {
  191. runTest("parameterized type and around advice - 2");
  192. }
  193. public void testPR91267_2() {
  194. runTest("NPE using generic methods in aspects 2");
  195. }
  196. public void testPR91053() {
  197. runTest("Generics problem with Set");
  198. }
  199. public void testPR87282() {
  200. runTest("Compilation error on generic member introduction");
  201. }
  202. public void testGenericsOverrides_1() { runTest("generics and ITD overrides - 1"); }
  203. public void testGenericsOverrides_2() { runTest("generics and ITD overrides - 2"); }
  204. public void testGenericsOverrides_3() { runTest("generics and ITD overrides - 3"); }
  205. public void testGenericsOverrides_4() { runTest("generics and ITD overrides - 4"); }
  206. public void testSelfBoundGenerics_pr117296() {
  207. runTest("self bounding generic types");
  208. }
  209. public void testPR88606() {
  210. runTest("Parameterized types on introduced fields not correctly recognized");
  211. }
  212. public void testPR97763() {
  213. runTest("ITD method with generic arg");
  214. }
  215. public void testGenericsBang_pr95993() {
  216. runTest("NPE at ClassScope.java:660 when compiling generic class");
  217. }
  218. // generic aspects
  219. public void testPR96220_GenericAspects1() {runTest("generic aspects - 1");}
  220. public void testPR96220_GenericAspects2() {runTest("generic aspects - 2");}
  221. public void testPR96220_GenericAspects3() {runTest("generic aspects - 3");}
  222. public void testGenericAspects4() {runTest("generic aspects - 4");}
  223. public void testGenericAspects5() {runTest("generic aspects - 5 (ajdk)");} // in separate files
  224. public void testGenericAspects6() {runTest("generic aspects - 6 (ajdk)");} // all in one file
  225. public void testTypeVariablesInDeclareWarning() { runTest("generic aspect with declare warning using type vars");}
  226. public void testTypeVariablesInExecutionAdvice() { runTest("generic aspect with execution advice using type vars");}
  227. public void testTypeVariablesInAnonymousPointcut() { runTest("generic aspect with anonymous pointcut");}
  228. public void testDeclareParentWithParameterizedInterface() {
  229. runTest("generic aspect declare parents");
  230. }
  231. public void testDeclareSoftInGenericAspect() {
  232. runTest("generic aspect declare soft");
  233. }
  234. //////////////////////////////////////////////////////////////////////////////
  235. // Generic/Parameterized ITDs - includes scenarios from developers notebook //
  236. //////////////////////////////////////////////////////////////////////////////
  237. // parsing of generic ITD members
  238. public void testParseItdNonStaticMethod() {runTest("Parsing generic ITDs - 1");}
  239. public void testParseItdStaticMethod() {runTest("Parsing generic ITDs - 2");}
  240. public void testParseItdCtor() {runTest("Parsing generic ITDs - 3");}
  241. public void testParseItdComplexMethod() {runTest("Parsing generic ITDs - 4");}
  242. public void testParseItdSharingVars1() {runTest("Parsing generic ITDs - 5");}
  243. public void testParseItdSharingVars2() {runTest("Parsing generic ITDs - 6");}
  244. // non static
  245. public void testGenericMethodITD1() {runTest("generic method itd - 1");} // <E> ... (List<? extends E>)
  246. public void testGenericMethodITD2() {runTest("generic method itd - 2");} // <E extends Number> ... (List<? extends E>) called incorrectly
  247. public void testGenericMethodITD3() {runTest("generic method itd - 3");} // <E> ... (List<E>,List<E>)
  248. public void testGenericMethodITD4() {runTest("generic method itd - 4");} // <A,B> ... (List<A>,List<B>)
  249. public void testGenericMethodITD5() {runTest("generic method itd - 5");} // <E> ... (List<E>,List<E>) called incorrectly
  250. public void testGenericMethodITD6() {runTest("generic method itd - 6");} // <E extends Number> ... (List<? extends E>)
  251. public void testGenericMethodITD7() {runTest("generic method itd - 7"); } // <E> ... (List<E>,List<? extends E>)
  252. public void testGenericMethodITD8() {runTest("generic method itd - 8"); } // <E> ... (List<E>,List<? extends E>) called incorrectly
  253. public void testGenericMethodITD9() {runTest("generic method itd - 9"); } // <R extends Comparable<? super R>> ... (List<R>)
  254. public void testGenericMethodITD10() {runTest("generic method itd - 10");} // <R extends Comparable<? super R>> ... (List<R>) called incorrectly
  255. public void testGenericMethodITD11() {runTest("generic method itd - 11");} // <R extends Comparable<? extends R>> ... (List<R>)
  256. public void testGenericMethodITD12() {runTest("generic method itd - 12");} // <R extends Comparable<? extends R>> ... (List<R>) called incorrectly
  257. public void testGenericMethodITD13() {runTest("generic method itd - 13");} // <R extends Comparable<? extends R>> ... (List<R>) called correctly in a clever way ;)
  258. public void testGenericMethodITD14() {runTest("generic method itd - 14");} // <R extends Comparable<? super R>> ... (List<R>) called incorrectly in a clever way
  259. public void testGenericMethodITD15() {runTest("generic method itd - 15");} // <R extends Comparable<? super R>> ... (List<R>) called correctly in a clever way
  260. // generic ctors
  261. public void testGenericCtorITD1() {runTest("generic ctor itd - 1");} // <T> new(List<T>)
  262. public void testGenericCtorITD2() {runTest("generic ctor itd - 2");} // <T> new(List<T>,List<? extends T>)
  263. public void testGenericCtorITD3() {runTest("generic ctor itd - 3");} // <T> new(List<T>,Comparator<? super T>)
  264. // parameterized ITDs
  265. public void testParameterizedMethodITD1() {runTest("parameterized method itd - 1");} // (List<? extends Super>)
  266. public void testParameterizedMethodITD2() {runTest("parameterized method itd - 2");} // (List<? extends Number>) called incorrectly
  267. public void testParameterizedMethodITD3() {runTest("parameterized method itd - 3");} // (List<? super A>) called incorrectly
  268. public void testParameterizedMethodITD4() {runTest("parameterized method itd - 4");} // (List<? super B>)
  269. // differing visibilities
  270. public void testPublicITDs() {runTest("public itds");}
  271. public void testPublicITDsErrors() {runTest("public itds with errors");}
  272. public void testPrivateITDs() {runTest("private itds");}
  273. public void testPackageITDs() {runTest("package itds");}
  274. // targetting different types (interface/class/aspect)
  275. public void testTargettingInterface() {runTest("targetting interface");}
  276. public void testTargettingAspect() {runTest("targetting aspect");}
  277. public void testTargettingClass() {runTest("targetting class");}
  278. // using a type variable from the target generic type in your ITD
  279. public void testFieldITDsUsingTargetTypeVars1() {runTest("field itd using type variable from target type - 1");}
  280. public void testFieldITDsUsingTargetTypeVars2() {runTest("field itd using type variable from target type - 2");}
  281. public void testFieldITDsUsingTargetTypeVars3() {runTest("field itd using type variable from target type - 3");}
  282. public void testFieldITDsUsingTargetTypeVars4() {runTest("field itd using type variable from target type - 4");}
  283. public void testFieldITDsUsingTargetTypeVars5() {runTest("field itd using type variable from target type - 5");}
  284. public void testFieldITDsUsingTargetTypeVars6() {runTest("field itd using type variable from target type - 6");}
  285. public void testFieldITDsUsingTargetTypeVars7() {runTest("field itd using type variable from target type - 7");}
  286. public void testFieldITDsUsingTargetTypeVars8() {runTest("field itd using type variable from target type - 8");}
  287. public void testFieldITDsUsingTargetTypeVars9() {runTest("field itd using type variable from target type - 9");}
  288. public void testFieldITDsUsingTargetTypeVars10(){runTest("field itd using type variable from target type -10");}
  289. public void testFieldITDsUsingTargetTypeVars11(){runTest("field itd using type variable from target type -11");}
  290. public void testFieldITDsUsingTargetTypeVars12(){runTest("field itd using type variable from target type -12");}
  291. public void testFieldITDsUsingTargetTypeVars13(){runTest("field itd using type variable from target type -13");}
  292. public void testFieldITDsUsingTargetTypeVars14(){runTest("field itd using type variable from target type -14");}
  293. public void testFieldITDsUsingTargetTypeVars15(){runTest("field itd using type variable from target type -15");}
  294. public void testFieldITDsUsingTargetTypeVars16(){runTest("field itd using type variable from target type -16");}
  295. public void testFieldITDsUsingTargetTypeVars17(){runTest("field itd using type variable from target type -17");}
  296. public void testMethodITDsUsingTargetTypeVarsA1() {runTest("method itd using type variable from target type - A1");}
  297. public void testMethodITDsUsingTargetTypeVarsA2() {runTest("method itd using type variable from target type - A2");}
  298. public void testMethodITDsUsingTargetTypeVarsA3() {runTest("method itd using type variable from target type - A3");}
  299. public void testMethodITDsUsingTargetTypeVarsA4() {runTest("method itd using type variable from target type - A4");}
  300. public void testMethodITDsUsingTargetTypeVarsB1() {runTest("method itd using type variable from target type - B1");}
  301. public void testMethodITDsUsingTargetTypeVarsC1() {runTest("method itd using type variable from target type - C1");}
  302. public void testMethodITDsUsingTargetTypeVarsD1() {runTest("method itd using type variable from target type - D1");}
  303. public void testMethodITDsUsingTargetTypeVarsE1() {runTest("method itd using type variable from target type - E1");}
  304. public void testMethodITDsUsingTargetTypeVarsF1() {runTest("method itd using type variable from target type - F1");}
  305. public void testMethodITDsUsingTargetTypeVarsG1() {runTest("method itd using type variable from target type - G1");}
  306. public void testMethodITDsUsingTargetTypeVarsH1() {runTest("method itd using type variable from target type - H1");}
  307. public void testMethodITDsUsingTargetTypeVarsI1() {runTest("method itd using type variable from target type - I1");}
  308. public void testMethodITDsUsingTargetTypeVarsI2() {runTest("method itd using type variable from target type - I2");}
  309. public void testMethodITDsUsingTargetTypeVarsJ1() {runTest("method itd using type variable from target type - J1");}
  310. public void testMethodITDsUsingTargetTypeVarsK1() {runTest("method itd using type variable from target type - K1");}
  311. public void testMethodITDsUsingTargetTypeVarsL1() {runTest("method itd using type variable from target type - L1");}
  312. public void testMethodITDsUsingTargetTypeVarsM1() {runTest("method itd using type variable from target type - M1");}
  313. public void testMethodITDsUsingTargetTypeVarsM2() {runTest("method itd using type variable from target type - M2");}
  314. public void testMethodITDsUsingTargetTypeVarsN1() {runTest("method itd using type variable from target type - N1");}
  315. public void testMethodITDsUsingTargetTypeVarsO1() {runTest("method itd using type variable from target type - O1");}
  316. public void testMethodITDsUsingTargetTypeVarsO2() {runTest("method itd using type variable from target type - O2");}
  317. public void testMethodITDsUsingTargetTypeVarsP1() {runTest("method itd using type variable from target type - P1");}
  318. public void testMethodITDsUsingTargetTypeVarsQ1() {runTest("method itd using type variable from target type - Q1");}
  319. public void testCtorITDsUsingTargetTypeVarsA1() {runTest("ctor itd using type variable from target type - A1");}
  320. public void testCtorITDsUsingTargetTypeVarsB1() {runTest("ctor itd using type variable from target type - B1");}
  321. public void testCtorITDsUsingTargetTypeVarsC1() {runTest("ctor itd using type variable from target type - C1");}
  322. public void testCtorITDsUsingTargetTypeVarsD1() {runTest("ctor itd using type variable from target type - D1");}
  323. public void testCtorITDsUsingTargetTypeVarsE1() {runTest("ctor itd using type variable from target type - E1");}
  324. public void testCtorITDsUsingTargetTypeVarsF1() {runTest("ctor itd using type variable from target type - F1");}
  325. public void testCtorITDsUsingTargetTypeVarsG1() {runTest("ctor itd using type variable from target type - G1");}
  326. public void testCtorITDsUsingTargetTypeVarsH1() {runTest("ctor itd using type variable from target type - H1");}
  327. public void testCtorITDsUsingTargetTypeVarsI1() {runTest("ctor itd using type variable from target type - I1");}
  328. public void testSophisticatedAspectsA() {runTest("uberaspects - A");}
  329. public void testSophisticatedAspectsB() {runTest("uberaspects - B");}
  330. public void testSophisticatedAspectsC() {runTest("uberaspects - C");}
  331. public void testSophisticatedAspectsD() {runTest("uberaspects - D");}
  332. public void testSophisticatedAspectsE() {runTest("uberaspects - E");}
  333. public void testSophisticatedAspectsF() {runTest("uberaspects - F");}
  334. public void testSophisticatedAspectsG() {runTest("uberaspects - G");}
  335. public void testSophisticatedAspectsH() {runTest("uberaspects - H");}
  336. public void testSophisticatedAspectsI() {runTest("uberaspects - I");}
  337. public void testSophisticatedAspectsJ() {runTest("uberaspects - J");}
  338. //public void testSophisticatedAspectsK() {runTest("uberaspects - K");} // FIXME asc bounds testing is tough!
  339. public void testSophisticatedAspectsK2(){runTest("uberaspects - K2");}
  340. public void testSophisticatedAspectsL() {runTest("uberaspects - L");}
  341. public void testSophisticatedAspectsM() {runTest("uberaspects - M");}
  342. public void testSophisticatedAspectsN() {runTest("uberaspects - N");}
  343. public void testSophisticatedAspectsO() {runTest("uberaspects - O");}
  344. public void testSophisticatedAspectsP() {runTest("uberaspects - P");}
  345. public void testSophisticatedAspectsQ() {runTest("uberaspects - Q");}
  346. public void testSophisticatedAspectsR() {runTest("uberaspects - R");}
  347. public void testSophisticatedAspectsS() {runTest("uberaspects - S");}
  348. public void testSophisticatedAspectsT() {runTest("uberaspects - T");}
  349. public void testSophisticatedAspectsU() {runTest("uberaspects - U");} // includes nasty casts
  350. public void testSophisticatedAspectsV() {runTest("uberaspects - V");} // casts are gone
  351. public void testSophisticatedAspectsW() {runTest("uberaspects - W");}
  352. public void testSophisticatedAspectsX() {runTest("uberaspects - X");} // from the AJDK
  353. public void testSophisticatedAspectsY() {runTest("uberaspects - Y");} // pointcut matching
  354. public void testSophisticatedAspectsZ() {runTest("uberaspects - Z");}
  355. // FIXME asc these two tests have peculiar error messages - generic aspect related
  356. // public void testItdUsingTypeParameter() {runTest("itd using type parameter");}
  357. // public void testItdIncorrectlyUsingTypeParameter() {runTest("itd incorrectly using type parameter");}
  358. public void testUsingSameTypeVariable() {runTest("using same type variable in ITD");}
  359. public void testBinaryWeavingITDsA() {runTest("binary weaving ITDs - A");}
  360. public void testBinaryWeavingITDsB() {runTest("binary weaving ITDs - B");}
  361. public void testBinaryWeavingITDs1() {runTest("binary weaving ITDs - 1");}
  362. public void testBinaryWeavingITDs2() {runTest("binary weaving ITDs - 2");}
  363. public void testBinaryWeavingITDs3() {runTest("binary weaving ITDs - 3");}
  364. public void testGenericITFSharingTypeVariable() {runTest("generic intertype field declaration, sharing type variable");}
  365. // general tests ... usually just more complex scenarios
  366. public void testReusingTypeVariableLetters() {runTest("reusing type variable letters");}
  367. public void testMultipleGenericITDsInOneFile() {runTest("multiple generic itds in one file");}
  368. public void testItdNonStaticMember() {runTest("itd of non static member");}
  369. public void testItdStaticMember() {runTest("itd of static member");}
  370. public void testStaticGenericMethodITD() {runTest("static generic method itd");}
  371. public void testAtOverride0() {runTest("atOverride used with ITDs");}
  372. public void testAtOverride1() {runTest("atOverride used with ITDs - 1");}
  373. public void testAtOverride2() {runTest("atOverride used with ITDs - 2");}
  374. public void testAtOverride3() {runTest("atOverride used with ITDs - 3");}
  375. public void testAtOverride4() {runTest("atOverride used with ITDs - 4");}
  376. public void testAtOverride5() {runTest("atOverride used with ITDs - 5");}
  377. public void testAtOverride6() {runTest("atOverride used with ITDs - 6");}
  378. public void testAtOverride7() {runTest("atOverride used with ITDs - 7");}
  379. // bridge methods
  380. public void testITDBridgeMethodsCovariance1() {runTest("bridging with covariance 1 - normal");}
  381. public void testITDBridgeMethodsCovariance2() {runTest("bridging with covariance 1 - itd");}
  382. public void testITDBridgeMethods1Normal() {runTest("basic bridging with type vars - 1 - normal");}
  383. public void testITDBridgeMethods1Itd() {runTest("basic bridging with type vars - 1 - itd");}
  384. public void testITDBridgeMethods2Normal() {runTest("basic bridging with type vars - 2 - normal");}
  385. public void testITDBridgeMethods2Itd() {runTest("basic bridging with type vars - 2 - itd");}
  386. public void testITDBridgeMethodsPr91381() {runTest("Abstract intertype method and covariant returns");}
  387. // Just normal source compile of two types with a method override between them
  388. public void testGenericITDsBridgeMethods1() {
  389. runTest("bridge methods - 1");
  390. checkMethodsExist("Sub1",new String[]{
  391. "java.lang.Integer Sub1.m()",
  392. "java.lang.Object Sub1.m() [BridgeMethod]"});
  393. }
  394. // Now the same thing but the aspect (which doesn't do much!) is binary woven in.
  395. public void testGenericITDsBridgeMethods1binary() {
  396. runTest("bridge methods - 1 - binary");
  397. checkMethodsExist("Sub1",new String[]{
  398. "java.lang.Integer Sub1.m()",
  399. "java.lang.Object Sub1.m() [BridgeMethod]"});
  400. }
  401. // Now the method is put into the superclass via ITD - there should be a bridge method in the subclass
  402. public void testGenericITDsBridgeMethods2() {
  403. runTest("bridge methods - 2");
  404. checkMethodsExist("Sub2",new String[]{
  405. "java.lang.Integer Sub2.m()",
  406. "java.lang.Object Sub2.m() [BridgeMethod]"});
  407. }
  408. // Now the superclass ITD is done with binary weaving so the weaver (rather than compiler) has to create the bridge method
  409. public void testGenericITDsBridgeMethods2binary() {
  410. runTest("bridge methods - 2 - binary");
  411. checkMethodsExist("Sub2",new String[]{
  412. "java.lang.Integer Sub2.m()",
  413. "java.lang.Object Sub2.m() [BridgeMethod]"});
  414. }
  415. // Now the method is put into the subclass via ITD - there should be a bridge method alongside it in the subclass
  416. public void testGenericITDsBridgeMethods3() {
  417. runTest("bridge methods - 3");
  418. checkMethodsExist("Sub3",new String[]{
  419. "java.lang.Integer Sub3.m()",
  420. "java.lang.Object Sub3.m() [BridgeMethod]"});
  421. }
  422. // Now the subclass ITD is done with binary weaving - the weaver should create the necessary bridge method
  423. public void testGenericITDsBridgeMethods3binary() {
  424. runTest("bridge methods - 3 - binary");
  425. checkMethodsExist("Sub3",new String[]{
  426. "java.lang.Integer Sub3.m()",
  427. "java.lang.Object Sub3.m() [BridgeMethod]"});
  428. }
  429. // Now the two types are disconnected until the aspect supplies a declare parents relationship -
  430. // the bridge method should still be created in the subtype
  431. public void testGenericITDSBridgeMethods4() {
  432. runTest("bridge methods - 4");
  433. checkMethodsExist("Sub4",new String[]{
  434. "java.lang.Integer Sub4.m()",
  435. "java.lang.Object Sub4.m() [BridgeMethod]"});
  436. }
  437. // now the aspect doing the decp between the types is applied via binary weaving - weaver should create the bridge method
  438. public void testGenericITDSBridgeMethods4binary() {
  439. runTest("bridge methods - 4 - binary");
  440. checkMethodsExist("Sub4",new String[]{
  441. "java.lang.Integer Sub4.m()",
  442. "java.lang.Object Sub4.m() [BridgeMethod]"});
  443. }
  444. public void testBinaryBridgeMethodsOne() {
  445. runTest("binary bridge methods - one");
  446. checkMethodsExist("OneB",new String[]{
  447. "java.lang.Number OneB.firstMethod() [BridgeMethod]",
  448. "java.lang.Integer OneB.firstMethod()",
  449. "void OneB.secondMethod(java.lang.Number) [BridgeMethod]",
  450. "void OneB.secondMethod(java.lang.Integer)",
  451. "void OneB.thirdMethod(java.lang.Number,java.lang.Number) [BridgeMethod]",
  452. "void OneB.thirdMethod(java.lang.Integer,java.lang.Integer)",
  453. "void OneB.fourthMethod(java.util.List)",
  454. "java.lang.Number OneB.fifthMethod(java.lang.Number,java.util.List) [BridgeMethod]",
  455. "java.lang.Integer OneB.fifthMethod(java.lang.Integer,java.util.List)"
  456. });
  457. }
  458. public void testBinaryBridgeMethodsTwo() {
  459. runTest("binary bridge methods - two");
  460. checkMethodsExist("TwoB",new String[]{
  461. "java.lang.Number TwoB.firstMethod(java.io.Serializable) [BridgeMethod]",
  462. "java.lang.Integer TwoB.firstMethod(java.lang.String)"
  463. });
  464. }
  465. public void testBinaryBridgeMethodsThree() {
  466. runTest("binary bridge methods - three");
  467. checkMethodsExist("ThreeB",new String[]{
  468. "java.lang.Number ThreeB.m() [BridgeMethod]",
  469. "java.lang.Double ThreeB.m()"
  470. });
  471. }
  472. public void testGenericITDsBridgeMethodsPR91381() {runTest("abstract intertype methods and covariant returns");}
  473. public void testGenericITDsBridgeMethodsPR91381_2() {runTest("abstract intertype methods and covariant returns - error");}
  474. // ----------------------------------------------------------------------------------------
  475. // generic declare parents tests
  476. // ----------------------------------------------------------------------------------------
  477. public void testPR96220_GenericDecp() {
  478. runTest("generic decp - simple");
  479. checkOneSignatureAttribute(ajc,"Basic");
  480. verifyClassSignature(ajc,"Basic","Ljava/lang/Object;LJ<Ljava/lang/Double;>;LI<Ljava/lang/Double;>;");
  481. }
  482. // Both the existing type decl and the one adding via decp are parameterized
  483. public void testGenericDecpMultipleVariantsOfAParameterizedType1() {
  484. runTest("generic decp - implementing two variants #1");
  485. }
  486. // Existing type decl is raw and the one added via decp is parameterized
  487. public void testGenericDecpMultipleVariantsOfAParameterizedType2() {
  488. runTest("generic decp - implementing two variants #2");
  489. }
  490. // Existing type decl is parameterized and the one added via decp is raw
  491. public void testGenericDecpMultipleVariantsOfAParameterizedType3() {
  492. runTest("generic decp - implementing two variants #3");
  493. }
  494. // decp is parameterized but it does match the one already on the type
  495. public void testGenericDecpMultipleVariantsOfAParameterizedType4() {
  496. runTest("generic decp - implementing two variants #4");
  497. }
  498. // same as above four tests for binary weaving
  499. public void testGenericDecpMultipleVariantsOfAParameterizedType1_binaryWeaving() {
  500. runTest("generic decp binary - implementing two variants #1");
  501. }
  502. public void testGenericDecpMultipleVariantsOfAParameterizedType2_binaryWeaving() {
  503. runTest("generic decp binary - implementing two variants #2");
  504. }
  505. // Existing type decl is parameterized and the one added via decp is raw
  506. public void testGenericDecpMultipleVariantsOfAParameterizedType3_binaryWeaving() {
  507. runTest("generic decp binary - implementing two variants #3");
  508. }
  509. // decp is parameterized but it does match the one already on the type
  510. public void testGenericDecpMultipleVariantsOfAParameterizedType4_binaryWeaving() {
  511. runTest("generic decp binary - implementing two variants #4");
  512. }
  513. public void testGenericDecpParameterized() {
  514. runTest("generic decp - with parameterized on the target");
  515. checkOneSignatureAttribute(ajc,"Basic6");
  516. verifyClassSignature(ajc,"Basic6","<J:Ljava/lang/Object;>Ljava/lang/Object;LI<TJ;>;LK<Ljava/lang/Integer;>;");
  517. }
  518. public void testGenericDecpIncorrectNumberOfTypeParams() {
  519. runTest("generic decp - incorrect number of type parameters");
  520. }
  521. public void testGenericDecpSpecifyingBounds() {
  522. runTest("generic decp - specifying bounds");
  523. }
  524. public void testGenericDecpViolatingBounds() {
  525. runTest("generic decp - specifying bounds but breaking them");
  526. }
  527. // need separate compilation test to verify signatures are ok
  528. //
  529. // public void testIllegalGenericDecp() {
  530. // runTest("illegal generic decp");
  531. // }
  532. //
  533. // public void testPR95992_TypeResolvingProblemWithGenerics() {
  534. // runTest("Problems resolving type name inside generic class");
  535. // }
  536. // -- Pointcut tests...
  537. public void testHandlerWithGenerics() {
  538. runTest("handler pcd and generics / type vars");
  539. }
  540. public void testPointcutsThatDontAllowTypeVars() {
  541. runTest("pointcuts that dont allow type vars");
  542. }
  543. public void testParameterizedTypesInAtPCDs() {
  544. runTest("annotation pcds with parameterized types");
  545. }
  546. public void testAnnotationPatternsWithParameterizedTypes() {
  547. runTest("annotation patterns with parameterized types");
  548. }
  549. public void testStaticInitializationWithParameterizedTypes() {
  550. runTest("staticinitialization and parameterized types");
  551. }
  552. // no longer a valid test with generics simplication
  553. // public void testStaticInitializationMatchingWithParameterizedTypes() {
  554. // runTest("staticinitialization and parameterized type matching");
  555. // }
  556. // no longer a valid test in simplified design
  557. // public void testStaticInitializationWithGenericTypes() {
  558. // runTest("staticinitialization with generic types");
  559. // }
  560. // no longer a valid test in simplified design
  561. // public void testStaticInitializationWithGenericTypesAdvanced() {
  562. // runTest("staticinitialization with generic types - advanced");
  563. // }
  564. public void testWithinPointcutErrors() {
  565. runTest("within pcd with various parameterizations and generic types - errors");
  566. }
  567. public void testWithinPointcutWarnings() {
  568. runTest("within pcd with various parameterizations and generic types - warnings");
  569. }
  570. public void testThisTargetPointcutErrors() {
  571. runTest("this and target with various parameterizations and generic types - errors");
  572. }
  573. public void testThisTargetPointcutRuntime() {
  574. runTest("this and target with various parameterizations and generic types - runtime");
  575. }
  576. public void testInitAndPreInitPointcutErrors() {
  577. runTest("init and preinit with parameterized declaring types");
  578. }
  579. public void testInitAndPreInitPointcutMatchingWithGenericDeclaringTypes() {
  580. runTest("init and preinit with raw declaring type pattern");
  581. }
  582. public void testInitAndPreInitPointcutMatchingWithParameterizedParameterTypes() {
  583. runTest("init and preinit with parameterized parameter types");
  584. }
  585. public void testWithinCodePointcutErrors() {
  586. runTest("withincode with various parameterizations and generic types - errors");
  587. }
  588. public void testWithinCodeMatching() {
  589. runTest("withincode with various parameterizations and generic types - matching");
  590. }
  591. public void testWithinCodeOverrideMatchingWithGenericMembers() {
  592. runTest("withincode with overriding of inherited generic members");
  593. }
  594. public void testExecutionWithRawType() {
  595. runTest("execution pcd with raw type matching");
  596. }
  597. public void testExecutionWithRawSignature() {
  598. runTest("execution pcd with raw signature matching");
  599. }
  600. public void testExecutionPointcutErrors() {
  601. runTest("execution with various parameterizations and generic types - errors");
  602. }
  603. public void testExecutionMatching() {
  604. runTest("execution with various parameterizations and generic types - matching");
  605. }
  606. public void testExecutionOverrideMatchingWithGenericMembers() {
  607. runTest("execution with overriding of inherited generic members");
  608. }
  609. public void testCallPointcutErrors() {
  610. runTest("call with various parameterizations and generic types - errors");
  611. }
  612. public void testCallMatching() {
  613. runTest("call with various parameterizations and generic types - matching");
  614. }
  615. public void testCallOverrideMatchingWithGenericMembers() {
  616. runTest("call with overriding of inherited generic members");
  617. }
  618. public void testCallWithBridgeMethods() {
  619. runTest("call with bridge methods");
  620. }
  621. public void testGetAndSetPointcutErrors() {
  622. runTest("get and set with various parameterizations and generic types - errors");
  623. }
  624. public void testGetAndSetPointcutMatchingWithGenericAndParameterizedTypes() {
  625. runTest("get and set with various parameterizations and generic declaring types");
  626. }
  627. public void testGetAndSetPointcutMatchingWithGenericAndParameterizedFieldTypes() {
  628. runTest("get and set with various parameterizations and generic field types");
  629. }
  630. public void testArgsWithRawType() {
  631. runTest("args with raw type and generic / parameterized sigs");
  632. }
  633. public void testArgsParameterizedType() {
  634. runTest("args with parameterized type and generic / parameterized sigs");
  635. }
  636. public void testArgsParameterizedAndWildcards() {
  637. runTest("args with parameterized type and wildcards");
  638. }
  639. public void testArgsWithWildcardVar() {
  640. runTest("args with generic wildcard");
  641. }
  642. public void testArgsWithWildcardExtendsVar() {
  643. runTest("args with generic wildcard extends");
  644. }
  645. public void testArgsWithWildcardSuperVar() {
  646. runTest("args with generic wildcard super");
  647. }
  648. public void testGenericMethodMatching() {
  649. runTest("generic method matching");
  650. }
  651. public void testGenericWildcardsInSignatureMatching() {
  652. runTest("generic wildcards in signature matching");
  653. }
  654. public void testAfterThrowing() {
  655. runTest("after throwing with parameterized throw type");
  656. }
  657. public void testAfterReturningWithRawType() {
  658. runTest("after returning with raw type and generic / parameterized sigs");
  659. }
  660. public void testAfterReturningParameterizedType() {
  661. runTest("after returning with parameterized type and generic / parameterized sigs");
  662. }
  663. public void testAfterReturningParameterizedAndWildcards() {
  664. runTest("after returning with parameterized type and wildcards");
  665. }
  666. public void testAfterReturningWithWildcardVar() {
  667. runTest("after returning with generic wildcard");
  668. }
  669. public void testAfterReturningWithWildcardExtendsVar() {
  670. runTest("after returning with generic wildcard extends");
  671. }
  672. public void testAfterReturningWithWildcardSuperVar() {
  673. runTest("after returning with generic wildcard super");
  674. }
  675. public void testAJDKErasureMatchingExamples() {
  676. runTest("ajdk notebook: erasure matching examples");
  677. }
  678. public void testAJDKParameterizedMatchingSimpleExamples() {
  679. runTest("ajdk notebook: simple parameterized type matching examples");
  680. }
  681. public void testAJDKMixedTypeVarsAndParametersExample() {
  682. runTest("ajdk notebook: mixed parameterized types and generic methods");
  683. }
  684. public void testAJDKSignatureAndWildcardExamples() {
  685. runTest("ajdk notebook: signature matching with generic wildcards");
  686. }
  687. // had to remove at e37 level - although pointcuts are likely to work, we can't compile the code
  688. // that invokes the bridge methods - seems the compiler is too smart and won't let them through.
  689. // public void testAJDKBridgeMethodExamples() {
  690. // runTest("ajdk notebook: bridge method examples");
  691. // }
  692. public void testAJDKArgsExamples() {
  693. runTest("ajdk notebook: args examples");
  694. }
  695. public void testAJDKArgsAndWildcardsExamples() {
  696. runTest("ajdk notebook: args and wildcards examples");
  697. }
  698. public void testAJDKAfterReturningExamples() {
  699. runTest("ajdk notebook: after returning examples");
  700. }
  701. public void testAJDKPointcutInGenericClassExample() {
  702. runTest("ajdk notebook: pointcut in generic class example");
  703. }
  704. // TESTS for generic abstract aspects that get extended and parameterized...
  705. public void testStaticPointcutParameterization() {
  706. runTest("static pointcut parameterization suite");
  707. }
  708. public void testDynamicPointcutParameterization() {
  709. runTest("dynamic pointcut parameterization suite");
  710. }
  711. public void testReferenceToPointcutInGenericClass() {
  712. runTest("reference to pointcut in generic class");
  713. }
  714. public void testReferenceToPointcutInGenericClass2() {
  715. runTest("reference to non-parameterized pointcut in generic class");
  716. }
  717. public void testDeclareParentsParameterized() {
  718. runTest("declare parents parameterized");
  719. }
  720. public void testDeclarePrecedenceParameterized() {
  721. runTest("declare precedence parameterized");
  722. }
  723. public void testDeclareAnnotationParameterized() {
  724. runTest("declare annotation parameterized");
  725. }
  726. public void testMultiLevelGenericAspects() {
  727. runTest("multi-level generic abstract aspects");
  728. }
  729. // --- helpers
  730. /**
  731. * When a class has been written to the sandbox directory, you can ask this method to
  732. * verify it contains a particular set of methods. Typically this is used to verify that
  733. * bridge methods have been created.
  734. */
  735. public void checkMethodsExist(String classname,String[] methods) {
  736. Set<String> methodsFound = new HashSet<>();
  737. StringBuffer debugString = new StringBuffer();
  738. try {
  739. ClassLoader cl = new URLClassLoader(new URL[]{ajc.getSandboxDirectory().toURL()});
  740. Class<?> clz = Class.forName(classname,false,cl);
  741. java.lang.reflect.Method[] ms = clz.getDeclaredMethods();
  742. if (ms!=null) {
  743. for (int i =0;i<ms.length;i++) {
  744. String methodString = ms[i].getReturnType().getName()+" "+ms[i].getDeclaringClass().getName()+"."+
  745. ms[i].getName()+"("+stringify(ms[i].getParameterTypes())+")"+
  746. (isBridge(ms[i])?" [BridgeMethod]":"");
  747. methodsFound.add(methodString);
  748. debugString.append("\n[").append(methodString).append("]");
  749. }
  750. }
  751. } catch (ClassNotFoundException e) {
  752. e.printStackTrace();
  753. } catch (MalformedURLException e) {
  754. e.printStackTrace();
  755. }
  756. // check the methods specified do exist
  757. for (int i = 0; i < methods.length; i++) {
  758. String string = methods[i];
  759. if (!methodsFound.remove(string)) {
  760. fail("Couldn't find ["+string+"] in the set of methods in "+classname+" => "+debugString);
  761. }
  762. }
  763. StringBuffer unexpectedMethods = new StringBuffer();
  764. if (!methodsFound.isEmpty()) {
  765. for (String element: methodsFound) {
  766. unexpectedMethods.append("[").append(element).append("]");
  767. }
  768. fail("These methods weren't expected: "+unexpectedMethods);
  769. }
  770. }
  771. /**
  772. * Use 1.5 API isBridge if available.
  773. * See JLS3 15.12.4.5 Create Frame, Synchronize, Transfer Control
  774. */
  775. public static boolean isBridge(java.lang.reflect.Method m) {
  776. // why not importing java.lang.reflect.Method? No BCEL clash?
  777. if (!LangUtil.is15VMOrGreater()) {
  778. return false;
  779. }
  780. try {
  781. final Class<?>[] noparms = new Class[0];
  782. java.lang.reflect.Method isBridge
  783. = java.lang.reflect.Method.class.getMethod("isBridge", noparms);
  784. Boolean result = (Boolean) isBridge.invoke(m, new Object[0]);
  785. return result.booleanValue();
  786. } catch (Throwable t) {
  787. return false;
  788. }
  789. }
  790. public static JavaClass getClass(Ajc ajc, String classname) {
  791. try {
  792. ClassPath cp =
  793. new ClassPath(ajc.getSandboxDirectory() + File.pathSeparator + System.getProperty("java.class.path"));
  794. SyntheticRepository sRepos = SyntheticRepository.getInstance(cp);
  795. JavaClass clazz = sRepos.loadClass(classname);
  796. return clazz;
  797. } catch (ClassNotFoundException e) {
  798. fail("Couldn't find class "+classname+" in the sandbox directory.");
  799. }
  800. return null;
  801. }
  802. public static Signature getClassSignature(Ajc ajc,String classname) {
  803. JavaClass clazz = getClass(ajc,classname);
  804. Signature sigAttr = null;
  805. Attribute[] attrs = clazz.getAttributes();
  806. for (int i = 0; i < attrs.length; i++) {
  807. Attribute attribute = attrs[i];
  808. if (attribute.getName().equals("Signature")) sigAttr = (Signature)attribute;
  809. }
  810. return sigAttr;
  811. }
  812. public static void checkOneSignatureAttribute(Ajc ajc,String classname) {
  813. JavaClass clazz = getClass(ajc,classname);
  814. Attribute[] attrs = clazz.getAttributes();
  815. int signatureCount = 0;
  816. StringBuffer sb = new StringBuffer();
  817. for (int i = 0; i < attrs.length; i++) {
  818. Attribute attribute = attrs[i];
  819. if (attribute.getName().equals("Signature")) {
  820. signatureCount++;
  821. sb.append("\n"+((Signature)attribute).getSignature());
  822. }
  823. }
  824. if (signatureCount>1) fail("Should be only one signature attribute but found "+signatureCount+sb.toString());
  825. }
  826. // Check the signature attribute on a class is correct
  827. public static void verifyClassSignature(Ajc ajc,String classname,String sig) {
  828. Signature sigAttr = getClassSignature(ajc,classname);
  829. assertTrue("Failed to find signature attribute for class "+classname,sigAttr!=null);
  830. assertTrue("Expected signature to be '"+sig+"' but was '"+sigAttr.getSignature()+"'",
  831. sigAttr.getSignature().equals(sig));
  832. }
  833. private static String stringify(Class<?>[] clazzes) {
  834. if (clazzes==null) return "";
  835. StringBuffer sb = new StringBuffer();
  836. for (int i = 0; i < clazzes.length; i++) {
  837. if (i>0) sb.append(",");
  838. sb.append(clazzes[i].getName());
  839. }
  840. return sb.toString();
  841. }
  842. }