diff --git a/src/org/jetbrains/java/decompiler/main/ClassWriter.java b/src/org/jetbrains/java/decompiler/main/ClassWriter.java index 6de5933..9a1e7aa 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassWriter.java +++ b/src/org/jetbrains/java/decompiler/main/ClassWriter.java @@ -250,7 +250,7 @@ public class ClassWriter { for (ClassNode inner : node.nested) { if (inner.type == ClassNode.CLASS_MEMBER) { StructClass innerCl = inner.classStruct; - boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic(); + boolean isSynthetic = (inner.access & CodeConstants.ACC_SYNTHETIC) != 0 || innerCl.isSynthetic() || inner.namelessConstructorStub; boolean hide = isSynthetic && DecompilerContext.getOption(IFernflowerPreferences.REMOVE_SYNTHETIC) || wrapper.getHiddenMembers().contains(innerCl.qualifiedName); if (hide) continue; diff --git a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java index 32470e0..458ed55 100644 --- a/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/ClassesProcessor.java @@ -359,6 +359,7 @@ public class ClassesProcessor { public Set enclosingClasses = new HashSet(); public ClassNode parent; public LambdaInformation lambdaInformation; + public boolean namelessConstructorStub = false; public ClassNode(String content_class_name, String content_method_name, diff --git a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java index 6218319..0858e80 100644 --- a/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java +++ b/src/org/jetbrains/java/decompiler/main/rels/NestedClassProcessor.java @@ -79,6 +79,7 @@ public class NestedClassProcessor { DecompilerContext.getLogger().writeMessage(message, IFernflowerLogger.Severity.WARN); child.simpleName = "NamelessClass_" + (++nameless); } + child.namelessConstructorStub = !cl.hasModifier(CodeConstants.ACC_STATIC) && cl.getMethods().size() + cl.getFields().size() == 0; } } diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java index 4fa62c6..543c0ad 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -311,20 +311,31 @@ public class NewExprent extends Exprent { if (!enumconst || start < lstParameters.size()) { buf.append("("); - boolean firstpar = true; + boolean firstParam = true; for (int i = start; i < lstParameters.size(); i++) { if (sigFields == null || sigFields.get(i) == null) { - if (!firstpar) { + Exprent expr = lstParameters.get(i); + VarType leftType = constructor.getDescriptor().params[i]; + + if (i == lstParameters.size() - 1 && expr.getExprType() == VarType.VARTYPE_NULL) { + ClassNode node = DecompilerContext.getClassProcessor().getMapRootClasses().get(leftType.value); + if (node != null && node.namelessConstructorStub) { + break; // skip last parameter of synthetic constructor call + } + } + + if (!firstParam) { buf.append(", "); } TextBuffer buff = new TextBuffer(); - ExprProcessor.getCastedExprent(lstParameters.get(i), constructor.getDescriptor().params[i], buff, indent, true, tracer); - + ExprProcessor.getCastedExprent(expr, leftType, buff, indent, true, tracer); buf.append(buff); - firstpar = false; + + firstParam = false; } } + buf.append(")"); } } diff --git a/test/org/jetbrains/java/decompiler/SingleClassesTest.java b/test/org/jetbrains/java/decompiler/SingleClassesTest.java index 73af499..f0de32d 100644 --- a/test/org/jetbrains/java/decompiler/SingleClassesTest.java +++ b/test/org/jetbrains/java/decompiler/SingleClassesTest.java @@ -34,4 +34,6 @@ public class SingleClassesTest extends SingleClassesTestBase { @Test public void testEnum() { doTest("pkg/TestEnum"); } @Test public void testDebugSymbols() { doTest("pkg/TestDebugSymbols"); } @Test public void testInvalidMethodSignature() { doTest("InvalidMethodSignature"); } + @Test public void testInnerClassConstructor() { doTest("pkg/TestInnerClassConstructor"); } + @Test public void testInnerClassConstructor11() { doTest("v11/TestInnerClassConstructor"); } } diff --git a/testData/classes/pkg/TestInnerClassConstructor$1.class b/testData/classes/pkg/TestInnerClassConstructor$1.class new file mode 100644 index 0000000..384ce5d Binary files /dev/null and b/testData/classes/pkg/TestInnerClassConstructor$1.class differ diff --git a/testData/classes/pkg/TestInnerClassConstructor$Inner.class b/testData/classes/pkg/TestInnerClassConstructor$Inner.class new file mode 100644 index 0000000..37e9262 Binary files /dev/null and b/testData/classes/pkg/TestInnerClassConstructor$Inner.class differ diff --git a/testData/classes/pkg/TestInnerClassConstructor.class b/testData/classes/pkg/TestInnerClassConstructor.class new file mode 100644 index 0000000..fb0d898 Binary files /dev/null and b/testData/classes/pkg/TestInnerClassConstructor.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor$1.class b/testData/classes/v11/TestInnerClassConstructor$1.class new file mode 100644 index 0000000..b11a30e Binary files /dev/null and b/testData/classes/v11/TestInnerClassConstructor$1.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor$Inner.class b/testData/classes/v11/TestInnerClassConstructor$Inner.class new file mode 100644 index 0000000..81face1 Binary files /dev/null and b/testData/classes/v11/TestInnerClassConstructor$Inner.class differ diff --git a/testData/classes/v11/TestInnerClassConstructor.class b/testData/classes/v11/TestInnerClassConstructor.class new file mode 100644 index 0000000..9cbad7f Binary files /dev/null and b/testData/classes/v11/TestInnerClassConstructor.class differ diff --git a/testData/results/TestInnerClassConstructor.dec b/testData/results/TestInnerClassConstructor.dec new file mode 100644 index 0000000..9b63154 --- /dev/null +++ b/testData/results/TestInnerClassConstructor.dec @@ -0,0 +1,17 @@ +package pkg; + +class TestInnerClassConstructor { + void m() { + new TestInnerClassConstructor.Inner("text"); + } + + void n(String var1) { + System.out.println("n(): " + var1); + } + + final class Inner { + private Inner(String var2) { + TestInnerClassConstructor.this.n(var2); + } + } +} diff --git a/testData/src/pkg/TestInnerClassConstructor.java b/testData/src/pkg/TestInnerClassConstructor.java new file mode 100644 index 0000000..e42c319 --- /dev/null +++ b/testData/src/pkg/TestInnerClassConstructor.java @@ -0,0 +1,17 @@ +package pkg; + +class TestInnerClassConstructor { + void m() { + new Inner("text"); + } + + void n(String s) { + System.out.println("n(): " + s); + } + + final class Inner { + private Inner(String s) { + n(s); + } + } +}