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 5268e16..e946c9a 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/NewExprent.java @@ -143,6 +143,8 @@ public class NewExprent extends Exprent { if (anonymous) { ClassNode child = DecompilerContext.getClassProcessor().getMapRootClasses().get(newType.value); + boolean selfReference = DecompilerContext.getProperty(DecompilerContext.CURRENT_CLASS_NODE) == child; + // IDEA-204310 - avoid backtracking later on for lambdas (causes spurious imports) if (!enumConst && (!lambda || DecompilerContext.getOption(IFernflowerPreferences.LAMBDA_TO_ANONYMOUS_CLASS))) { String enclosing = null; @@ -156,33 +158,37 @@ public class NewExprent extends Exprent { buf.append("new "); - String typename = ExprProcessor.getCastTypeName(child.anonymousClassType); - if (enclosing != null) { - ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); - if (anonymousNode != null) { - typename = anonymousNode.simpleName; - } - else { - typename = typename.substring(typename.lastIndexOf('.') + 1); + if (selfReference) { + buf.append(""); + } else { + String typename = ExprProcessor.getCastTypeName(child.anonymousClassType); + if (enclosing != null) { + ClassNode anonymousNode = DecompilerContext.getClassProcessor().getMapRootClasses().get(child.anonymousClassType.value); + if (anonymousNode != null) { + typename = anonymousNode.simpleName; + } + else { + typename = typename.substring(typename.lastIndexOf('.') + 1); + } } - } - GenericClassDescriptor descriptor = ClassWriter.getGenericClassDescriptor(child.classStruct); - if (descriptor != null) { - if (descriptor.superinterfaces.isEmpty()) { - buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); + GenericClassDescriptor descriptor = ClassWriter.getGenericClassDescriptor(child.classStruct); + if (descriptor != null) { + if (descriptor.superinterfaces.isEmpty()) { + buf.append(GenericMain.getGenericCastTypeName(descriptor.superclass)); + } + else { + if (descriptor.superinterfaces.size() > 1 && !lambda) { + DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, + IFernflowerLogger.Severity.WARN); + } + buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0))); + } } else { - if (descriptor.superinterfaces.size() > 1 && !lambda) { - DecompilerContext.getLogger().writeMessage("Inconsistent anonymous class signature: " + child.classStruct.qualifiedName, - IFernflowerLogger.Severity.WARN); - } - buf.append(GenericMain.getGenericCastTypeName(descriptor.superinterfaces.get(0))); + buf.append(typename); } } - else { - buf.append(typename); - } } buf.append('('); @@ -226,7 +232,7 @@ public class NewExprent extends Exprent { buf.append(clsBuf); tracer.incrementCurrentSourceLine(clsBuf.countLines()); } - else { + else if (!selfReference) { TextBuffer clsBuf = new TextBuffer(); new ClassWriter().classToJava(child, clsBuf, indent, tracer); buf.append(clsBuf); diff --git a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java index 810c9ec..cde5796 100644 --- a/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java +++ b/test/org/jetbrains/java/decompiler/BulkDecompilationTest.java @@ -47,6 +47,11 @@ public class BulkDecompilationTest { doTestJar("bulk"); } + @Test + public void testKtJar() { + doTestJar("kt25937"); + } + @Test public void testObfuscated() { doTestJar("obfuscated"); diff --git a/testData/kt25937.jar b/testData/kt25937.jar new file mode 100644 index 0000000..6353075 Binary files /dev/null and b/testData/kt25937.jar differ diff --git a/testData/kt25937/META-INF/MANIFEST.MF b/testData/kt25937/META-INF/MANIFEST.MF new file mode 100644 index 0000000..1b4de4e --- /dev/null +++ b/testData/kt25937/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Created-By: 1.8.0_171 (Oracle Corporation) + diff --git a/testData/kt25937/kt/Kt25937Kt.java b/testData/kt25937/kt/Kt25937Kt.java new file mode 100644 index 0000000..4855c45 --- /dev/null +++ b/testData/kt25937/kt/Kt25937Kt.java @@ -0,0 +1,26 @@ +package kt; + +import kotlin.Metadata; +import kotlin.Unit; +import kotlin.coroutines.Continuation; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.internal.Intrinsics; +import org.jetbrains.annotations.NotNull; + +@Metadata( + mv = {1, 1, 16}, + bv = {1, 0, 3}, + k = 2, + d1 = {"\u0000\u001c\n\u0000\n\u0002\u0010\b\n\u0000\n\u0002\u0018\u0002\n\u0002\u0018\u0002\n\u0002\u0010\u0002\n\u0002\u0010\u0000\n\u0002\b\u0003\u001a,\u0010\u0000\u001a\u00020\u00012\u001c\u0010\u0002\u001a\u0018\b\u0001\u0012\n\u0012\b\u0012\u0004\u0012\u00020\u00050\u0004\u0012\u0006\u0012\u0004\u0018\u00010\u00060\u0003ø\u0001\u0000¢\u0006\u0002\u0010\u0007\u001a\u0006\u0010\b\u001a\u00020\u0001\u0082\u0002\u0004\n\u0002\b\u0019¨\u0006\t"}, + d2 = {"callSuspendBlock", "", "block", "Lkotlin/Function1;", "Lkotlin/coroutines/Continuation;", "", "", "(Lkotlin/jvm/functions/Function1;)I", "callSuspendBlockGood", "kotlinx-test"} +) +public final class Kt25937Kt { + public static final int callSuspendBlock(@NotNull Function1, ? extends Object> block) { + Intrinsics.checkParameterIsNotNull(block, "block"); + return 1; + } + + public static final int callSuspendBlockGood() { + return 1; + } +} diff --git a/testData/kt25937/kt/Kt25937_1Kt.java b/testData/kt25937/kt/Kt25937_1Kt.java new file mode 100644 index 0000000..711f6de --- /dev/null +++ b/testData/kt25937/kt/Kt25937_1Kt.java @@ -0,0 +1,49 @@ +package kt; + +import kotlin.Metadata; +import kotlin.ResultKt; +import kotlin.Unit; +import kotlin.coroutines.Continuation; +import kotlin.coroutines.intrinsics.IntrinsicsKt; +import kotlin.jvm.functions.Function1; +import kotlin.jvm.internal.Intrinsics; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +@Metadata( + mv = {1, 1, 17}, + bv = {1, 0, 3}, + k = 2, + d1 = {"\u0000\b\n\u0000\n\u0002\u0010\b\n\u0000\u001a\u0006\u0010\u0000\u001a\u00020\u0001¨\u0006\u0002"}, + d2 = {"some1", "", "ide-kotlin-test.kotlinx-test.main"} +) +public final class Kt25937_1Kt { + public static final int some1() { + return Kt25937Kt.callSuspendBlock((Function1)(new Function1, Object>((Continuation)null) { + int label; + + @Nullable + public final Object invokeSuspend(@NotNull Object $result) { + Object var2 = IntrinsicsKt.getCOROUTINE_SUSPENDED(); + switch(this.label) { + case 0: + ResultKt.throwOnFailure($result); + return Unit.INSTANCE; + default: + throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine"); + } + } + + @NotNull + public final Continuation create(@NotNull Continuation completion) { + Intrinsics.checkParameterIsNotNull(completion, "completion"); + Function1 var2 = new (completion); + return var2; + } + + public final Object invoke(Object var1) { + return (()this.create((Continuation)var1)).invokeSuspend(Unit.INSTANCE); + } + })); + } +}