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.
This commit is contained in:
Yan Zhulanow
2019-07-25 21:16:37 +09:00
parent cc3f1b3501
commit 89c45e9e3f
@@ -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)
}