Fix stub mismatch for top level declaration with JvmPackageName (KT-21831)
ClassId stores jvm name and it differs from kotlin name in that case. #KT-21831 Fixed
This commit is contained in:
+2
-1
@@ -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 kotlinClass = IDEKotlinBinaryClassCache.getKotlinBinaryClass(file, fileContent) ?: error("Can't find binary class for Kotlin file: $file")
|
||||||
val header = kotlinClass.classHeader
|
val header = kotlinClass.classHeader
|
||||||
val classId = kotlinClass.classId
|
val classId = kotlinClass.classId
|
||||||
val packageFqName = classId.packageFqName
|
val packageFqName = header.packageName?.let { FqName(it) } ?: classId.packageFqName
|
||||||
|
|
||||||
if (!header.metadataVersion.isCompatible()) {
|
if (!header.metadataVersion.isCompatible()) {
|
||||||
return createIncompatibleAbiVersionFileStub()
|
return createIncompatibleAbiVersionFileStub()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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]
|
||||||
+15
-3
@@ -27,6 +27,7 @@ import com.intellij.util.indexing.FileContentImpl
|
|||||||
import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClsStubBuilder
|
import org.jetbrains.kotlin.idea.decompiler.classFile.KotlinClsStubBuilder
|
||||||
import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest
|
import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtFileStubBuilder
|
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.KotlinTestUtils
|
||||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
@@ -36,8 +37,18 @@ import java.util.*
|
|||||||
|
|
||||||
abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() {
|
abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() {
|
||||||
fun doTest(sourcePath: String) {
|
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")
|
val txtFilePath = File("$sourcePath/${lastSegment(sourcePath)}.txt")
|
||||||
|
|
||||||
testClsStubsForFile(classFile, txtFilePath)
|
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)
|
val outDir = KotlinTestUtils.tmpDir("libForStubTest-" + sourcePath)
|
||||||
MockLibraryUtil.compileKotlin(sourcePath, outDir, extraOptions = listOf("-Xallow-kotlin-package"))
|
MockLibraryUtil.compileKotlin(sourcePath, outDir, extraOptions = listOf("-Xallow-kotlin-package"))
|
||||||
val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(outDir)!!
|
val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(outDir)!!
|
||||||
return root.findClassFileByName(lastSegment(sourcePath))
|
|
||||||
|
return root.findClassFileByName(classFileName ?: lastSegment(sourcePath))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lastSegment(sourcePath: String): String {
|
private fun lastSegment(sourcePath: String): String {
|
||||||
|
|||||||
Generated
+6
@@ -181,6 +181,12 @@ public class ClsStubBuilderTestGenerated extends AbstractClsStubBuilderTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("TopJvmPackageName")
|
||||||
|
public void testTopJvmPackageName() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopJvmPackageName/");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("TopLevelMembersAnnotatedKt")
|
@TestMetadata("TopLevelMembersAnnotatedKt")
|
||||||
public void testTopLevelMembersAnnotatedKt() throws Exception {
|
public void testTopLevelMembersAnnotatedKt() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopLevelMembersAnnotatedKt/");
|
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/decompiler/stubBuilder/TopLevelMembersAnnotatedKt/");
|
||||||
|
|||||||
+1
-1
@@ -32,7 +32,7 @@ import org.junit.Assert
|
|||||||
class ClsStubConsistencyTest : KotlinLightCodeInsightFixtureTestCase() {
|
class ClsStubConsistencyTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||||
private fun doTest(id: ClassId) {
|
private fun doTest(id: ClassId) {
|
||||||
val packageFile = VirtualFileFinder.SERVICE.getInstance(project).findVirtualFileWithHeader(id)
|
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 decompiledText = buildDecompiledTextForClassFile(packageFile).text
|
||||||
val fileWithDecompiledText = KtPsiFactory(project).createFile(decompiledText)
|
val fileWithDecompiledText = KtPsiFactory(project).createFile(decompiledText)
|
||||||
val stubTreeFromDecompiledText = KtFileStubBuilder().buildStubTree(fileWithDecompiledText)
|
val stubTreeFromDecompiledText = KtFileStubBuilder().buildStubTree(fileWithDecompiledText)
|
||||||
|
|||||||
Reference in New Issue
Block a user