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:
Nikolay Krasko
2018-03-13 15:36:47 +03:00
parent c1f43558b9
commit bc7ccbc39b
6 changed files with 54 additions and 5 deletions
@@ -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()
}
@@ -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]
@@ -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 {
@@ -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/");
@@ -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)