Fix #265 javassist.CannotCompileException: [source error] the called …tags/rel_3_26_0_ga
@@ -619,6 +619,18 @@ public class MemberCodeGen extends CodeGen { | |||
aload0pos, found); | |||
} | |||
private boolean isFromSameDeclaringClass(CtClass outer, CtClass inner) { | |||
try { | |||
while (outer != null) { | |||
if (isEnclosing(outer, inner)) | |||
return true; | |||
outer = outer.getDeclaringClass(); | |||
} | |||
} | |||
catch (NotFoundException e) {} | |||
return false; | |||
} | |||
private void atMethodCallCore2(CtClass targetClass, String mname, | |||
boolean isStatic, boolean isSpecial, | |||
int aload0pos, | |||
@@ -636,19 +648,8 @@ public class MemberCodeGen extends CodeGen { | |||
throw new CompileError("no such constructor: " + targetClass.getName()); | |||
if (declClass != thisClass && AccessFlag.isPrivate(acc)) { | |||
boolean isNested = false; | |||
if (declClass.getClassFile().getMajorVersion() >= ClassFile.JAVA_11) { | |||
try { | |||
CtClass[] nestedClasses = declClass.getNestedClasses(); | |||
for (int i = 0; i < nestedClasses.length; i++) { | |||
if (thisClass == nestedClasses[i]) { | |||
isNested = true; | |||
break; | |||
} | |||
} | |||
} catch (NotFoundException ignored) { } | |||
} | |||
if (!isNested) { | |||
if (declClass.getClassFile().getMajorVersion() < ClassFile.JAVA_11 | |||
|| !isFromSameDeclaringClass(declClass, thisClass)) { | |||
desc = getAccessibleConstructor(desc, declClass, minfo); | |||
bytecode.addOpcode(Opcode.ACONST_NULL); // the last parameter | |||
} |
@@ -490,6 +490,33 @@ public class JvstTest5 extends JvstTestRoot { | |||
} | |||
} | |||
public void testNestPrivateConstructor2() throws Exception { | |||
CtClass cc = sloader.get("test5.NestHost4$InnerClass1"); | |||
cc.instrument(new ExprEditor() { | |||
public void edit(NewExpr e) throws CannotCompileException { | |||
String code = "$_ = $proceed($$);"; | |||
e.replace(code); | |||
} | |||
}); | |||
cc.writeFile(); | |||
cc = sloader.get("test5.NestHost4$InnerClass1$InnerClass5"); | |||
cc.instrument(new ExprEditor() { | |||
public void edit(NewExpr e) throws CannotCompileException { | |||
String code = "$_ = $proceed($$);"; | |||
e.replace(code); | |||
} | |||
}); | |||
cc.writeFile(); | |||
try { | |||
Class<?> nestHost4Class = cloader.loadClass("test5.NestHost4"); | |||
nestHost4Class.getDeclaredConstructor().newInstance(); | |||
} catch (Exception ex) { | |||
ex.printStackTrace(); | |||
fail("it should be able to access the private constructor of the nest host"); | |||
} | |||
} | |||
public void testSwitchCaseWithStringConstant2() throws Exception { | |||
CtClass cc = sloader.makeClass("test5.SwitchCase2"); | |||
cc.addMethod(CtNewMethod.make( |
@@ -0,0 +1,26 @@ | |||
package test5; | |||
public class NestHost4 { | |||
public void test() { | |||
new InnerClass1().new InnerClass5(); | |||
} | |||
private class InnerClass1 { | |||
private InnerClass1() { | |||
new InnerClass2(); | |||
} | |||
private class InnerClass5 { | |||
private InnerClass5() { | |||
new InnerClass2().new InnerClass3(); | |||
} | |||
} | |||
} | |||
private class InnerClass2 { | |||
private class InnerClass3 { | |||
} | |||
} | |||
} |