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,
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
}
}
}
+ 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(
--- /dev/null
+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 {
+
+ }
+ }
+}