From 89c45e9e3f0ca914103dc86aa5d8a75f30084c79 Mon Sep 17 00:00:00 2001 From: Yan Zhulanow Date: Thu, 25 Jul 2019 21:16:37 +0900 Subject: [PATCH] Fix stub loading for crossinline lambdas compiled by older Kotlinc (EA-105730) Older kotlinc versions (1.1.5?) didn't generate the 'INNERCLASS' attribute for some anonymous classes, e.g. for 'crossinline' lambdas. An example: 'Timer().schedule(1000) { foo () }' Normally, stub loader checks if the class is 'ClassFileViewProvider.isInnerClass()', and ignores the class file. Without the 'INNERCLASS' attribute this check fails. As the stub loaded isn't created to deal with anonymous classes nicely, it fails miserably. This commit explicitly ignores classes with local visibility. --- .../idea/decompiler/classFile/KotlinClsStubBuilder.kt | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt index e723213483e..e16912a7373 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/decompiler/classFile/KotlinClsStubBuilder.kt @@ -28,6 +28,7 @@ import org.jetbrains.kotlin.idea.decompiler.stubBuilder.* import org.jetbrains.kotlin.load.kotlin.* import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader import org.jetbrains.kotlin.metadata.ProtoBuf +import org.jetbrains.kotlin.metadata.deserialization.Flags import org.jetbrains.kotlin.metadata.deserialization.NameResolver import org.jetbrains.kotlin.metadata.deserialization.TypeTable import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmProtoBufUtil @@ -87,6 +88,13 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { KotlinClassHeader.Kind.CLASS -> { if (classId.isLocal) return null val (nameResolver, classProto) = JvmProtoBufUtil.readClassDataFrom(annotationData, strings) + if (Flags.VISIBILITY.get(classProto.flags) == ProtoBuf.Visibility.LOCAL) { + // Older Kotlin compiler versions didn't put 'INNERCLASS' attributes in some cases (e.g. for cross-inline lambdas), + // so 'ClassFileViewProvider.isInnerClass()' pre-check won't find them (EA-105730). + // Example: `Timer().schedule(1000) { foo () }`. + return null + } + val context = components.createContext(nameResolver, packageFqName, TypeTable(classProto.typeTable)) createTopLevelClassStub(classId, classProto, KotlinJvmBinarySourceElement(kotlinClass), context, header.isScript) }