You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Ajc164Tests.java 18KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
  1. /*******************************************************************************
  2. * Copyright (c) 2008 Contributors
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v 2.0
  5. * which accompanies this distribution, and is available at
  6. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  7. *
  8. * Contributors:
  9. * Andy Clement - initial API and implementation
  10. *******************************************************************************/
  11. package org.aspectj.systemtest.ajc164;
  12. import java.io.PrintWriter;
  13. import java.util.List;
  14. import org.aspectj.apache.bcel.classfile.LocalVariable;
  15. import org.aspectj.apache.bcel.classfile.LocalVariableTable;
  16. import org.aspectj.apache.bcel.classfile.Method;
  17. import org.aspectj.asm.AsmManager;
  18. import org.aspectj.asm.IHierarchy;
  19. import org.aspectj.asm.IProgramElement;
  20. import org.aspectj.asm.IRelationship;
  21. import org.aspectj.testing.XMLBasedAjcTestCase;
  22. import junit.framework.Test;
  23. public class Ajc164Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
  24. public void testGenericAspectsNpe_pr268689() {
  25. runTest("generics aspects npe");
  26. }
  27. public void testGenericAspectsNpe_pr268710() {
  28. runTest("generics aspects incorrect error");
  29. }
  30. public void testGenericsItdNpe_pr267559() {
  31. runTest("generics and itd npe");
  32. }
  33. public void testAnnoStyleLong_pr266564() {
  34. runTest("annotation style long");
  35. }
  36. public void testAnnoStyleLong_pr266564_2() {
  37. runTest("annotation style long - 2");
  38. }
  39. public void testUnusedPrivateWarning_pr266420() {
  40. runTest("unused private warning");
  41. }
  42. public void testUnusedPrivateWarning_pr266420_2() {
  43. runTest("unused private warning - 2");
  44. }
  45. public void testUnusedPrivateWarning_pr266420_3() {
  46. runTest("unused private warning - 3");
  47. }
  48. /**
  49. * This test program can be used to compare handles for faulted in binary aspects with handles that would be used if the aspect
  50. * was available as source. There are two compile steps in the xml for the test - commenting out the first will allow the source
  51. * handles to be seen, leaving it in will switch to binary. Effectively the only difference should be that in the binary case
  52. * the handles are prefixed 'binaries'.
  53. *
  54. * Change due to bug 274558: now AJDT wants (blah.class as the 'source file' for the ITD so that is another difference when
  55. * switching.
  56. */
  57. public void testItdsAspectPathModel_pr265729_1() {
  58. runTest("aspectpath model");
  59. AsmManager model = AsmManager.lastActiveStructureModel;
  60. IHierarchy top = model.getHierarchy();
  61. printModel(model);
  62. IProgramElement ipe = null;
  63. // ITD METHOD
  64. // should be the ITD method from the binary aspect:
  65. // public Color Orange.getColor() { return Color.orange; }
  66. ipe = top.findElementForType("demo", "Orange");
  67. assertNotNull(ipe);
  68. assertEquals("<demo{Orange.java[Orange", ipe.getHandleIdentifier());
  69. IRelationship ir = model.getRelationshipMap().get(ipe).get(0);
  70. String itdMethodHandle = ir.getTargets().get(0);
  71. // handle when all source: <{Aspect.java}Aspect)Orange.getColor
  72. // assertEquals("/binaries<{Aspect.java}Aspect)Orange.getColor", itdMethodHandle);
  73. assertEquals("/binaries<(Aspect.class>Aspect°Orange.getColor", itdMethodHandle);
  74. IProgramElement itdpe = model.getHierarchy().findElementForHandle(itdMethodHandle);
  75. assertEquals("java.awt.Color", itdpe.getCorrespondingType(true));
  76. // ITD FIELD
  77. // should be the ITD field from the binary aspect:
  78. // public Color Strawberry.color
  79. ipe = top.findElementForType("demo", "Strawberry");
  80. assertNotNull(ipe);
  81. assertEquals("<demo{Strawberry.java[Strawberry", ipe.getHandleIdentifier());
  82. ir = model.getRelationshipMap().get(ipe).get(0);
  83. String itdFieldHandle = ir.getTargets().get(0);
  84. // source handle <{Aspect.java}Aspect)Strawberry.color
  85. // assertEquals("/binaries<{Aspect.java}Aspect)Strawberry.color", itdFieldHandle);
  86. assertEquals("/binaries<(Aspect.class>Aspect,Strawberry.color", itdFieldHandle);
  87. IProgramElement itdfpe = model.getHierarchy().findElementForHandle(itdMethodHandle);
  88. assertEquals("java.awt.Color", itdfpe.getCorrespondingType(true));
  89. // ITD CONSTRUCTOR
  90. // /binaries< Aspect.java}Aspect)java.awt.Color demo.Strawberry.color
  91. ipe = top.findElementForType("demo", "Fruit");
  92. assertNotNull(ipe);
  93. assertEquals("<demo{Fruit.java[Fruit", ipe.getHandleIdentifier());
  94. ir = model.getRelationshipMap().get(ipe).get(0);
  95. String itdCtorHandle = ir.getTargets().get(0);
  96. // source handle <{Aspect.java}Aspect)Fruit.Fruit_new)QColor;)QString;
  97. // assertEquals("/binaries<{Aspect.java}Aspect)Fruit.Fruit_new)QColor;)QString;", itdCtorHandle);
  98. assertEquals("/binaries<(Aspect.class>Aspect°Fruit.Fruit_new°QColor;°QString;", itdCtorHandle);
  99. IProgramElement itdcpe = model.getHierarchy().findElementForHandle(itdCtorHandle);
  100. List<char[]> ptypes = itdcpe.getParameterTypes();
  101. assertEquals("java.awt.Color", new String(ptypes.get(0)));
  102. assertEquals("java.lang.String", new String(ptypes.get(1)));
  103. }
  104. private void printModel(AsmManager model) {
  105. try {
  106. AsmManager.dumptree(model.getHierarchy().getRoot(), 0);
  107. model.dumprels(new PrintWriter(System.out));
  108. } catch (Exception e) {
  109. }
  110. }
  111. public void testGenericsAopXml_pr266220() {
  112. runTest("generics and aop.xml");
  113. }
  114. public void testOptimizingIf_pr266165_1() {
  115. runTest("optimizing if for constant reference - 1");
  116. }
  117. public void testOptimizingIf_pr266165_2() {
  118. runTest("optimizing if for constant reference - 2");
  119. }
  120. public void testOptimizingIf_pr266165_3() {
  121. runTest("optimizing if for constant reference - 3");
  122. }
  123. public void testOptimizingIf_pr266165_4() {
  124. runTest("optimizing if for constant reference - 4");
  125. }
  126. // public void testAnnoInherited_pr265695() {
  127. // runTest("anno inherited");
  128. // }
  129. //
  130. // public void testAnnoInherited_pr265695_2() {
  131. // runTest("new syntax for inherited anno - 1");
  132. // }
  133. //
  134. // public void testAnnoInherited_pr265695_3() {
  135. // runTest("new syntax for inherited anno - 3");
  136. // }
  137. public void testParserProblemSubArrayPatterns_pr148508() {
  138. runTest("parser problem for array subtypes");
  139. }
  140. public void testVarargs_pr265418() {
  141. runTest("varargs");
  142. }
  143. public void testIncorrectDateResolution_pr265360() {
  144. runTest("incorrect resolution of Date");
  145. }
  146. public void testDualPreClinit_pr233032() {
  147. runTest("dual preClinit");
  148. }
  149. public void testHandles_pr263310() {
  150. runTest("inner handles");
  151. IHierarchy top = AsmManager.lastActiveStructureModel.getHierarchy();
  152. IProgramElement ipe = null;
  153. ipe = findElementAtLine(top.getRoot(), 13);
  154. assertEquals("<p{HandleTestingAspect.java>HandleTestingAspect[InnerClass>InnerInnerAspect|1", ipe.getHandleIdentifier());
  155. // ipe = findElementAtLine(top.getRoot(), 29);
  156. // assertEquals("<x*OverrideOptions.aj}OverrideOptions&around!2",
  157. // ipe.getHandleIdentifier());
  158. }
  159. public void testHandles_pr263666() {
  160. runTest("around advice handles");
  161. IHierarchy top = AsmManager.lastActiveStructureModel.getHierarchy();
  162. IProgramElement ipe = null;
  163. ipe = findElementAtLine(top.getRoot(), 22);
  164. assertEquals("<x*OverrideOptions.aj>OverrideOptions§around", ipe.getHandleIdentifier());
  165. ipe = findElementAtLine(top.getRoot(), 29);
  166. assertEquals("<x*OverrideOptions.aj>OverrideOptions§around!2", ipe.getHandleIdentifier());
  167. }
  168. // Only one of two aspects named
  169. public void testAopConfig1() {
  170. runTest("aop config - 1");
  171. }
  172. // Only one of two aspects named - and named one is scoped to only affect
  173. // one type
  174. public void testAopConfig2() {
  175. runTest("aop config - 2");
  176. }
  177. // Invalid scope specified - cannot be parsed as type pattern
  178. public void testAopConfig3() {
  179. runTest("aop config - 3");
  180. }
  181. // excluding types from weaving
  182. public void testAopConfig4() {
  183. runTest("aop config - 4");
  184. }
  185. // excluding types from weaving
  186. public void testAopConfig5() {
  187. runTest("aop config - 5");
  188. }
  189. /**
  190. * If multiple XML files are given together with {@code -xmlConfigured}, they will be logically merged into one.
  191. * I.e., given the following three XML config files:
  192. *
  193. * <pre>{@code
  194. * <aspectj>
  195. * <aspects>
  196. * <aspect name="A" scope="B"/>
  197. * </aspects>
  198. * <weaver>
  199. * <exclude within="A*"/>
  200. * </weaver>
  201. * </aspectj>
  202. * }</pre>
  203. *
  204. * <pre>{@code
  205. * <aspectj>
  206. * <aspects>
  207. * <aspect name="A2" scope="B2"/>
  208. * </aspects>
  209. * </aspectj>
  210. * }</pre>
  211. *
  212. * <pre>{@code
  213. * <aspectj>
  214. * <aspects>
  215. * <aspect name="A3"/>
  216. * </aspects>
  217. * </aspectj>
  218. * }</pre>
  219. *
  220. * The result will be as if only one XML config file with this content was specified:
  221. *
  222. * <pre>{@code
  223. * <aspectj>
  224. * <aspects>
  225. * <aspect name="A" scope="B"/>
  226. * <aspect name="A2" scope="B2"/>
  227. * <aspect name="A3"/>
  228. * </aspects>
  229. * <weaver>
  230. * <exclude within="A*"/>
  231. * </weaver>
  232. * </aspectj>
  233. * }</pre>
  234. */
  235. public void testMultipleXMLFiles() {
  236. runTest("aop config - multiple XML files");
  237. }
  238. public void testAjcThisNotRead() {
  239. runTest("ajcthis not read");
  240. }
  241. public void testRecursiveCflow() {
  242. runTest("recursive cflow");
  243. }
  244. public void testAnnoDecprecedence_pr256779() {
  245. runTest("anno decprecedence");
  246. }
  247. //
  248. public void testBrokenLVT_pr194314_1() throws Exception {
  249. runTest("broken lvt - 1");
  250. Method m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "Service"), "method_aroundBody1$advice");
  251. if (m.getLocalVariableTable() == null) {
  252. fail("Local variable table should not be null");
  253. }
  254. // Method:
  255. // private static final void method_aroundBody1$advice(Service, long,
  256. // JoinPoint, ServiceInterceptor, ProceedingJoinPoint);
  257. LocalVariable[] lvt = m.getLocalVariableTable().getLocalVariableTable();
  258. assertEquals(7, lvt.length); // no aroundClosure compared to second
  259. // version of this test
  260. assertEquals("LService; ajc$this(0) start=0 len=86", stringify(m.getLocalVariableTable(), 0));
  261. assertEquals("J l(1) start=0 len=86", stringify(m.getLocalVariableTable(), 1));
  262. assertEquals("Lorg/aspectj/lang/JoinPoint; thisJoinPoint(3) start=0 len=86", stringify(m.getLocalVariableTable(), 2));
  263. assertEquals("LServiceInterceptor; ajc$aspectInstance(4) start=0 len=86", stringify(m.getLocalVariableTable(), 3));
  264. assertEquals("Lorg/aspectj/lang/ProceedingJoinPoint; pjp(5) start=0 len=86", stringify(m.getLocalVariableTable(), 4));
  265. assertEquals("[Ljava/lang/Object; args(6) start=9 len=77", stringify(m.getLocalVariableTable(), 5));
  266. assertEquals("J id(7) start=21 len=65", stringify(m.getLocalVariableTable(), 6));
  267. }
  268. public void testBrokenLVT_pr194314_2() throws Exception {
  269. runTest("broken lvt - 2");
  270. Method m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "Service"), "method_aroundBody1$advice");
  271. if (m.getLocalVariableTable() == null) {
  272. fail("Local variable table should not be null");
  273. }
  274. System.out.println(m.getLocalVariableTable());
  275. LocalVariable[] lvt = m.getLocalVariableTable().getLocalVariableTable();
  276. assertEquals(8, lvt.length);
  277. // private static final void method_aroundBody1$advice(Service, long,
  278. // JoinPoint, ServiceInterceptorCodeStyle, AroundClosure,
  279. // JoinPoint);
  280. assertEquals("LService; ajc$this(0) start=0 len=68", stringify(m.getLocalVariableTable(), 0));
  281. assertEquals("J l(1) start=0 len=68", stringify(m.getLocalVariableTable(), 1));
  282. assertEquals("Lorg/aspectj/lang/JoinPoint; thisJoinPoint(3) start=0 len=68", stringify(m.getLocalVariableTable(), 2));
  283. assertEquals("LServiceInterceptorCodeStyle; ajc$aspectInstance(4) start=0 len=68", stringify(m.getLocalVariableTable(), 3));
  284. assertEquals("Lorg/aspectj/runtime/internal/AroundClosure; ajc$aroundClosure(5) start=0 len=68",
  285. stringify(m.getLocalVariableTable(), 4));
  286. assertEquals("Lorg/aspectj/lang/JoinPoint; thisJoinPoint(6) start=0 len=68", stringify(m.getLocalVariableTable(), 5));
  287. assertEquals("[Ljava/lang/Object; args(7) start=9 len=59", stringify(m.getLocalVariableTable(), 6));
  288. assertEquals("J id(8) start=21 len=47", stringify(m.getLocalVariableTable(), 7));
  289. }
  290. /**
  291. * This test checks that local variable table for the interMethodDispatcher is built correctly, for the related code see
  292. * IntertypeMethodDeclaration.generateDispatchMethod(). It checks non-static and static ITDs. Once the information here is
  293. * correct then around advice on ITDs can also be correct.
  294. */
  295. public void testBrokenLVT_pr194314_3() throws Exception {
  296. runTest("broken lvt - 3");
  297. // Check intermethoddispatchers have the lvts correct
  298. // first ITD: public void I.foo(String s,int i,String[] ss) {}
  299. Method m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "X"), "ajc$interMethodDispatch1$X$I$foo");
  300. LocalVariableTable lvt = m.getLocalVariableTable();
  301. assertNotNull(lvt);
  302. assertEquals("LI; ajc$this_(0) start=0 len=10", stringify(lvt, 0));
  303. assertEquals("Ljava/lang/String; s(1) start=0 len=10", stringify(lvt, 1));
  304. assertEquals("I i(2) start=0 len=10", stringify(lvt, 2));
  305. assertEquals("[Ljava/lang/String; ss(3) start=0 len=10", stringify(lvt, 3));
  306. // second ITD: public void I.fooStatic(Long l,int i,String[] ss) {}
  307. m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "X"), "ajc$interMethodDispatch1$X$C$fooStatic");
  308. lvt = m.getLocalVariableTable();
  309. assertNotNull(lvt);
  310. assertEquals("J l(0) start=0 len=7", stringify(lvt, 0));
  311. assertEquals("I i(2) start=0 len=7", stringify(lvt, 1));
  312. assertEquals("[Ljava/lang/String; ss(3) start=0 len=7", stringify(lvt, 2));
  313. // Now let's check the around advice on the calls to those ITDs
  314. // non-static:
  315. m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "C"), "foo_aroundBody1$advice");
  316. lvt = m.getLocalVariableTable();
  317. assertNotNull(lvt);
  318. assertEquals("LC; ajc$this(0) start=0 len=0", stringify(lvt, 0));
  319. assertEquals("LI; target(1) start=0 len=0", stringify(lvt, 1));
  320. assertEquals("Ljava/lang/String; s(2) start=0 len=0", stringify(lvt, 2));
  321. assertEquals("I i(3) start=0 len=0", stringify(lvt, 3));
  322. assertEquals("[Ljava/lang/String; ss(4) start=0 len=0", stringify(lvt, 4));
  323. assertEquals("LX; ajc$aspectInstance(5) start=0 len=0", stringify(lvt, 5));
  324. assertEquals("Lorg/aspectj/runtime/internal/AroundClosure; ajc$aroundClosure(6) start=0 len=0", stringify(lvt, 6));
  325. // static:
  326. m = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "C"), "fooStatic_aroundBody3$advice");
  327. lvt = m.getLocalVariableTable();
  328. assertNotNull(lvt);
  329. assertEquals("LC; ajc$this(0) start=0 len=0", stringify(lvt, 0));
  330. assertEquals("J l(1) start=0 len=0", stringify(lvt, 1));
  331. assertEquals("I i(3) start=0 len=0", stringify(lvt, 2));
  332. assertEquals("[Ljava/lang/String; ss(4) start=0 len=0", stringify(lvt, 3));
  333. assertEquals("LX; ajc$aspectInstance(5) start=0 len=0", stringify(lvt, 4));
  334. assertEquals("Lorg/aspectj/runtime/internal/AroundClosure; ajc$aroundClosure(6) start=0 len=0", stringify(lvt, 5));
  335. }
  336. // Single piece of advice on before execution of a method with a this and a
  337. // parameter
  338. public void testDebuggingBeforeAdvice_pr262509() throws Exception {
  339. runTest("debugging before advice");
  340. Method method = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "Foo"), "foo");
  341. assertEquals("LFoo; this(0) start=0 len=13", stringify(method.getLocalVariableTable(), 0));
  342. assertEquals("LBar; bar(1) start=0 len=13", stringify(method.getLocalVariableTable(), 1));
  343. }
  344. // Single piece of advice on before execution of a method with a this and a
  345. // parameter and other various locals within it
  346. public void testDebuggingBeforeAdvice_pr262509_2() throws Exception {
  347. // Compile with -preserveAllLocals
  348. runTest("debugging before advice - 2");
  349. Method method = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "Foo2"), "foo");
  350. // System.out.println(stringify(method.getLocalVariableTable()));
  351. List<LocalVariable> l = sortedLocalVariables(method.getLocalVariableTable());
  352. assertEquals("LBar; bar(1) start=0 len=34", stringify(l, 0));
  353. assertEquals("Ljava/lang/Exception; e(3) start=29 len=4", stringify(l, 1));
  354. assertEquals("LFoo2; this(0) start=0 len=34", stringify(l, 4));
  355. assertEquals("Ljava/lang/String; s(2) start=15 len=19", stringify(l, 2));
  356. // With the 1.8 compiler looks like len=7 and not len=10 here, the goto to jump to the return is no longer included
  357. // in the variable range
  358. assertEquals("Ljava/lang/String; s2(3) start=18 len=7", stringify(l, 3));
  359. }
  360. // Two pieces of advice on before execution of a method with a this and a
  361. // parameter and another local within it
  362. public void testDebuggingBeforeAdvice_pr262509_3() throws Exception {
  363. // Compile with -preserveAllLocals
  364. runTest("debugging before advice - 3");
  365. Method method = getMethodFromClass(getClassFrom(ajc.getSandboxDirectory(), "Foo3"), "foo");
  366. System.out.println(stringify(method.getLocalVariableTable()));
  367. assertEquals("LFoo3; this(0) start=0 len=35", stringify(method.getLocalVariableTable(), 0));
  368. assertEquals("LBar; bar(1) start=0 len=35", stringify(method.getLocalVariableTable(), 1));
  369. assertEquals("Ljava/lang/Exception; e(2) start=30 len=4", stringify(method.getLocalVariableTable(), 2));
  370. }
  371. public void testRogueErrors_pr246393_1() {
  372. runTest("rogue errors - 1");
  373. }
  374. // public void testNameClash_pr262257() {
  375. // runTest("name clash");
  376. // fail("incomplete");
  377. // }
  378. public void testCompilingSpring_pr260384() {
  379. runTest("compiling spring");
  380. }
  381. public void testCompilingSpring_pr260384_2() {
  382. runTest("compiling spring - 2");
  383. }
  384. public void testCompilingSpring_pr260384_3() {
  385. runTest("compiling spring - 3");
  386. }
  387. public void testCompilingSpring_pr260384_4() {
  388. runTest("compiling spring - 4");
  389. }
  390. public void testAtAspectJDecp_pr164016() {
  391. runTest("ataspectj decp 164016");
  392. }
  393. public void testAtAspectJDecp_pr258788() {
  394. runTest("ataspectj decp 258788");
  395. }
  396. // ---
  397. public static Test suite() {
  398. return XMLBasedAjcTestCase.loadSuite(Ajc164Tests.class);
  399. }
  400. @Override
  401. protected java.net.URL getSpecFile() {
  402. return getClassResource("ajc164.xml");
  403. }
  404. private IProgramElement findElementAtLine(IProgramElement whereToLook, int line) {
  405. if (whereToLook == null) {
  406. return null;
  407. }
  408. if (whereToLook.getSourceLocation() != null && whereToLook.getSourceLocation().getLine() == line) {
  409. return whereToLook;
  410. }
  411. List<IProgramElement> kids = whereToLook.getChildren();
  412. for (IProgramElement object : kids) {
  413. if (object.getSourceLocation() != null && object.getSourceLocation().getLine() == line) {
  414. return object;
  415. }
  416. IProgramElement gotSomething = findElementAtLine(object, line);
  417. if (gotSomething != null) {
  418. return gotSomething;
  419. }
  420. }
  421. return null;
  422. }
  423. }