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 fe76ff689a6..ace7f7dc180 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 @@ -56,7 +56,8 @@ open class KotlinClsStubBuilder : ClsStubBuilder() { val kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file, fileContent) ?: error("Can't find binary class for Kotlin file: $file") val header = kotlinClass.classHeader val classId = kotlinClass.classId - val packageFqName = classId.packageFqName + val packageFqName = header.packageName?.let { FqName(it) } ?: classId.packageFqName + if (!header.metadataVersion.isCompatible()) { return createIncompatibleAbiVersionFileStub() } diff --git a/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.kt b/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.kt new file mode 100644 index 00000000000..ee5f3dcd2e1 --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.kt @@ -0,0 +1,9 @@ +@file:Suppress("UNCHECKED_CAST", "NOTHING_TO_INLINE", "INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") +@file:JvmName("OtherKt") +@file:kotlin.jvm.JvmPackageName("some.other.jvm") +package some.other + +@SinceKotlin("1.2") +fun foo() {} + +// JVM_FILE_NAME: OtherKt \ No newline at end of file diff --git a/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.txt b/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.txt new file mode 100644 index 00000000000..950a286ee62 --- /dev/null +++ b/idea/testData/decompiler/stubBuilder/TopJvmPackageName/TopJvmPackageName.txt @@ -0,0 +1,21 @@ +PsiJetFileStubImpl[package=some.other] + PACKAGE_DIRECTIVE + DOT_QUALIFIED_EXPRESSION + REFERENCE_EXPRESSION[referencedName=some] + REFERENCE_EXPRESSION[referencedName=other] + IMPORT_LIST + FUN[fqName=some.other.foo, hasBlockBody=true, hasBody=true, hasTypeParameterListBeforeFunctionName=false, isExtension=false, isTopLevel=true, name=foo] + MODIFIER_LIST[public] + ANNOTATION_ENTRY[hasValueArguments=false, shortName=SinceKotlin] + CONSTRUCTOR_CALLEE + TYPE_REFERENCE + USER_TYPE + USER_TYPE + REFERENCE_EXPRESSION[referencedName=kotlin] + REFERENCE_EXPRESSION[referencedName=SinceKotlin] + VALUE_PARAMETER_LIST + TYPE_REFERENCE + USER_TYPE + USER_TYPE + REFERENCE_EXPRESSION[referencedName=kotlin] + REFERENCE_EXPRESSION[referencedName=Unit] diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/AbstractClsStubBuilderTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/AbstractClsStubBuilderTest.kt index a8bbd5bdfeb..ebd3ef67875 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/AbstractClsStubBuilderTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/AbstractClsStubBuilderTest.kt @@ -27,6 +27,7 @@ import com.intellij.util.indexing.FileContentImpl import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClsStubBuilder import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest import org.jetbrains.kotlin.psi.stubs.elements.KtFileStubBuilder +import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils import org.jetbrains.kotlin.test.MockLibraryUtil import org.jetbrains.kotlin.utils.addIfNotNull @@ -36,8 +37,18 @@ import java.util.* abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() { fun doTest(sourcePath: String) { - val classFile = getClassFileToDecompile(sourcePath) + val ktFile = File("$sourcePath/${lastSegment(sourcePath)}.kt") + val jvmFileName = if (ktFile.exists()) { + val ktFileText = ktFile.readText() + InTextDirectivesUtils.findStringWithPrefixes(ktFileText, "JVM_FILE_NAME:") + } else { + null + } + + val classFile = getClassFileToDecompile(sourcePath, jvmFileName) + val txtFilePath = File("$sourcePath/${lastSegment(sourcePath)}.txt") + testClsStubsForFile(classFile, txtFilePath) } @@ -53,11 +64,12 @@ abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() { } } - private fun getClassFileToDecompile(sourcePath: String): VirtualFile { + private fun getClassFileToDecompile(sourcePath: String, classFileName: String?): VirtualFile { val outDir = KotlinTestUtils.tmpDir("libForStubTest-" + sourcePath) MockLibraryUtil.compileKotlin(sourcePath, outDir, extraOptions = listOf("-Xallow-kotlin-package")) val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(outDir)!! - return root.findClassFileByName(lastSegment(sourcePath)) + + return root.findClassFileByName(classFileName ?: lastSegment(sourcePath)) } private fun lastSegment(sourcePath: String): String { diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java index 8dadcd76257..a8fe7818bee 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubBuilderTestGenerated.java @@ -181,6 +181,12 @@ public class ClsStubBuilderTestGenerated extends AbstractClsStubBuilderTest { doTest(fileName); } + @TestMetadata("TopJvmPackageName") + public void testTopJvmPackageName() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopJvmPackageName/"); + doTest(fileName); + } + @TestMetadata("TopLevelMembersAnnotatedKt") public void testTopLevelMembersAnnotatedKt() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopLevelMembersAnnotatedKt/"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubConsistencyTest.kt b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubConsistencyTest.kt index 80d12d03a91..089bfbdcc00 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubConsistencyTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/decompiler/stubBuilder/ClsStubConsistencyTest.kt @@ -32,7 +32,7 @@ import org.junit.Assert class ClsStubConsistencyTest : KotlinLightCodeInsightFixtureTestCase() { private fun doTest(id: ClassId) { val packageFile = VirtualFileFinder.SERVICE.getInstance(project).findVirtualFileWithHeader(id) - ?: throw AssertionError("File not found for id: $id") + ?: throw AssertionError("File not found for id: $id") val decompiledText = buildDecompiledTextForClassFile(packageFile).text val fileWithDecompiledText = KtPsiFactory(project).createFile(decompiledText) val stubTreeFromDecompiledText = KtFileStubBuilder().buildStubTree(fileWithDecompiledText)