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.

JvstTest5.java 25KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591
  1. package javassist;
  2. import java.lang.annotation.Annotation;
  3. import java.lang.reflect.TypeVariable;
  4. import javassist.bytecode.AccessFlag;
  5. import javassist.bytecode.AnnotationsAttribute;
  6. import javassist.bytecode.AttributeInfo;
  7. import javassist.bytecode.ClassFile;
  8. import javassist.bytecode.ConstPool;
  9. import javassist.bytecode.InnerClassesAttribute;
  10. import javassist.bytecode.NestHostAttribute;
  11. import javassist.bytecode.NestMembersAttribute;
  12. import javassist.expr.ExprEditor;
  13. import javassist.expr.Handler;
  14. import javassist.expr.MethodCall;
  15. import javassist.expr.NewExpr;
  16. import junit.framework.Assert;
  17. @SuppressWarnings({"rawtypes","unchecked","unused"})
  18. public class JvstTest5 extends JvstTestRoot {
  19. public JvstTest5(String name) {
  20. super(name);
  21. }
  22. public void testDollarClassInStaticMethod() throws Exception {
  23. CtClass cc = sloader.makeClass("test5.DollarClass");
  24. CtMethod m = CtNewMethod.make("public static int run(){ return $class.getName().length(); }", cc);
  25. cc.addMethod(m);
  26. m = CtNewMethod.make("public int run2(){ return $class.getName().length(); }", cc);
  27. cc.addMethod(m);
  28. cc.writeFile();
  29. Object obj = make(cc.getName());
  30. assertEquals(cc.getName().length(), invoke(obj, "run"));
  31. assertEquals(cc.getName().length(), invoke(obj, "run2"));
  32. }
  33. public void testSuperDefaultMethodCall() throws Exception {
  34. CtClass cc = sloader.get("test5.DefaultMethod");
  35. CtMethod m = CtNewMethod.make("public int run(){ return test5.DefaultMethodIntf.super.foo(); }", cc);
  36. cc.addMethod(m);
  37. m = CtNewMethod.make("public int run2(){ return test5.DefaultMethodIntf.baz(); }", cc);
  38. cc.addMethod(m);
  39. m = CtNewMethod.make("public int run3(){ return test5.DefaultMethodIntf.super.baz(); }", cc);
  40. cc.addMethod(m);
  41. cc.writeFile();
  42. Object obj = make(cc.getName());
  43. assertEquals(1, invoke(obj, "run"));
  44. assertEquals(10, invoke(obj, "run2"));
  45. assertEquals(10, invoke(obj, "run3"));
  46. }
  47. public void testTypeAnno() throws Exception {
  48. CtClass cc = sloader.get("test5.TypeAnno");
  49. cc.getClassFile().compact();
  50. cc.writeFile();
  51. Object obj = make(cc.getName());
  52. TypeVariable<?> t = obj.getClass().getTypeParameters()[0];
  53. Annotation[] annos = t.getAnnotations();
  54. assertEquals("@test5.TypeAnnoA()", annos[0].toString());
  55. }
  56. public void testJIRA241() throws Exception {
  57. CtClass cc = sloader.get("test5.JIRA241");
  58. CtMethod testMethod = cc.getDeclaredMethod("test");
  59. testMethod.insertAfter("System.out.println(\"inserted!\");");
  60. cc.writeFile();
  61. Object obj = make(cc.getName());
  62. assertEquals(10, invoke(obj, "run"));
  63. }
  64. public void testJIRA246() throws Exception {
  65. CtClass ctClass = sloader.makeClass("test5.JIRA246Test");
  66. ctClass.addInterface(sloader.get(test5.JIRA246.Test.class.getName()));
  67. String methodBody = "public void test() { defaultMethod(); }";
  68. CtMethod ctMethod = CtMethod.make(methodBody, ctClass);
  69. ctClass.addMethod(ctMethod);
  70. }
  71. public void testJIRA246b() throws Exception {
  72. CtClass ctClass = sloader.get(test5.JIRA246.A.class.getName());
  73. String src = "public void id() { get(); }";
  74. CtMethod make = CtNewMethod.make(src, ctClass);
  75. }
  76. public void testJIRA242() throws Exception {
  77. Boolean ss = Boolean.valueOf(2 > 3);
  78. ClassPool cp = ClassPool.getDefault();
  79. CtClass cc = cp.get("test5.JIRA242$Hello");
  80. CtMethod m = cc.getDeclaredMethod("say");
  81. m.insertBefore("{ System.out.println(\"Say Hello...\"); }");
  82. StringBuilder sb = new StringBuilder();
  83. sb.append("BOOL_SERIES = createBooleanSeriesStep();");
  84. //Below code cause the issue
  85. sb.append("BOOL_SERIES.setValue(3>=3);"); //lets comment this and run it will work
  86. // Below code snippets will work
  87. // this cast into exact class and call the same function
  88. sb.append("((test5.JIRA242$BooleanDataSeries)BOOL_SERIES).setValue(3>=3);");
  89. // this code snippet will set exact boolean variable to the function.
  90. sb.append("boolean var = 3>=3;");
  91. sb.append("BOOL_SERIES.setValue(var);");
  92. m.insertBefore(sb.toString());
  93. cc.writeFile();
  94. Object obj = make(cc.getName());
  95. assertEquals(0, invoke(obj, "say"));
  96. }
  97. public void testJIRA249() throws Exception {
  98. CtClass cc = sloader.get("test5.BoolTest");
  99. CtMethod testMethod = cc.getDeclaredMethod("test");
  100. testMethod.insertBefore("i = foo(true & true);");
  101. cc.writeFile();
  102. Object obj = make(cc.getName());
  103. assertEquals(1, invoke(obj, "run"));
  104. }
  105. public void testInnerClassAttributeRemove() throws Exception {
  106. CtClass cc = sloader.get("test5.InnerClassRemove");
  107. ClassFile cf = cc.getClassFile();
  108. InnerClassesAttribute ica = (InnerClassesAttribute)cf.getAttribute(InnerClassesAttribute.tag);
  109. String second = ica.innerClass(1);
  110. String secondName = ica.innerName(1);
  111. String third = ica.innerClass(2);
  112. String thirdName = ica.innerName(2);
  113. assertEquals(3, ica.remove(3));
  114. assertEquals(2, ica.remove(0));
  115. assertEquals(second, ica.innerClass(0));
  116. assertEquals(secondName, ica.innerName(0));
  117. assertEquals(third, ica.innerClass(1));
  118. assertEquals(thirdName, ica.innerName(1));
  119. assertEquals(1, ica.remove(1));
  120. assertEquals(second, ica.innerClass(0));
  121. assertEquals(secondName, ica.innerName(0));
  122. cc.writeFile();
  123. Object obj = make(cc.getName());
  124. assertEquals(1, invoke(obj, "run"));
  125. }
  126. public void testJIRA248() throws Exception {
  127. CtClass cc = sloader.get("test5.JIRA248");
  128. String methodBody = "public int run() { return foo() + super.foo() + super.bar() + test5.JIRA248Intf2.super.baz(); }";
  129. CtMethod ctMethod = CtMethod.make(methodBody, cc);
  130. cc.addMethod(ctMethod);
  131. cc.writeFile();
  132. Object obj = make(cc.getName());
  133. assertEquals(40271, invoke(obj, "run"));
  134. }
  135. public void testInvalidCastWithDollar() throws Exception {
  136. String code = "{ new test5.JavassistInvalidCastTest().inspectReturn((Object) ($w) $_); } ";
  137. CtClass c = sloader.get("test5.InvalidCastDollar");
  138. for (CtMethod method : c.getDeclaredMethods())
  139. method.insertAfter(code);
  140. }
  141. public void testJIRA256() throws Exception {
  142. // CtClass ec = sloader.get("test5.Entity");
  143. CtClass cc = sloader.makeClass("test5.JIRA256");
  144. ClassFile ccFile = cc.getClassFile();
  145. ConstPool constpool = ccFile.getConstPool();
  146. AnnotationsAttribute attr = new AnnotationsAttribute(constpool, AnnotationsAttribute.visibleTag);
  147. javassist.bytecode.annotation.Annotation entityAnno
  148. = new javassist.bytecode.annotation.Annotation("test5.Entity", constpool);
  149. // = new javassist.bytecode.annotation.Annotation(constpool, ec);
  150. entityAnno.addMemberValue("value", new javassist.bytecode.annotation.ArrayMemberValue(constpool));
  151. attr.addAnnotation(entityAnno);
  152. ccFile.addAttribute(attr);
  153. cc.writeFile();
  154. Object o = make(cc.getName());
  155. assertTrue(o.getClass().getName().equals("test5.JIRA256"));
  156. java.lang.annotation.Annotation[] annotations = o.getClass().getDeclaredAnnotations();
  157. assertEquals(1, annotations.length);
  158. }
  159. public void testJIRA250() throws Exception {
  160. CtClass cc = sloader.makeClass("test5.JIRA250", sloader.get("test5.JIRA250Super"));
  161. cc.addMethod(CtNewMethod.make(
  162. " public test5.JIRA250Bar getBar() {" +
  163. " return super.getBar();\n" +
  164. " }\n", cc));
  165. cc.addMethod(CtNewMethod.make("public int run() { getBar(); return 1; }", cc));
  166. cc.writeFile();
  167. Object obj = make(cc.getName());
  168. assertEquals(1, invoke(obj, "run"));
  169. }
  170. public void testProceedToDefaultMethod() throws Exception {
  171. CtClass cc = ClassPool.getDefault().get("test5.ProceedDefault");
  172. CtMethod mth = cc.getDeclaredMethod("bar");
  173. mth.instrument(new ExprEditor() {
  174. public void edit(MethodCall c) throws CannotCompileException {
  175. c.replace("$_ = $proceed($$) + 10000;");
  176. }
  177. });
  178. cc.writeFile();
  179. Object obj = make(cc.getName());
  180. assertEquals(21713, invoke(obj, "run"));
  181. }
  182. public void testBadClass() throws Exception {
  183. CtClass badClass = ClassPool.getDefault().makeClass("badClass");
  184. String src = String.join(System.getProperty("line.separator"),
  185. "public void eval () {",
  186. " if (true) {",
  187. " double t=0;",
  188. " } else {",
  189. " double t=0;",
  190. " }",
  191. " for (int i=0; i < 2; i++) {",
  192. " int a=0;",
  193. " int b=0;",
  194. " int c=0;",
  195. " int d=0;",
  196. " if (true) {",
  197. " int e = 0;",
  198. " }",
  199. " }",
  200. "}");
  201. System.out.println(src);
  202. badClass.addMethod(CtMethod.make(src, badClass));
  203. Class clazzz = badClass.toClass(Class.forName("DefineClassCapability"));
  204. Object obj = clazzz.getConstructor().newInstance(); // <-- falls here
  205. }
  206. public void test83StackmapWithArrayType() throws Exception {
  207. final CtClass ctClass = sloader.get("test5.StackmapWithArray83");
  208. final CtMethod method = ctClass.getDeclaredMethod("bytecodeVerifyError");
  209. method.addLocalVariable("test_localVariable", CtClass.intType);
  210. method.insertBefore("{ test_localVariable = 1; }");
  211. final CtMethod method2 = ctClass.getDeclaredMethod("bytecodeVerifyError2");
  212. method2.addLocalVariable("test_localVariable", CtClass.intType);
  213. method2.insertBefore("{ test_localVariable = 1; }");
  214. ctClass.writeFile();
  215. Object obj = make(ctClass.getName());
  216. assertEquals(1, invoke(obj, "run"));
  217. }
  218. public void testLoaderClassPath() throws Exception {
  219. ClassPool cp = new ClassPool();
  220. cp.appendClassPath(new LoaderClassPath(new Loader()));
  221. assertNotNull(cp.get(Object.class.getName()));
  222. assertNotNull(cp.get(this.getClass().getName()));
  223. }
  224. public void testAddDefaultMethod() throws Exception {
  225. CtClass cc = sloader.makeInterface("test5.AddDefaultMethod");
  226. cc.addMethod(CtNewMethod.make("static int foo() { return 1; }", cc));
  227. cc.addMethod(CtNewMethod.make("public static int foo1() { return 1; }", cc));
  228. cc.addMethod(CtNewMethod.make("public int foo2() { return 1; }", cc));
  229. cc.addMethod(CtNewMethod.make("int foo3() { return 1; }", cc));
  230. try {
  231. cc.addMethod(CtNewMethod.make("private int foo4() { return 1; }", cc));
  232. fail();
  233. } catch (CannotCompileException e) {}
  234. try {
  235. cc.addMethod(CtNewMethod.make("private static int foo5() { return 1; }", cc));
  236. fail();
  237. } catch (CannotCompileException e) {}
  238. }
  239. public void testRemoveAnnotatino() throws Exception {
  240. CtClass cc = sloader.get("test5.RemoveAnnotation");
  241. AnnotationsAttribute aa
  242. = (AnnotationsAttribute)cc.getClassFile().getAttribute(AnnotationsAttribute.invisibleTag);
  243. assertTrue(aa.removeAnnotation("test5.RemoveAnno1"));
  244. AttributeInfo ai = cc.getClassFile().removeAttribute(AnnotationsAttribute.invisibleTag);
  245. assertEquals(ai.getName(), AnnotationsAttribute.invisibleTag);
  246. CtMethod foo = cc.getDeclaredMethod("foo");
  247. AnnotationsAttribute aa2 = (AnnotationsAttribute)foo.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
  248. assertTrue(aa2.removeAnnotation("test5.RemoveAnno1"));
  249. CtMethod bar = cc.getDeclaredMethod("bar");
  250. AnnotationsAttribute aa3 = (AnnotationsAttribute)bar.getMethodInfo().getAttribute(AnnotationsAttribute.invisibleTag);
  251. assertFalse(aa3.removeAnnotation("test5.RemoveAnno1"));
  252. assertTrue(aa3.removeAnnotation("test5.RemoveAnno2"));
  253. AttributeInfo ai2 = bar.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  254. assertEquals(ai2.getName(), AnnotationsAttribute.invisibleTag);
  255. CtMethod run = cc.getDeclaredMethod("run");
  256. AttributeInfo ai3 = run.getMethodInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  257. assertNull(ai3);
  258. CtField baz = cc.getDeclaredField("baz");
  259. AttributeInfo ai4 = baz.getFieldInfo().removeAttribute(AnnotationsAttribute.invisibleTag);
  260. assertEquals(ai4.getName(), AnnotationsAttribute.invisibleTag);
  261. cc.writeFile();
  262. Object obj = make(cc.getName());
  263. assertEquals(3, invoke(obj, "run"));
  264. }
  265. public void testInnerClassModifiers() throws Exception {
  266. CtClass cc = sloader.get("test5.InnerModifier$NonStatic");
  267. try {
  268. cc.setModifiers(Modifier.PUBLIC | Modifier.STATIC);
  269. fail();
  270. }
  271. catch (RuntimeException e) {
  272. if (!e.getMessage().startsWith("cannot change "))
  273. fail();
  274. }
  275. cc.setModifiers(Modifier.PUBLIC);
  276. cc.writeFile();
  277. assertEquals(Modifier.PUBLIC, cc.getModifiers());
  278. InnerClassesAttribute ica = getInnerClassAttr(cc);
  279. int i = ica.find("test5.InnerModifier$NonStatic");
  280. assertTrue(i >= 0);
  281. assertEquals(Modifier.PUBLIC, ica.accessFlags(i));
  282. CtClass cc2 = sloader.get("test5.InnerModifier$Static");
  283. InnerClassesAttribute ica3 = getInnerClassAttr(cc2);
  284. int i3 = ica3.find("test5.InnerModifier$Static");
  285. assertTrue(i3 >= 0);
  286. assertEquals(AccessFlag.STATIC, ica3.accessFlags(i3));
  287. cc2.setModifiers(Modifier.PROTECTED | Modifier.STATIC);
  288. cc2.setModifiers(Modifier.PUBLIC);
  289. cc2.writeFile();
  290. assertEquals(Modifier.PUBLIC | Modifier.STATIC, cc2.getModifiers());
  291. InnerClassesAttribute ica2 = getInnerClassAttr(cc2);
  292. int i2 = ica2.find("test5.InnerModifier$Static");
  293. assertTrue(i2 >= 0);
  294. assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica2.accessFlags(i2));
  295. CtClass cc3 = cc.getDeclaringClass();
  296. assertTrue(cc3.isModified());
  297. cc3.writeFile();
  298. InnerClassesAttribute ica4 = getInnerClassAttr(cc3);
  299. int i4 = ica4.find("test5.InnerModifier$Static");
  300. assertTrue(i4 >= 0);
  301. assertEquals(AccessFlag.PUBLIC | AccessFlag.STATIC, ica4.accessFlags(i4));
  302. int i5 = ica4.find("test5.InnerModifier$NonStatic");
  303. assertTrue(i5 >= 0);
  304. assertEquals(Modifier.PUBLIC, ica4.accessFlags(i5));
  305. }
  306. public void testInnerClassModifiers2() throws Exception {
  307. CtClass cc = sloader.get("test5.InnerModifier2$Protected");
  308. Class<?> ccc = Class.forName("test5.InnerModifier2$Protected");
  309. assertEquals(cc.getModifiers(), ccc.getModifiers());
  310. assertTrue(Modifier.isProtected(cc.getModifiers()));
  311. cc = sloader.get("test5.InnerModifier2$Public");
  312. ccc = Class.forName("test5.InnerModifier2$Public");
  313. assertEquals(cc.getModifiers(), ccc.getModifiers());
  314. assertTrue(Modifier.isPublic(cc.getModifiers()));
  315. cc = sloader.get("test5.InnerModifier2$Private");
  316. ccc = Class.forName("test5.InnerModifier2$Private");
  317. assertEquals(cc.getModifiers(), ccc.getModifiers());
  318. assertTrue(Modifier.isPrivate(cc.getModifiers()));
  319. cc = sloader.get("test5.InnerModifier2$Package");
  320. ccc = Class.forName("test5.InnerModifier2$Package");
  321. assertEquals(cc.getModifiers(), ccc.getModifiers());
  322. assertTrue(Modifier.isPackage(cc.getModifiers()));
  323. cc = sloader.get("test5.InnerModifier2$ProtectedStatic");
  324. ccc = Class.forName("test5.InnerModifier2$ProtectedStatic");
  325. assertEquals(cc.getModifiers(), ccc.getModifiers());
  326. assertTrue(Modifier.isProtected(cc.getModifiers()));
  327. assertTrue(Modifier.isStatic(cc.getModifiers()));
  328. cc = sloader.get("test5.InnerModifier2$PublicStatic");
  329. ccc = Class.forName("test5.InnerModifier2$PublicStatic");
  330. assertEquals(cc.getModifiers(), ccc.getModifiers());
  331. assertTrue(Modifier.isPublic(cc.getModifiers()));
  332. assertTrue(Modifier.isStatic(cc.getModifiers()));
  333. cc = sloader.get("test5.InnerModifier2$PrivateStatic");
  334. ccc = Class.forName("test5.InnerModifier2$PrivateStatic");
  335. assertEquals(cc.getModifiers(), ccc.getModifiers());
  336. assertTrue(Modifier.isPrivate(cc.getModifiers()));
  337. assertTrue(Modifier.isStatic(cc.getModifiers()));
  338. cc = sloader.get("test5.InnerModifier2$PackageStatic");
  339. ccc = Class.forName("test5.InnerModifier2$PackageStatic");
  340. assertEquals(cc.getModifiers(), ccc.getModifiers());
  341. assertTrue(Modifier.isPackage(cc.getModifiers()));
  342. assertTrue(Modifier.isStatic(cc.getModifiers()));
  343. }
  344. private InnerClassesAttribute getInnerClassAttr(CtClass cc) {
  345. return (InnerClassesAttribute)cc.getClassFile2().getAttribute(InnerClassesAttribute.tag);
  346. }
  347. public void testVarArgsModifier() throws Exception {
  348. CtClass cc = sloader.get("test5.VarArgsMethod");
  349. assertTrue(Modifier.isVarArgs(cc.getDeclaredMethod("foo").getModifiers()));
  350. assertFalse(Modifier.isVarArgs(cc.getDeclaredMethod("bar").getModifiers()));
  351. }
  352. public void testIssue155() throws Exception {
  353. CtClass cc = sloader.get("test5.Issue155");
  354. CtMethod testMethod = cc.getDeclaredMethod("foo");
  355. testMethod.instrument(
  356. new ExprEditor() {
  357. public void edit(Handler m)
  358. throws CannotCompileException {
  359. m.insertBefore("throw $1;");
  360. }
  361. });
  362. cc.writeFile();
  363. Object obj = make(cc.getName());
  364. assertEquals(1, invoke(obj, "test"));
  365. }
  366. public void testNestHostAttribute() throws Exception {
  367. CtClass cc = sloader.get("test5.NestHost$Foo");
  368. ClassFile cf = cc.getClassFile();
  369. NestHostAttribute attr = (NestHostAttribute)cf.getAttribute(NestHostAttribute.tag);
  370. assertEquals(test5.NestHost.class.getName(),
  371. cf.getConstPool().getClassInfo(attr.hostClassIndex()));
  372. }
  373. public void testNestMembersAttribute() throws Exception {
  374. CtClass cc = sloader.get("test5.NestHost");
  375. ClassFile cf = cc.getClassFile();
  376. NestMembersAttribute attr = (NestMembersAttribute)cf.getAttribute(NestMembersAttribute.tag);
  377. assertEquals(2, attr.numberOfClasses());
  378. String[] names = new String[2];
  379. for (int i = 0; i < 2; i++)
  380. names[i] = cf.getConstPool().getClassInfo(attr.memberClass(i));
  381. assertFalse(names[0].equals(names[1]));
  382. assertTrue(names[0].equals("test5.NestHost$Foo") || names[0].equals("test5.NestHost$Bar"));
  383. assertTrue(names[1].equals("test5.NestHost$Foo") || names[1].equals("test5.NestHost$Bar"));
  384. }
  385. public void testNestMembersAttributeCopy() throws Exception {
  386. CtClass cc = sloader.get("test5.NestHost2");
  387. cc.getClassFile().compact();
  388. cc.writeFile();
  389. make(cc.getName());
  390. }
  391. public void testNestHostAttributeCopy() throws Exception {
  392. CtClass cc = sloader.get("test5.NestHost2$Foo");
  393. cc.getClassFile().compact();
  394. cc.toClass(test5.DefineClassCapability.class);
  395. }
  396. public void testSwitchCaseWithStringConstant() throws Exception {
  397. CtClass cc = sloader.get("test5.SwitchCase");
  398. cc.addMethod(CtNewMethod.make(
  399. "public int run() {" +
  400. " String s = \"foobar\";\n" +
  401. " switch (s) {\n" +
  402. " case STR1: return 1;\n" +
  403. " case \"foobar\": return 2;\n" +
  404. " default: return 3; }\n" +
  405. "}\n", cc));
  406. cc.writeFile();
  407. Object obj = make(cc.getName());
  408. assertEquals(2, invoke(obj, "run"));
  409. }
  410. public void testNestPrivateConstructor() throws Exception {
  411. CtClass cc = sloader.get("test5.NestHost3$Builder");
  412. cc.instrument(new ExprEditor() {
  413. public void edit(NewExpr e) throws CannotCompileException {
  414. String code = "$_ = $proceed($$);";
  415. e.replace(code);
  416. }
  417. });
  418. cc.writeFile();
  419. try {
  420. Class<?> nestHost3Class = cloader.loadClass("test5.NestHost3");
  421. Object builder = nestHost3Class.getDeclaredMethod("builder").invoke(nestHost3Class);
  422. Class<?> nestHost3BuilderClass = cloader.loadClass("test5.NestHost3$Builder");
  423. nestHost3BuilderClass.getDeclaredMethod("build").invoke(builder);
  424. } catch (Exception ex) {
  425. ex.printStackTrace();
  426. fail("it should be able to access the private constructor of the nest host");
  427. }
  428. }
  429. public void testNestPrivateConstructor2() throws Exception {
  430. CtClass cc = sloader.get("test5.NestHost4$InnerClass1");
  431. cc.instrument(new ExprEditor() {
  432. public void edit(NewExpr e) throws CannotCompileException {
  433. String code = "$_ = $proceed($$);";
  434. e.replace(code);
  435. }
  436. });
  437. cc.writeFile();
  438. cc = sloader.get("test5.NestHost4$InnerClass1$InnerClass5");
  439. cc.instrument(new ExprEditor() {
  440. public void edit(NewExpr e) throws CannotCompileException {
  441. String code = "$_ = $proceed($$);";
  442. e.replace(code);
  443. }
  444. });
  445. cc.writeFile();
  446. try {
  447. Class<?> nestHost4Class = cloader.loadClass("test5.NestHost4");
  448. nestHost4Class.getDeclaredConstructor().newInstance();
  449. } catch (Exception ex) {
  450. ex.printStackTrace();
  451. fail("it should be able to access the private constructor of the nest host");
  452. }
  453. }
  454. public void testSwitchCaseWithStringConstant2() throws Exception {
  455. CtClass cc = sloader.makeClass("test5.SwitchCase2");
  456. cc.addMethod(CtNewMethod.make(
  457. "public int run() {" +
  458. " String s = \"foo\";\n" +
  459. " switch (s) {\n" +
  460. " case test5.SwitchCase.STR1: return 1;\n" +
  461. " case \"foobar\": return 2;\n" +
  462. " }\n" +
  463. " return 3;\n" +
  464. "}\n", cc));
  465. cc.writeFile();
  466. Object obj = make(cc.getName());
  467. assertEquals(1, invoke(obj, "run"));
  468. }
  469. // Issue #241
  470. public void testInsertBeforeAndDollarR() throws Exception {
  471. CtClass cc = sloader.get(test5.InsertBeforeDollarR.class.getName());
  472. CtMethod m = cc.getDeclaredMethod("foo");
  473. m.insertBefore("{ if ($1 == 1) return ($r)$2; }");
  474. try {
  475. m.insertBefore("{ $_ = \"bar\"; }");
  476. assertTrue(false);
  477. } catch (CannotCompileException e) {}
  478. cc.writeFile();
  479. Object obj = make(cc.getName());
  480. assertEquals(1, invoke(obj, "run"));
  481. }
  482. // Issue #275
  483. public void testRedundantInsertAfter() throws Exception {
  484. CtClass cc = sloader.get(test5.InsertAfter.class.getName());
  485. CtMethod m = cc.getDeclaredMethod("foo");
  486. m.insertAfter("{ $_ += 1; }", false, true);
  487. CtMethod m2 = cc.getDeclaredMethod("bar");
  488. m2.insertAfter("{ $_ += 1; }", true, true);
  489. cc.writeFile();
  490. Object obj = make(cc.getName());
  491. assertEquals(71 + 22, invoke(obj, "run"));
  492. }
  493. // PR #294
  494. public void testEmptyArrayInit() throws Exception {
  495. CtClass cc = sloader.makeClass("test5.EmptyArrayInit");
  496. CtMethod m = CtNewMethod.make("public int[] foo(){ int[] a = {}; return a; }", cc);
  497. cc.addMethod(m);
  498. CtMethod m2 = CtNewMethod.make("public int[] bar(){ int[] a = new int[]{}; return a; }", cc);
  499. cc.addMethod(m2);
  500. CtMethod m3 = CtNewMethod.make("public String[] baz(){ String[] a = { null }; return a; }", cc);
  501. cc.addMethod(m3);
  502. CtMethod m0 = CtNewMethod.make("public int run() { return foo().length + bar().length + baz().length; }", cc);
  503. cc.addMethod(m0);
  504. cc.writeFile();
  505. Object obj = make(cc.getName());
  506. assertEquals(1, invoke(obj, "run"));
  507. }
  508. public void testTooManyConstPoolItems() throws Exception {
  509. CtClass cc = sloader.makeClass("TooManyConstPoolItems");
  510. ClassFile cf = cc.getClassFile();
  511. ConstPool cPool = cf.getConstPool();
  512. for (int i = 0; i <= 65527; i++)
  513. cPool.addIntegerInfo(i);
  514. try {
  515. cc.writeFile();
  516. fail("too many items were accepted");
  517. }
  518. catch (CannotCompileException e) {}
  519. }
  520. }