From ca1e0a4b88baefe5aad0c12dfb98f80c0b1ed0f7 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 5 Sep 2018 14:58:51 +0300 Subject: [PATCH] Do not fetch Kotlin stubs for versioned files from multi-release jars (KT-26439) An incomplete list of inner class files might be stored in versioned directory and that ruins Kotlin stub building. Another reason for excluding such files, that they are duplicated in different declarations lists such as `Navigate -> Class...` action. #KT-26439 Fixed --- .../classFile/KotlinClsStubBuilder.kt | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) 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 9a7ceacc60a..bb2513f23e7 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 @@ -43,13 +43,19 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { override fun getStubVersion() = ClassFileStubBuilder.STUB_VERSION + KotlinStubVersions.CLASSFILE_STUB_VERSION override fun buildFileStub(content: FileContent): PsiFileStub<*>? { - val file = content.file + val virtualFile = content.file - if (isKotlinInternalCompiledFile(file, content.content)) { + if (isKotlinInternalCompiledFile(virtualFile, content.content)) { return null } - return doBuildFileStub(file, content.content) + if (isVersioned(virtualFile)) { + // Kotlin can't build stubs for versioned class files, because list of versioned inner classes + // might be incomplete + return null + } + + return doBuildFileStub(virtualFile, content.content) } private fun doBuildFileStub(file: VirtualFile, fileContent: ByteArray): PsiFileStub? { @@ -105,6 +111,13 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { companion object { val LOG = Logger.getInstance(KotlinClsStubBuilder::class.java) + + // Archive separator + META-INF + versions + private val VERSIONED_PATH_MARKER = "!/META-INF/versions/" + + fun isVersioned(virtualFile: VirtualFile): Boolean { + return virtualFile.path.contains(VERSIONED_PATH_MARKER) + } } }