diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 6963f1d..c529a44 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -65,9 +65,9 @@ public class NestedClassProcessor { int nameless = 0, synthetics = 0; for (ClassNode child : node.nested) { + StructClass cl = child.classStruct; // ensure not-empty class name if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_MEMBER) && child.simpleName == null) { - StructClass cl = child.classStruct; if ((child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) { child.simpleName = "SyntheticClass_" + (++synthetics); } @@ -78,6 +78,9 @@ public class NestedClassProcessor { } child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0; } + else if (child.type == ClassNode.CLASS_ANONYMOUS && (child.access & CodeConstants.ACC_SYNTHETIC) != 0 || cl.isSynthetic()) { + child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0; + } } for (ClassNode child : node.nested) { @@ -180,10 +183,14 @@ public class NestedClassProcessor { List copy = new ArrayList(node.nested); for (ClassNode child : copy) { + if (child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + continue; + } + if ((child.type == ClassNode.CLASS_LOCAL || child.type == ClassNode.CLASS_ANONYMOUS) && child.enclosingMethod == null) { Set setEnclosing = child.enclosingClasses; - if (setEnclosing.size() == 1) { + if (!setEnclosing.isEmpty()) { StructEnclosingMethodAttribute attr = (StructEnclosingMethodAttribute)child.classStruct.getAttributes().getWithKey("EnclosingMethod"); if (attr != null && @@ -199,17 +206,12 @@ public class NestedClassProcessor { child.parent = null; setEnclosing.remove(node.classStruct.qualifiedName); - boolean hasEnclosing = !setEnclosing.isEmpty(); - if (hasEnclosing) { - hasEnclosing = insertNestedClass(root, child); - } + boolean hasEnclosing = !setEnclosing.isEmpty() && insertNestedClass(root, child); if (!hasEnclosing) { if (child.type == ClassNode.CLASS_ANONYMOUS) { - if (!child.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } + String message = "Unreferenced anonymous class " + child.classStruct.qualifiedName + "!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } else if (child.type == ClassNode.CLASS_LOCAL) { String message = "Unreferenced local class " + child.classStruct.qualifiedName + "!"; @@ -251,6 +253,10 @@ public class NestedClassProcessor { int clTypes = 0; for (ClassNode nd : node.nested) { + if (nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { + continue; + } + if (nd.type != ClassNode.CLASS_LAMBDA && (nd.access & CodeConstants.ACC_STATIC) == 0 && (nd.access & CodeConstants.ACC_INTERFACE) == 0) { @@ -258,10 +264,8 @@ public class NestedClassProcessor { Map> mask = getMaskLocalVars(nd.getWrapper()); if (mask.isEmpty()) { - if (!nd.classStruct.hasModifier(CodeConstants.ACC_SYNTHETIC)) { - String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; - DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); - } + String message = "Nested class " + nd.classStruct.qualifiedName + " has no constructor!"; + DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); } else { mapVarMasks.put(nd.classStruct.qualifiedName, mask); diff --git a/testData/classes/pkg/TestInnerClassConstructor$1.class b/testData/classes/pkg/TestInnerClassConstructor$1.class index 384ce5d..07172b9 100644 Binary files a/testData/classes/pkg/TestInnerClassConstructor$1.class and b/testData/classes/pkg/TestInnerClassConstructor$1.class differ diff --git a/testData/classes/pkg/TestInnerClassConstructor$Another.class b/testData/classes/pkg/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000..5178a8f Binary files /dev/null and b/testData/classes/pkg/TestInnerClassConstructor$Another.class differ diff --git a/testData/classes/pkg/TestInnerClassConstructor$Inner.class b/testData/classes/pkg/TestInnerClassConstructor$Inner.class index 37e9262..460cc7f 100644 Binary files a/testData/classes/pkg/TestInnerClassConstructor$Inner.class and b/testData/classes/pkg/TestInnerClassConstructor$Inner.class differ diff --git a/testData/classes/pkg/TestInnerClassConstructor.class b/testData/classes/pkg/TestInnerClassConstructor.class index fb0d898..6a48109 100644 Binary files a/testData/classes/pkg/TestInnerClassConstructor.class and b/testData/classes/pkg/TestInnerClassConstructor.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor$1.class b/testData/classes/v11/TestInnerClassConstructor$1.class index b11a30e..fad6e4e 100644 Binary files a/testData/classes/v11/TestInnerClassConstructor$1.class and b/testData/classes/v11/TestInnerClassConstructor$1.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor$Another.class b/testData/classes/v11/TestInnerClassConstructor$Another.class new file mode 100644 index 0000000..61d71db Binary files /dev/null and b/testData/classes/v11/TestInnerClassConstructor$Another.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor$Inner.class b/testData/classes/v11/TestInnerClassConstructor$Inner.class index 81face1..906b571 100644 Binary files a/testData/classes/v11/TestInnerClassConstructor$Inner.class and b/testData/classes/v11/TestInnerClassConstructor$Inner.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor.class b/testData/classes/v11/TestInnerClassConstructor.class index 9cbad7f..b203edf 100644 Binary files a/testData/classes/v11/TestInnerClassConstructor.class and b/testData/classes/v11/TestInnerClassConstructor.class differ diff --git a/testData/results/TestInnerClassConstructor.dec b/testData/results/TestInnerClassConstructor.dec index 235d50f..f15701a 100644 --- a/testData/results/TestInnerClassConstructor.dec +++ b/testData/results/TestInnerClassConstructor.dec @@ -1,40 +1,65 @@ package pkg; class TestInnerClassConstructor { - void m() { + void l() { new TestInnerClassConstructor.Inner("text");// 5 }// 6 - void n(String var1) { - System.out.println("n(): " + var1);// 9 + void m() { + new TestInnerClassConstructor.Another(3, 4);// 9 }// 10 + void n(String var1) { + System.out.println("n(): " + var1);// 13 + }// 14 + + private class Another { + private Another(int var2, int var3) { + TestInnerClassConstructor.this.n(var2 + "+" + var3);// 24 + }// 25 + } + final class Inner { private Inner(String var2) { - TestInnerClassConstructor.this.n(var2);// 14 - }// 15 + TestInnerClassConstructor.this.n(var2);// 18 + }// 19 } } class 'pkg/TestInnerClassConstructor' { - method 'm ()V' { + method 'l ()V' { 5 4 c 5 } + method 'm ()V' { + 5 8 + 6 8 + c 9 + } + method 'n (Ljava/lang/String;)V' { - 0 8 - a 8 - 13 8 - 16 8 - 19 9 + 0 12 + a 12 + 13 12 + 16 12 + 19 13 + } +} + +class 'pkg/TestInnerClassConstructor$Another' { + method ' (Lpkg/TestInnerClassConstructor;II)V' { + 15 17 + 1e 17 + 21 17 + 24 18 } } class 'pkg/TestInnerClassConstructor$Inner' { method ' (Lpkg/TestInnerClassConstructor;Ljava/lang/String;)V' { - b 13 - e 14 + b 23 + e 24 } } @@ -43,7 +68,12 @@ Lines mapping: 6 <-> 6 9 <-> 9 10 <-> 10 +13 <-> 13 14 <-> 14 -15 <-> 15 +18 <-> 24 +19 <-> 25 +24 <-> 18 +25 <-> 19 Not mapped: -13 +17 +23 diff --git a/testData/src/pkg/TestInnerClassConstructor.java b/testData/src/pkg/TestInnerClassConstructor.java index e42c319..ccc33ff 100644 --- a/testData/src/pkg/TestInnerClassConstructor.java +++ b/testData/src/pkg/TestInnerClassConstructor.java @@ -1,10 +1,14 @@ package pkg; class TestInnerClassConstructor { - void m() { + void l() { new Inner("text"); } + void m() { + new Another(3, 4); + } + void n(String s) { System.out.println("n(): " + s); } @@ -14,4 +18,10 @@ class TestInnerClassConstructor { n(s); } } + + private class Another { + private Another(int a, int b) { + n(a + "+" + b); + } + } }