Fix generating cls stubs when is metadata using type tables (KT-23345)
Affected cases: - return type for suspend lambda - aliased type in type alias declaration - using type alias instead of aliased type in declarations #KT-23345 Fixed
This commit is contained in:
@@ -28,7 +28,7 @@ object KotlinStubVersions {
|
|||||||
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
|
// Binary stub version should be increased if stub format (org.jetbrains.kotlin.psi.stubs.impl) is changed
|
||||||
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
|
// or changes are made to the core stub building code (org.jetbrains.kotlin.idea.decompiler.stubBuilder).
|
||||||
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
|
// Increasing this version will lead to reindexing of all binary files that are potentially kotlin binaries (including all class files).
|
||||||
private const val BINARY_STUB_VERSION = 64
|
private const val BINARY_STUB_VERSION = 66
|
||||||
|
|
||||||
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
|
// Classfile stub version should be increased if changes are made to classfile stub building subsystem (org.jetbrains.kotlin.idea.decompiler.classFile)
|
||||||
// Increasing this version will lead to reindexing of all classfiles.
|
// Increasing this version will lead to reindexing of all classfiles.
|
||||||
|
|||||||
@@ -35,3 +35,5 @@ val DO_NOTHING_2: (Any?, Any?) -> Unit = { _, _ -> }
|
|||||||
val DO_NOTHING_3: (Any?, Any?, Any?) -> Unit = { _, _, _ -> }
|
val DO_NOTHING_3: (Any?, Any?, Any?) -> Unit = { _, _, _ -> }
|
||||||
|
|
||||||
fun <T> doNothing(): (T) -> Unit = DO_NOTHING
|
fun <T> doNothing(): (T) -> Unit = DO_NOTHING
|
||||||
|
|
||||||
|
fun doNothing() {}
|
||||||
+11
-2
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||||
import org.jetbrains.kotlin.serialization.js.DynamicTypeDeserializer
|
import org.jetbrains.kotlin.serialization.js.DynamicTypeDeserializer
|
||||||
|
import org.jetbrains.kotlin.utils.doNothing
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
// TODO: see DescriptorRendererOptions.excludedTypeAnnotationClasses for decompiler
|
// TODO: see DescriptorRendererOptions.excludedTypeAnnotationClasses for decompiler
|
||||||
@@ -47,7 +48,11 @@ private val ANNOTATIONS_NOT_LOADED_FOR_TYPES = setOf(KotlinBuiltIns.FQ_NAMES.par
|
|||||||
|
|
||||||
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
||||||
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type, additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }) {
|
fun createTypeReferenceStub(parent: StubElement<out PsiElement>, type: Type, additionalAnnotations: () -> List<ClassIdWithTarget> = { emptyList() }) {
|
||||||
if (type.hasAbbreviatedType()) return createTypeReferenceStub(parent, type.abbreviatedType, additionalAnnotations)
|
val abbreviatedType = type.abbreviatedType(c.typeTable)
|
||||||
|
if (abbreviatedType != null) {
|
||||||
|
return createTypeReferenceStub(parent, abbreviatedType, additionalAnnotations)
|
||||||
|
}
|
||||||
|
|
||||||
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(parent, KtStubElementTypes.TYPE_REFERENCE)
|
val typeReference = KotlinPlaceHolderStubImpl<KtTypeReference>(parent, KtStubElementTypes.TYPE_REFERENCE)
|
||||||
|
|
||||||
val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot {
|
val annotations = c.components.annotationLoader.loadTypeAnnotations(type, c.nameResolver).filterNot {
|
||||||
@@ -64,6 +69,9 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
|||||||
createTypeParameterStub(typeReference, type, c.typeParameters[type.typeParameter], allAnnotations)
|
createTypeParameterStub(typeReference, type, c.typeParameters[type.typeParameter], allAnnotations)
|
||||||
type.hasTypeParameterName() ->
|
type.hasTypeParameterName() ->
|
||||||
createTypeParameterStub(typeReference, type, c.nameResolver.getName(type.typeParameterName), allAnnotations)
|
createTypeParameterStub(typeReference, type, c.nameResolver.getName(type.typeParameterName), allAnnotations)
|
||||||
|
else -> {
|
||||||
|
doNothing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,7 +216,8 @@ class TypeClsStubBuilder(private val c: ClsStubBuilderContext) {
|
|||||||
createTypeReferenceStub(functionType, returnType)
|
createTypeReferenceStub(functionType, returnType)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
createTypeReferenceStub(functionType, suspendParameterType.getArgument(0).type)
|
val continuationArgumentType = suspendParameterType.getArgument(0).type(c.typeTable)!!
|
||||||
|
createTypeReferenceStub(functionType, continuationArgumentType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -26,6 +26,7 @@ import org.jetbrains.kotlin.psi.stubs.impl.KotlinTypeAliasStubImpl
|
|||||||
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
import org.jetbrains.kotlin.serialization.deserialization.ProtoContainer
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||||
import org.jetbrains.kotlin.serialization.deserialization.getName
|
import org.jetbrains.kotlin.serialization.deserialization.getName
|
||||||
|
import org.jetbrains.kotlin.metadata.deserialization.underlyingType
|
||||||
|
|
||||||
fun createTypeAliasStub(
|
fun createTypeAliasStub(
|
||||||
parent: StubElement<out PsiElement>,
|
parent: StubElement<out PsiElement>,
|
||||||
@@ -57,5 +58,6 @@ fun createTypeAliasStub(
|
|||||||
createAnnotationStubs(typeAliasProto.annotationList.map { context.nameResolver.getClassId(it.id) }, modifierList)
|
createAnnotationStubs(typeAliasProto.annotationList.map { context.nameResolver.getClassId(it.id) }, modifierList)
|
||||||
}
|
}
|
||||||
|
|
||||||
typeStubBuilder.createTypeReferenceStub(typeAlias, typeAliasProto.underlyingType)
|
val typeAliasUnderlyingType = typeAliasProto.underlyingType(context.typeTable)
|
||||||
|
typeStubBuilder.createTypeReferenceStub(typeAlias, typeAliasUnderlyingType)
|
||||||
}
|
}
|
||||||
|
|||||||
+31
-8
@@ -45,11 +45,23 @@ abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() {
|
|||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
val classFile = getClassFileToDecompile(sourcePath, jvmFileName)
|
|
||||||
|
|
||||||
val txtFilePath = File("$sourcePath/${lastSegment(sourcePath)}.txt")
|
val txtFilePath = File("$sourcePath/${lastSegment(sourcePath)}.txt")
|
||||||
|
|
||||||
testClsStubsForFile(classFile, txtFilePath)
|
testWithEnabledStringTable(sourcePath, jvmFileName, txtFilePath)
|
||||||
|
testWithDisabledStringTable(sourcePath, jvmFileName, txtFilePath)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testWithEnabledStringTable(sourcePath: String, classFileName: String?, txtFile: File?) {
|
||||||
|
doTest(sourcePath, true, classFileName, txtFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun testWithDisabledStringTable(sourcePath: String, classFileName: String?, txtFile: File?) {
|
||||||
|
doTest(sourcePath, false, classFileName, txtFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun doTest(sourcePath: String, useStringTable: Boolean, classFileName: String?, txtFile: File?) {
|
||||||
|
val classFile = getClassFileToDecompile(sourcePath, useStringTable, classFileName)
|
||||||
|
testClsStubsForFile(classFile, txtFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected fun testClsStubsForFile(classFile: VirtualFile, txtFile: File?) {
|
protected fun testClsStubsForFile(classFile: VirtualFile, txtFile: File?) {
|
||||||
@@ -64,9 +76,16 @@ abstract class AbstractClsStubBuilderTest : LightCodeInsightFixtureTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getClassFileToDecompile(sourcePath: String, classFileName: String?): VirtualFile {
|
private fun getClassFileToDecompile(sourcePath: String, isUseStringTable: Boolean, classFileName: String?): VirtualFile {
|
||||||
val outDir = KotlinTestUtils.tmpDir("libForStubTest-" + sourcePath)
|
val outDir = KotlinTestUtils.tmpDir("libForStubTest-" + sourcePath)
|
||||||
MockLibraryUtil.compileKotlin(sourcePath, outDir, extraOptions = listOf("-Xallow-kotlin-package"))
|
|
||||||
|
val extraOptions = ArrayList<String>()
|
||||||
|
extraOptions.add("-Xallow-kotlin-package")
|
||||||
|
if (isUseStringTable) {
|
||||||
|
extraOptions.add("-Xuse-type-table")
|
||||||
|
}
|
||||||
|
|
||||||
|
MockLibraryUtil.compileKotlin(sourcePath, outDir, extraOptions = extraOptions)
|
||||||
val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(outDir)!!
|
val root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(outDir)!!
|
||||||
|
|
||||||
return root.findClassFileByName(classFileName ?: lastSegment(sourcePath))
|
return root.findClassFileByName(classFileName ?: lastSegment(sourcePath))
|
||||||
@@ -84,9 +103,13 @@ fun StubElement<out PsiElement>.serializeToString(): String {
|
|||||||
fun VirtualFile.findClassFileByName(className: String): VirtualFile {
|
fun VirtualFile.findClassFileByName(className: String): VirtualFile {
|
||||||
val files = LinkedHashSet<VirtualFile>()
|
val files = LinkedHashSet<VirtualFile>()
|
||||||
VfsUtilCore.iterateChildrenRecursively(
|
VfsUtilCore.iterateChildrenRecursively(
|
||||||
this,
|
this,
|
||||||
{ virtualFile -> virtualFile.isDirectory || virtualFile.name == "$className.class" },
|
{ virtualFile ->
|
||||||
{ virtualFile -> if (!virtualFile.isDirectory) files.addIfNotNull(virtualFile); true })
|
virtualFile.isDirectory || virtualFile.name == "$className.class"
|
||||||
|
},
|
||||||
|
{ virtualFile ->
|
||||||
|
if (!virtualFile.isDirectory) files.addIfNotNull(virtualFile); true
|
||||||
|
})
|
||||||
|
|
||||||
return files.single()
|
return files.single()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user