From e35da00aecb197ba52eff4a4e885c9423ae65d67 Mon Sep 17 00:00:00 2001 From: Vladimir Ilmov Date: Mon, 3 Feb 2020 15:39:45 +0300 Subject: [PATCH 1/4] KT-25937 Decompilation to Java makes UI lag roughly every 2 seconds, and is not cancellable GitOrigin-RevId: 58ce5d601bcebb5826cb938f6ea365fa245e7be1 --- .../modules/decompiler/exps/NewExprent.java | 50 ++++++++++-------- .../decompiler/BulkDecompilationTest.java | 5 ++ testData/kt25937.jar | Bin 0 -> 3036 bytes testData/kt25937/META-INF/MANIFEST.MF | 3 ++ testData/kt25937/kt/Kt25937Kt.java | 26 +++++++++ testData/kt25937/kt/Kt25937_1Kt.java | 49 +++++++++++++++++ 6 files changed, 111 insertions(+), 22 deletions(-) create mode 100644 testData/kt25937.jar create mode 100644 testData/kt25937/META-INF/MANIFEST.MF create mode 100644 testData/kt25937/kt/Kt25937Kt.java create mode 100644 testData/kt25937/kt/Kt25937_1Kt.java 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 0000000000000000000000000000000000000000..635307556acd7ec92006872e395d8b6b1f1e3641 GIT binary patch literal 3036 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 dOFQ;^HuOW literal 0 HcmV?d00001 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); + } + })); + } +} From 488da329f439ef8df349f2f8beb2c993fe7d1449 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 22 Apr 2020 12:20:35 +0700 Subject: [PATCH 2/4] Fix warnings (redundant boolean operation and others) GitOrigin-RevId: 115ba7dfd69a2b37963430aac7e979271c0331db --- .../jetbrains/java/decompiler/modules/decompiler/IfHelper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java index 0e55d27..89bfae3 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/IfHelper.java @@ -100,7 +100,7 @@ public class IfHelper { break; } - res |= true; + res = true; } return res; From 8382c008b2d7f47e0d59759bc3322f1c2810b6e6 Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Wed, 13 May 2020 15:04:08 +0700 Subject: [PATCH 3/4] Fixed unnecessarily escaped character GitOrigin-RevId: 9532833be54e94cfe74dee90f4ca815790d7f5be --- .../java/decompiler/modules/decompiler/exps/ConstExprent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java index d250db9..9fa5812 100644 --- a/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java +++ b/src/org/jetbrains/java/decompiler/modules/decompiler/exps/ConstExprent.java @@ -28,7 +28,7 @@ public class ConstExprent extends Exprent { CHAR_ESCAPES.put(0xC, "\\f"); /* \u000c: form feed FF */ CHAR_ESCAPES.put(0xD, "\\r"); /* \u000d: carriage return CR */ //CHAR_ESCAPES.put(0x22, "\\\""); /* \u0022: double quote " */ - CHAR_ESCAPES.put(0x27, "\\\'"); /* \u0027: single quote ' */ + CHAR_ESCAPES.put(0x27, "\\'"); /* \u0027: single quote ' */ CHAR_ESCAPES.put(0x5C, "\\\\"); /* \u005c: backslash \ */ } From 1685759f6121c1ac8e2a7e2cb46683d206b1fd4e Mon Sep 17 00:00:00 2001 From: Tagir Valeev Date: Thu, 14 May 2020 15:31:46 +0700 Subject: [PATCH 4/4] Use Math.min/max GitOrigin-RevId: 4fafd6b7ef8fd2e8ac99b6e0c8af2d092ded2526 --- src/org/jetbrains/java/decompiler/struct/StructClass.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/org/jetbrains/java/decompiler/struct/StructClass.java b/src/org/jetbrains/java/decompiler/struct/StructClass.java index 02bb74a..0bb370c 100644 --- a/src/org/jetbrains/java/decompiler/struct/StructClass.java +++ b/src/org/jetbrains/java/decompiler/struct/StructClass.java @@ -166,7 +166,7 @@ public class StructClass extends StructMember { } public int getBytecodeVersion() { - return majorVersion < CodeConstants.BYTECODE_JAVA_LE_4 ? CodeConstants.BYTECODE_JAVA_LE_4 : majorVersion; + return Math.max(majorVersion, CodeConstants.BYTECODE_JAVA_LE_4); } @Override