Open
Description
Vineflower version
1.11.1
Describe the bug
Vineflower cannot decompile kotlin crossinline
lambdas when they are passed to a function which takes a suspending lambda.
Additional information
Here is some code which reproduces the issue. I have minimized it as much as possible, and have not been successful in minimizing it any further.
fun test() {
return test2 { }
}
inline fun test2(crossinline fn: () -> Unit) {
return runBlocking { fn() }
}
Here is the stack trace:
ERROR: Class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1 couldn't be fully decompiled.
java.lang.IllegalStateException: Couldn't find method <anonymous> (Lkotlinx/coroutines/CoroutineScope;)V in class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
at org.vineflower.kotlin.struct.KFunction.parse(KFunction.java:112)
at org.vineflower.kotlin.KotlinWriter.writeClass(KotlinWriter.java:221)
at org.jetbrains.java.decompiler.main.ClassesProcessor.writeClass(ClassesProcessor.java:500)
at org.jetbrains.java.decompiler.main.Fernflower.getClassContent(Fernflower.java:196)
at org.jetbrains.java.decompiler.struct.ContextUnit.lambda$save$3(ContextUnit.java:195)
at java.base/java.util.concurrent.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1403)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:387)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1312)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1843)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1808)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:188)
If you run javap
on the .class file, this is what it emits:
public final class ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1 extends kotlin.coroutines.jvm.internal.SuspendLambda implements kotlin.jvm.functions.Function2<kotlinx.coroutines.CoroutineScope, kotlin.coroutines.Continuation<? super kotlin.Unit>, java.lang.Object> {
int label;
public ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1(kotlin.coroutines.Continuation);
Code:
0: aload_0
1: iconst_2
2: aload_1
3: invokespecial #19 // Method kotlin/coroutines/jvm/internal/SuspendLambda."<init>":(ILkotlin/coroutines/Continuation;)V
6: return
public final java.lang.Object invokeSuspend(java.lang.Object);
Code:
0: invokestatic #42 // Method kotlin/coroutines/intrinsics/IntrinsicsKt.getCOROUTINE_SUSPENDED:()Ljava/lang/Object;
3: pop
4: aload_0
5: getfield #44 // Field label:I
8: tableswitch { // 0 to 0
0: 28
default: 39
}
28: aload_1
29: invokestatic #50 // Method kotlin/ResultKt.throwOnFailure:(Ljava/lang/Object;)V
32: iconst_0
33: istore_2
34: nop
35: getstatic #56 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
38: areturn
39: new #58 // class java/lang/IllegalStateException
42: dup
43: ldc #60 // String call to \'resume\' before \'invoke\' with coroutine
45: invokespecial #63 // Method java/lang/IllegalStateException."<init>":(Ljava/lang/String;)V
48: athrow
public final kotlin.coroutines.Continuation<kotlin.Unit> create(java.lang.Object, kotlin.coroutines.Continuation<?>);
Code:
0: new #2 // class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
3: dup
4: aload_2
5: invokespecial #71 // Method "<init>":(Lkotlin/coroutines/Continuation;)V
8: checkcast #73 // class kotlin/coroutines/Continuation
11: areturn
public final java.lang.Object invoke(kotlinx.coroutines.CoroutineScope, kotlin.coroutines.Continuation<? super kotlin.Unit>);
Code:
0: aload_0
1: aload_1
2: aload_2
3: invokevirtual #80 // Method create:(Ljava/lang/Object;Lkotlin/coroutines/Continuation;)Lkotlin/coroutines/Continuation;
6: checkcast #2 // class ca/solostudios/nyx/plugin/compile/TestKt$test$$inlined$test2$1
9: getstatic #56 // Field kotlin/Unit.INSTANCE:Lkotlin/Unit;
12: invokevirtual #82 // Method invokeSuspend:(Ljava/lang/Object;)Ljava/lang/Object;
15: areturn
public java.lang.Object invoke(java.lang.Object, java.lang.Object);
Code:
0: aload_0
1: aload_1
2: checkcast #86 // class kotlinx/coroutines/CoroutineScope
5: aload_2
6: checkcast #73 // class kotlin/coroutines/Continuation
9: invokevirtual #88 // Method invoke:(Lkotlinx/coroutines/CoroutineScope;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
12: areturn
}
and here are the kotlin annotations at the top of the class (decompiled with fernflower to get them):
@DebugMetadata(
f = "test.kt",
l = {},
i = {},
s = {},
n = {},
m = "invokeSuspend",
c = "ca.solostudios.nyx.plugin.compile.TestKt$test$$inlined$test2$1"
)
@Metadata(
mv = {1, 8, 0},
k = 3,
xi = 48,
d1 = {"\u0000\f\n\u0000\n\u0002\u0010\u0002\n\u0002\u0018\u0002\n\u0000\u0010\u0000\u001a\u00020\u0001*\u00020\u0002H\u008a@¨\u0006\u0003"},
d2 = {"<anonymous>", "", "Lkotlinx/coroutines/CoroutineScope;", "ca/solostudios/nyx/plugin/compile/TestKt$test2$1"}
)
@SourceDebugExtension({"SMAP\ntest.kt\nKotlin\n*S Kotlin\n*F\n+ 1 test.kt\nca/solostudios/nyx/plugin/compile/TestKt$test2$1\n+ 2 test.kt\nca/solostudios/nyx/plugin/compile/TestKt\n*L\n1#1,37:1\n33#2:38\n*E\n"})
Metadata
Metadata
Assignees
Labels
No labels