FIR: serialize correct fqnames for local classes
This commit is contained in:
+1
-1
@@ -391,7 +391,7 @@ object KotlinToJVMBytecodeCompiler {
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, moduleFragment, symbolTable, sourceManager, extensions
|
||||
) { context, irClass, _, serializationBindings, parent ->
|
||||
FirMetadataSerializer(session, context, irClass, serializationBindings, parent)
|
||||
FirMetadataSerializer(session, context, irClass, serializationBindings, components, parent)
|
||||
}
|
||||
CodegenFactory.doCheckCancelled(generationState)
|
||||
generationState.factory.done()
|
||||
|
||||
+3
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.serialization
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.metadata.serialization.StringTable
|
||||
@@ -16,11 +17,11 @@ interface FirElementAwareStringTable : StringTable {
|
||||
|
||||
fun getFqNameIndex(classLikeDeclaration: FirClassLikeDeclaration<*>): Int {
|
||||
val classId = classLikeDeclaration.symbol.classId.takeIf { !it.isLocal }
|
||||
?: getLocalClassIdReplacement(classLikeDeclaration)
|
||||
?: getLocalClassIdReplacement(classLikeDeclaration as FirClass<*>)
|
||||
?: throw IllegalStateException("Cannot get FQ name of local class: ${classLikeDeclaration.render()}")
|
||||
|
||||
return getQualifiedClassNameIndex(classId)
|
||||
}
|
||||
|
||||
fun getLocalClassIdReplacement(classLikeDeclaration: FirClassLikeDeclaration<*>): ClassId? = null
|
||||
fun getLocalClassIdReplacement(firClass: FirClass<*>): ClassId? = null
|
||||
}
|
||||
|
||||
+17
-15
@@ -5,30 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClassLikeDeclaration
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.IrTypeMapper
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.mapClass
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementAwareStringTable
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
class FirJvmElementAwareStringTable(
|
||||
private val typeMapper: IrTypeMapper,
|
||||
private val components: Fir2IrComponents,
|
||||
nameResolver: JvmNameResolver? = null
|
||||
) : JvmStringTable(nameResolver), FirElementAwareStringTable {
|
||||
override fun getLocalClassIdReplacement(classLikeDeclaration: FirClassLikeDeclaration<*>): ClassId {
|
||||
return when (classLikeDeclaration.symbol.classId.outerClassId) {
|
||||
// TODO: how to determine parent declaration for FIR local class properly?
|
||||
//is ClassifierDescriptorWithTypeParameters -> getLocalClassIdReplacement(container).createNestedClassId(descriptor.name)
|
||||
// null -> {
|
||||
// throw IllegalStateException(
|
||||
// "getLocalClassIdReplacement should only be called for local classes: ${classLikeDeclaration.render()}"
|
||||
// )
|
||||
// }
|
||||
override fun getLocalClassIdReplacement(firClass: FirClass<*>): ClassId =
|
||||
components.classifierStorage.getCachedIrClass(firClass)?.getLocalClassIdReplacement()
|
||||
?: throw AssertionError("not a local class: ${firClass.symbol.classId}")
|
||||
|
||||
private fun IrClass.getLocalClassIdReplacement(): ClassId =
|
||||
when (val parent = parent) {
|
||||
is IrClass -> parent.getLocalClassIdReplacement().createNestedClassId(name)
|
||||
else -> {
|
||||
classLikeDeclaration.symbol.classId
|
||||
// TODO: typeMapper.mapClass
|
||||
//val fqName = FqName(typeMapper.mapClass(descriptor).internalName.replace('/', '.'))
|
||||
//ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true)
|
||||
val fqName = FqName(typeMapper.mapClass(this).internalName.replace('/', '.'))
|
||||
ClassId(fqName.parent(), FqName.topLevel(fqName.shortName()), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+6
-2
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.fir.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.IrTypeMapper
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
@@ -12,6 +13,7 @@ import org.jetbrains.kotlin.config.JvmDefaultMode
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.resolve.firProvider
|
||||
@@ -41,10 +43,12 @@ class FirJvmSerializerExtension(
|
||||
state: GenerationState,
|
||||
private val irClass: IrClass,
|
||||
private val localDelegatedProperties: List<FirProperty>,
|
||||
private val approximator: AbstractTypeApproximator
|
||||
private val approximator: AbstractTypeApproximator,
|
||||
typeMapper: IrTypeMapper,
|
||||
components: Fir2IrComponents
|
||||
) : FirSerializerExtension() {
|
||||
private val globalBindings = state.globalSerializationBindings
|
||||
override val stringTable = FirJvmElementAwareStringTable()
|
||||
override val stringTable = FirJvmElementAwareStringTable(typeMapper, components)
|
||||
private val useTypeTable = state.useTypeTableInSerializer
|
||||
private val moduleName = state.moduleName
|
||||
private val classBuilderMode = state.classBuilderMode
|
||||
|
||||
+6
-2
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.MetadataSerializer
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
|
||||
import org.jetbrains.kotlin.fir.FirSession
|
||||
import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
|
||||
import org.jetbrains.kotlin.fir.backend.FirMetadataSource
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
||||
@@ -39,6 +40,7 @@ class FirMetadataSerializer(
|
||||
private val context: JvmBackendContext,
|
||||
private val irClass: IrClass,
|
||||
private val serializationBindings: JvmSerializationBindings,
|
||||
components: Fir2IrComponents,
|
||||
parent: MetadataSerializer?
|
||||
) : MetadataSerializer {
|
||||
private val approximator = object : AbstractTypeApproximator(session.typeContext) {
|
||||
@@ -144,8 +146,10 @@ class FirMetadataSerializer(
|
||||
(it.owner.metadata as FirMetadataSource.Property).fir.copyToFreeProperty()
|
||||
} ?: emptyList()
|
||||
|
||||
private val serializerExtension =
|
||||
FirJvmSerializerExtension(session, serializationBindings, context.state, irClass, localDelegatedProperties, approximator)
|
||||
private val serializerExtension = FirJvmSerializerExtension(
|
||||
session, serializationBindings, context.state, irClass, localDelegatedProperties, approximator,
|
||||
context.typeMapper, components
|
||||
)
|
||||
|
||||
private val serializer: FirElementSerializer? =
|
||||
when (val metadata = irClass.metadata) {
|
||||
|
||||
@@ -135,7 +135,7 @@ class Fir2IrClassifierStorage(
|
||||
return this
|
||||
}
|
||||
|
||||
internal fun getCachedIrClass(klass: FirClass<*>): IrClass? {
|
||||
fun getCachedIrClass(klass: FirClass<*>): IrClass? {
|
||||
return if (klass is FirAnonymousObject || klass is FirRegularClass && klass.visibility == Visibilities.Local) {
|
||||
localStorage.getLocalClass(klass)
|
||||
} else {
|
||||
|
||||
Generated
+5
@@ -28465,6 +28465,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/simpleGetProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withLocalType.kt")
|
||||
public void testWithLocalType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/withLocalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/properties/accessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// WITH_REFLECT
|
||||
// WITH_RUNTIME
|
||||
import kotlin.reflect.full.declaredMemberProperties
|
||||
|
||||
fun box(): String {
|
||||
class A(val x: String)
|
||||
class B(val y: A)
|
||||
return (B::class.declaredMemberProperties.single().invoke(B(A("OK"))) as A).x
|
||||
}
|
||||
@@ -144,7 +144,7 @@ object GenerationUtils {
|
||||
codegenFactory.generateModuleInFrontendIRMode(
|
||||
generationState, moduleFragment, symbolTable, sourceManager, extensions
|
||||
) { context, irClass, _, serializationBindings, parent ->
|
||||
FirMetadataSerializer(session, context, irClass, serializationBindings, parent)
|
||||
FirMetadataSerializer(session, context, irClass, serializationBindings, components, parent)
|
||||
}
|
||||
|
||||
generationState.factory.done()
|
||||
|
||||
+5
@@ -28831,6 +28831,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/simpleGetProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withLocalType.kt")
|
||||
public void testWithLocalType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/withLocalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/properties/accessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+5
@@ -26465,6 +26465,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/simpleGetProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withLocalType.kt")
|
||||
public void testWithLocalType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/withLocalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/properties/accessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
+5
@@ -28465,6 +28465,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/simpleGetProperties.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("withLocalType.kt")
|
||||
public void testWithLocalType() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/reflection/properties/withLocalType.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/codegen/box/reflection/properties/accessors")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user