Refactor metadata serialization for using after frontend
for "tight" IC cycle
This commit is contained in:
@@ -404,7 +404,7 @@ class GenerationState private constructor(
|
||||
classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && origin.originKind in doNotGenerateInLightClassMode
|
||||
|
||||
companion object {
|
||||
private val LANGUAGE_TO_METADATA_VERSION = EnumMap<LanguageVersion, JvmMetadataVersion>(LanguageVersion::class.java).apply {
|
||||
val LANGUAGE_TO_METADATA_VERSION = EnumMap<LanguageVersion, JvmMetadataVersion>(LanguageVersion::class.java).apply {
|
||||
val oldMetadataVersion = JvmMetadataVersion(1, 1, 18)
|
||||
this[KOTLIN_1_0] = oldMetadataVersion
|
||||
this[KOTLIN_1_1] = oldMetadataVersion
|
||||
|
||||
+1
-1
@@ -24,7 +24,7 @@ class FirJvmBackendExtension(private val session: FirSession, private val compon
|
||||
bindings: JvmSerializationBindings,
|
||||
parentSerializer: MetadataSerializer?
|
||||
): MetadataSerializer {
|
||||
return FirMetadataSerializer(session, context, klass, bindings, components, parentSerializer)
|
||||
return makeFirMetadataSerializerForIrClass(session, context, klass, bindings, components, parentSerializer)
|
||||
}
|
||||
|
||||
override fun generateMetadataExtraFlags(abiStability: JvmAbiStability?): Int =
|
||||
|
||||
+33
-17
@@ -19,15 +19,17 @@ import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.utils.*
|
||||
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
|
||||
import org.jetbrains.kotlin.fir.render
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
|
||||
import org.jetbrains.kotlin.fir.types.isBuiltinFunctionalType
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementAwareStringTable
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
|
||||
import org.jetbrains.kotlin.fir.serialization.FirSerializerExtension
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.MetadataSource
|
||||
import org.jetbrains.kotlin.load.kotlin.NON_EXISTENT_CLASS_NAME
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ClassMapperLite
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmFlags
|
||||
@@ -43,22 +45,36 @@ import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
class FirJvmSerializerExtension(
|
||||
override val session: FirSession,
|
||||
private val bindings: JvmSerializationBindings,
|
||||
state: GenerationState,
|
||||
private val irClass: IrClass,
|
||||
private val metadata: MetadataSource?,
|
||||
private val localDelegatedProperties: List<FirProperty>,
|
||||
private val approximator: AbstractTypeApproximator,
|
||||
typeMapper: IrTypeMapper,
|
||||
private val components: Fir2IrComponents
|
||||
private val scopeSession: ScopeSession,
|
||||
private val globalBindings: JvmSerializationBindings,
|
||||
private val useTypeTable: Boolean,
|
||||
private val moduleName: String,
|
||||
private val classBuilderMode: ClassBuilderMode,
|
||||
private val isParamAssertionsDisabled: Boolean,
|
||||
private val unifiedNullChecks: Boolean,
|
||||
override val metadataVersion: BinaryVersion,
|
||||
private val jvmDefaultMode: JvmDefaultMode,
|
||||
override val stringTable: FirElementAwareStringTable
|
||||
) : FirSerializerExtension() {
|
||||
private val globalBindings = state.globalSerializationBindings
|
||||
override val stringTable = FirJvmElementAwareStringTable(typeMapper, components)
|
||||
private val useTypeTable = state.useTypeTableInSerializer
|
||||
private val moduleName = state.moduleName
|
||||
private val classBuilderMode = state.classBuilderMode
|
||||
private val isParamAssertionsDisabled = state.isParamAssertionsDisabled
|
||||
private val unifiedNullChecks = state.unifiedNullChecks
|
||||
override val metadataVersion = state.metadataVersion
|
||||
private val jvmDefaultMode = state.jvmDefaultMode
|
||||
|
||||
constructor(
|
||||
session: FirSession,
|
||||
bindings: JvmSerializationBindings,
|
||||
state: GenerationState,
|
||||
metadata: MetadataSource?,
|
||||
localDelegatedProperties: List<FirProperty>,
|
||||
approximator: AbstractTypeApproximator,
|
||||
typeMapper: IrTypeMapper,
|
||||
components: Fir2IrComponents
|
||||
) : this(
|
||||
session, bindings, metadata, localDelegatedProperties, approximator, components.scopeSession,
|
||||
state.globalSerializationBindings, state.useTypeTableInSerializer, state.moduleName, state.classBuilderMode,
|
||||
state.isParamAssertionsDisabled, state.unifiedNullChecks, state.metadataVersion, state.jvmDefaultMode,
|
||||
FirJvmElementAwareStringTable(typeMapper, components)
|
||||
)
|
||||
|
||||
override fun shouldUseTypeTable(): Boolean = useTypeTable
|
||||
override fun shouldSerializeFunction(function: FirFunction): Boolean {
|
||||
@@ -84,7 +100,7 @@ class FirJvmSerializerExtension(
|
||||
versionRequirementTable: MutableVersionRequirementTable,
|
||||
childSerializer: FirElementSerializer
|
||||
) {
|
||||
assert((irClass.metadata as FirMetadataSource.Class).fir == klass)
|
||||
assert((metadata as FirMetadataSource.Class).fir == klass)
|
||||
if (moduleName != JvmProtoBufUtil.DEFAULT_MODULE_NAME) {
|
||||
proto.setExtension(JvmProtoBuf.classModuleName, stringTable.getStringIndex(moduleName))
|
||||
}
|
||||
@@ -140,7 +156,7 @@ class FirJvmSerializerExtension(
|
||||
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>>
|
||||
) {
|
||||
for (localVariable in localDelegatedProperties) {
|
||||
val serializer = FirElementSerializer.createForLambda(session, components.scopeSession,this, approximator)
|
||||
val serializer = FirElementSerializer.createForLambda(session, scopeSession,this, approximator)
|
||||
proto.addExtension(extension, serializer.propertyProto(localVariable)?.build() ?: continue)
|
||||
}
|
||||
}
|
||||
|
||||
+223
-142
@@ -7,11 +7,17 @@ package org.jetbrains.kotlin.fir.backend.jvm
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.mapping.IrTypeMapper
|
||||
import org.jetbrains.kotlin.backend.jvm.mapping.mapClass
|
||||
import org.jetbrains.kotlin.backend.jvm.metadata.MetadataSerializer
|
||||
import org.jetbrains.kotlin.codegen.ClassBuilderMode
|
||||
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.config.*
|
||||
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.containingClassForLocal
|
||||
import org.jetbrains.kotlin.fir.declarations.*
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildAnonymousFunction
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildProperty
|
||||
@@ -19,17 +25,21 @@ import org.jetbrains.kotlin.fir.declarations.builder.buildPropertyAccessor
|
||||
import org.jetbrains.kotlin.fir.declarations.builder.buildValueParameterCopy
|
||||
import org.jetbrains.kotlin.fir.diagnostics.ConeIntermediateDiagnostic
|
||||
import org.jetbrains.kotlin.fir.languageVersionSettings
|
||||
import org.jetbrains.kotlin.fir.packageFqName
|
||||
import org.jetbrains.kotlin.fir.resolve.ScopeSession
|
||||
import org.jetbrains.kotlin.fir.resolve.toFirRegularClass
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementAwareStringTable
|
||||
import org.jetbrains.kotlin.fir.serialization.FirElementSerializer
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirAnonymousFunctionSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirDelegateFieldSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertyAccessorSymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||
import org.jetbrains.kotlin.fir.symbols.impl.*
|
||||
import org.jetbrains.kotlin.fir.types.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.MetadataSource
|
||||
import org.jetbrains.kotlin.ir.util.getPackageFragment
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.serialization.JvmStringTable
|
||||
import org.jetbrains.kotlin.modules.TargetId
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.protobuf.MessageLite
|
||||
import org.jetbrains.kotlin.types.AbstractTypeApproximator
|
||||
import org.jetbrains.kotlin.types.TypeApproximatorConfiguration
|
||||
@@ -37,154 +47,90 @@ import org.jetbrains.kotlin.types.model.SimpleTypeMarker
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||
|
||||
class FirMetadataSerializer(
|
||||
private val session: FirSession,
|
||||
private val context: JvmBackendContext,
|
||||
private val irClass: IrClass,
|
||||
private val serializationBindings: JvmSerializationBindings,
|
||||
fun makeFirMetadataSerializerForIrClass(
|
||||
session: FirSession,
|
||||
context: JvmBackendContext,
|
||||
irClass: IrClass,
|
||||
serializationBindings: JvmSerializationBindings,
|
||||
components: Fir2IrComponents,
|
||||
parent: MetadataSerializer?
|
||||
) : MetadataSerializer {
|
||||
private val approximator = object : AbstractTypeApproximator(session.typeContext, session.languageVersionSettings) {
|
||||
override fun createErrorType(debugName: String): SimpleTypeMarker {
|
||||
return ConeErrorType(ConeIntermediateDiagnostic(debugName))
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirTypeRef.approximated(toSuper: Boolean, typeParameterSet: MutableCollection<FirTypeParameter>): FirTypeRef {
|
||||
val approximatedType = if (toSuper)
|
||||
approximator.approximateToSuperType(coneType, TypeApproximatorConfiguration.PublicDeclaration)
|
||||
else
|
||||
approximator.approximateToSubType(coneType, TypeApproximatorConfiguration.PublicDeclaration)
|
||||
return withReplacedConeType(approximatedType as? ConeKotlinType).apply { coneType.collectTypeParameters(typeParameterSet) }
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.collectTypeParameters(c: MutableCollection<FirTypeParameter>) {
|
||||
when (this) {
|
||||
is ConeFlexibleType -> {
|
||||
lowerBound.collectTypeParameters(c)
|
||||
upperBound.collectTypeParameters(c)
|
||||
}
|
||||
is ConeClassLikeType ->
|
||||
for (projection in type.typeArguments) {
|
||||
if (projection is ConeKotlinTypeProjection) {
|
||||
projection.type.collectTypeParameters(c)
|
||||
}
|
||||
}
|
||||
is ConeTypeParameterType -> c.add(lookupTag.typeParameterSymbol.fir)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirFunction.copyToFreeAnonymousFunction(): FirAnonymousFunction {
|
||||
val function = this
|
||||
return buildAnonymousFunction {
|
||||
val typeParameterSet = function.typeParameters.filterIsInstanceTo(mutableSetOf<FirTypeParameter>())
|
||||
moduleData = function.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
symbol = FirAnonymousFunctionSymbol()
|
||||
returnTypeRef = function.returnTypeRef.approximated(toSuper = true, typeParameterSet)
|
||||
receiverTypeRef = function.receiverTypeRef?.approximated(toSuper = false, typeParameterSet)
|
||||
isLambda = (function as? FirAnonymousFunction)?.isLambda == true
|
||||
hasExplicitParameterList = (function as? FirAnonymousFunction)?.hasExplicitParameterList == true
|
||||
valueParameters.addAll(function.valueParameters.map {
|
||||
buildValueParameterCopy(it) {
|
||||
returnTypeRef = it.returnTypeRef.approximated(toSuper = false, typeParameterSet)
|
||||
}
|
||||
})
|
||||
typeParameters += typeParameterSet
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirPropertyAccessor.copyToFreeAccessor(): FirPropertyAccessor {
|
||||
val accessor = this
|
||||
return buildPropertyAccessor {
|
||||
val typeParameterSet = accessor.typeParameters.toMutableSet()
|
||||
moduleData = accessor.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = accessor.returnTypeRef.approximated(toSuper = true, typeParameterSet)
|
||||
symbol = FirPropertyAccessorSymbol()
|
||||
isGetter = accessor.isGetter
|
||||
status = accessor.status
|
||||
accessor.valueParameters.mapTo(valueParameters) {
|
||||
buildValueParameterCopy(it) {
|
||||
returnTypeRef = it.returnTypeRef.approximated(toSuper = false, typeParameterSet)
|
||||
}
|
||||
}
|
||||
annotations += accessor.annotations
|
||||
typeParameters += typeParameterSet
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirProperty.copyToFreeProperty(): FirProperty {
|
||||
val property = this
|
||||
return buildProperty {
|
||||
val typeParameterSet = property.typeParameters.toMutableSet()
|
||||
moduleData = property.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
symbol = FirPropertySymbol(property.symbol.callableId)
|
||||
returnTypeRef = property.returnTypeRef.approximated(toSuper = true, typeParameterSet)
|
||||
receiverTypeRef = property.receiverTypeRef?.approximated(toSuper = false, typeParameterSet)
|
||||
name = property.name
|
||||
initializer = property.initializer
|
||||
delegate = property.delegate
|
||||
delegateFieldSymbol = property.delegateFieldSymbol?.let {
|
||||
FirDelegateFieldSymbol(it.callableId)
|
||||
}
|
||||
getter = property.getter?.copyToFreeAccessor()
|
||||
setter = property.setter?.copyToFreeAccessor()
|
||||
isVar = property.isVar
|
||||
isLocal = property.isLocal
|
||||
status = property.status
|
||||
dispatchReceiverType = property.dispatchReceiverType
|
||||
attributes = property.attributes.copy()
|
||||
annotations += property.annotations
|
||||
typeParameters += typeParameterSet
|
||||
}.apply {
|
||||
delegateFieldSymbol?.bind(this)
|
||||
}
|
||||
}
|
||||
|
||||
private val localDelegatedProperties = context.localDelegatedProperties[irClass.attributeOwnerId]?.map {
|
||||
(it.owner.metadata as FirMetadataSource.Property).fir.copyToFreeProperty()
|
||||
): FirMetadataSerializer {
|
||||
val approximator = TypeApproximatorForMetadataSerializer(session)
|
||||
val localDelegatedProperties = context.localDelegatedProperties[irClass.attributeOwnerId]?.map {
|
||||
(it.owner.metadata as FirMetadataSource.Property).fir.copyToFreeProperty(approximator)
|
||||
} ?: emptyList()
|
||||
|
||||
private val serializerExtension = FirJvmSerializerExtension(
|
||||
session, serializationBindings, context.state, irClass, localDelegatedProperties, approximator,
|
||||
context.typeMapper, components
|
||||
val firSerializerExtension = FirJvmSerializerExtension(
|
||||
session, serializationBindings, context.state, irClass.metadata, localDelegatedProperties,
|
||||
approximator, context.typeMapper, components
|
||||
)
|
||||
return FirMetadataSerializer(
|
||||
context.state.globalSerializationBindings,
|
||||
serializationBindings,
|
||||
firSerializerExtension,
|
||||
approximator,
|
||||
makeElementSerializer(irClass.metadata, components.session, components.scopeSession, firSerializerExtension, approximator, parent)
|
||||
)
|
||||
}
|
||||
|
||||
private val serializer: FirElementSerializer? =
|
||||
when (val metadata = irClass.metadata) {
|
||||
is FirMetadataSource.Class -> FirElementSerializer.create(
|
||||
components.session,
|
||||
components.scopeSession,
|
||||
metadata.fir, serializerExtension, (parent as? FirMetadataSerializer)?.serializer, approximator
|
||||
)
|
||||
is FirMetadataSource.File -> FirElementSerializer.createTopLevel(
|
||||
components.session,
|
||||
components.scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(
|
||||
components.session,
|
||||
components.scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
@OptIn(LookupTagInternals::class)
|
||||
fun makeLocalFirMetadataSerializerForMetadataSource(
|
||||
metadata: MetadataSource?,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
globalSerializationBindings: JvmSerializationBindings,
|
||||
parent: MetadataSerializer?,
|
||||
targetId: TargetId,
|
||||
configuration: CompilerConfiguration
|
||||
): FirMetadataSerializer {
|
||||
val serializationBindings = JvmSerializationBindings()
|
||||
val approximator = TypeApproximatorForMetadataSerializer(session)
|
||||
|
||||
val stringTable = object : JvmStringTable(null), FirElementAwareStringTable {
|
||||
override fun getLocalClassIdReplacement(firClass: FirClass): ClassId =
|
||||
((firClass as? FirRegularClass)?.containingClassForLocal()?.toFirRegularClass(session) ?: firClass)
|
||||
.symbol.classId
|
||||
}
|
||||
|
||||
val firSerializerExtension = FirJvmSerializerExtension(
|
||||
session, serializationBindings, metadata, emptyList(), approximator, scopeSession,
|
||||
globalSerializationBindings,
|
||||
configuration.getBoolean(JVMConfigurationKeys.USE_TYPE_TABLE),
|
||||
targetId.name,
|
||||
ClassBuilderMode.ABI,
|
||||
configuration.getBoolean(JVMConfigurationKeys.DISABLE_PARAM_ASSERTIONS),
|
||||
session.languageVersionSettings.apiVersion >= ApiVersion.KOTLIN_1_4 &&
|
||||
!configuration.getBoolean(JVMConfigurationKeys.NO_UNIFIED_NULL_CHECKS),
|
||||
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
|
||||
?: GenerationState.LANGUAGE_TO_METADATA_VERSION.getValue(session.languageVersionSettings.languageVersion),
|
||||
session.languageVersionSettings.getFlag(JvmAnalysisFlags.jvmDefaultMode),
|
||||
stringTable
|
||||
)
|
||||
return FirMetadataSerializer(
|
||||
globalSerializationBindings,
|
||||
serializationBindings,
|
||||
firSerializerExtension,
|
||||
approximator,
|
||||
makeElementSerializer(metadata, session, scopeSession, firSerializerExtension, approximator, parent)
|
||||
)
|
||||
}
|
||||
|
||||
class FirMetadataSerializer(
|
||||
private val globalSerializationBindings: JvmSerializationBindings,
|
||||
private val serializationBindings: JvmSerializationBindings,
|
||||
private val serializerExtension: FirJvmSerializerExtension,
|
||||
private val approximator: AbstractTypeApproximator,
|
||||
internal val serializer: FirElementSerializer?
|
||||
) : MetadataSerializer {
|
||||
|
||||
override fun serialize(metadata: MetadataSource): Pair<MessageLite, JvmStringTable>? {
|
||||
val message = when (metadata) {
|
||||
is FirMetadataSource.Class -> serializer!!.classProto(metadata.fir).build()
|
||||
is FirMetadataSource.File ->
|
||||
serializer!!.packagePartProto(irClass.getPackageFragment()!!.fqName, metadata.fir).apply {
|
||||
serializer!!.packagePartProto(metadata.fir.packageFqName, metadata.fir).apply {
|
||||
serializerExtension.serializeJvmPackage(this)
|
||||
}.build()
|
||||
is FirMetadataSource.Function -> {
|
||||
val withTypeParameters = metadata.fir.copyToFreeAnonymousFunction()
|
||||
val withTypeParameters = metadata.fir.copyToFreeAnonymousFunction(approximator)
|
||||
serializationBindings.get(FirJvmSerializerExtension.METHOD_FOR_FIR_FUNCTION, metadata.fir)?.let {
|
||||
serializationBindings.put(FirJvmSerializerExtension.METHOD_FOR_FIR_FUNCTION, withTypeParameters, it)
|
||||
}
|
||||
@@ -204,7 +150,7 @@ class FirMetadataSerializer(
|
||||
FirJvmSerializerExtension.DELEGATE_METHOD_FOR_FIR_VARIABLE
|
||||
else -> throw IllegalStateException("invalid origin $origin for property-related method $signature")
|
||||
}
|
||||
context.state.globalSerializationBindings.put(slice, fir, signature)
|
||||
globalSerializationBindings.put(slice, fir, signature)
|
||||
}
|
||||
|
||||
override fun bindMethodMetadata(metadata: MetadataSource.Function, signature: Method) {
|
||||
@@ -214,6 +160,141 @@ class FirMetadataSerializer(
|
||||
|
||||
override fun bindFieldMetadata(metadata: MetadataSource.Property, signature: Pair<Type, String>) {
|
||||
val fir = (metadata as FirMetadataSource.Property).fir
|
||||
context.state.globalSerializationBindings.put(FirJvmSerializerExtension.FIELD_FOR_PROPERTY, fir, signature)
|
||||
globalSerializationBindings.put(FirJvmSerializerExtension.FIELD_FOR_PROPERTY, fir, signature)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun makeElementSerializer(
|
||||
metadata: MetadataSource?,
|
||||
session: FirSession,
|
||||
scopeSession: ScopeSession,
|
||||
serializerExtension: FirJvmSerializerExtension,
|
||||
approximator: AbstractTypeApproximator,
|
||||
parent: MetadataSerializer?
|
||||
): FirElementSerializer? =
|
||||
when (metadata) {
|
||||
is FirMetadataSource.Class -> FirElementSerializer.create(
|
||||
session, scopeSession,
|
||||
metadata.fir,
|
||||
serializerExtension,
|
||||
(parent as? FirMetadataSerializer)?.serializer,
|
||||
approximator
|
||||
)
|
||||
is FirMetadataSource.File -> FirElementSerializer.createTopLevel(
|
||||
session, scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(
|
||||
session, scopeSession,
|
||||
serializerExtension,
|
||||
approximator
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal class TypeApproximatorForMetadataSerializer(session: FirSession) :
|
||||
AbstractTypeApproximator(session.typeContext, session.languageVersionSettings) {
|
||||
|
||||
override fun createErrorType(debugName: String): SimpleTypeMarker {
|
||||
return ConeErrorType(ConeIntermediateDiagnostic(debugName))
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirFunction.copyToFreeAnonymousFunction(approximator: AbstractTypeApproximator): FirAnonymousFunction {
|
||||
val function = this
|
||||
return buildAnonymousFunction {
|
||||
val typeParameterSet = function.typeParameters.filterIsInstanceTo(mutableSetOf<FirTypeParameter>())
|
||||
moduleData = function.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
symbol = FirAnonymousFunctionSymbol()
|
||||
returnTypeRef = function.returnTypeRef.approximated(approximator, typeParameterSet, toSuper = true)
|
||||
receiverTypeRef = function.receiverTypeRef?.approximated(approximator, typeParameterSet, toSuper = false)
|
||||
isLambda = (function as? FirAnonymousFunction)?.isLambda == true
|
||||
hasExplicitParameterList = (function as? FirAnonymousFunction)?.hasExplicitParameterList == true
|
||||
valueParameters.addAll(function.valueParameters.map {
|
||||
buildValueParameterCopy(it) {
|
||||
returnTypeRef = it.returnTypeRef.approximated(approximator, typeParameterSet, toSuper = false)
|
||||
}
|
||||
})
|
||||
typeParameters += typeParameterSet
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirPropertyAccessor.copyToFreeAccessor(approximator: AbstractTypeApproximator): FirPropertyAccessor {
|
||||
val accessor = this
|
||||
return buildPropertyAccessor {
|
||||
val typeParameterSet = accessor.typeParameters.toMutableSet()
|
||||
moduleData = accessor.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
returnTypeRef = accessor.returnTypeRef.approximated(approximator, typeParameterSet, toSuper = true)
|
||||
symbol = FirPropertyAccessorSymbol()
|
||||
isGetter = accessor.isGetter
|
||||
status = accessor.status
|
||||
accessor.valueParameters.mapTo(valueParameters) {
|
||||
buildValueParameterCopy(it) {
|
||||
returnTypeRef = it.returnTypeRef.approximated(approximator, typeParameterSet, toSuper = false)
|
||||
}
|
||||
}
|
||||
annotations += accessor.annotations
|
||||
typeParameters += typeParameterSet
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirProperty.copyToFreeProperty(approximator: AbstractTypeApproximator): FirProperty {
|
||||
val property = this
|
||||
return buildProperty {
|
||||
val typeParameterSet = property.typeParameters.toMutableSet()
|
||||
moduleData = property.moduleData
|
||||
origin = FirDeclarationOrigin.Source
|
||||
symbol = FirPropertySymbol(property.symbol.callableId)
|
||||
returnTypeRef = property.returnTypeRef.approximated(approximator, typeParameterSet, toSuper = true)
|
||||
receiverTypeRef = property.receiverTypeRef?.approximated(approximator, typeParameterSet, toSuper = false)
|
||||
name = property.name
|
||||
initializer = property.initializer
|
||||
delegate = property.delegate
|
||||
delegateFieldSymbol = property.delegateFieldSymbol?.let {
|
||||
FirDelegateFieldSymbol(it.callableId)
|
||||
}
|
||||
getter = property.getter?.copyToFreeAccessor(approximator)
|
||||
setter = property.setter?.copyToFreeAccessor(approximator)
|
||||
isVar = property.isVar
|
||||
isLocal = property.isLocal
|
||||
status = property.status
|
||||
dispatchReceiverType = property.dispatchReceiverType
|
||||
attributes = property.attributes.copy()
|
||||
annotations += property.annotations
|
||||
typeParameters += typeParameterSet
|
||||
}.apply {
|
||||
delegateFieldSymbol?.bind(this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun FirTypeRef.approximated(
|
||||
approximator: AbstractTypeApproximator,
|
||||
typeParameterSet: MutableCollection<FirTypeParameter>,
|
||||
toSuper: Boolean
|
||||
): FirTypeRef {
|
||||
val approximatedType = if (toSuper)
|
||||
approximator.approximateToSuperType(coneType, TypeApproximatorConfiguration.PublicDeclaration)
|
||||
else
|
||||
approximator.approximateToSubType(coneType, TypeApproximatorConfiguration.PublicDeclaration)
|
||||
return withReplacedConeType(approximatedType as? ConeKotlinType).apply { coneType.collectTypeParameters(typeParameterSet) }
|
||||
}
|
||||
|
||||
private fun ConeKotlinType.collectTypeParameters(c: MutableCollection<FirTypeParameter>) {
|
||||
when (this) {
|
||||
is ConeFlexibleType -> {
|
||||
lowerBound.collectTypeParameters(c)
|
||||
upperBound.collectTypeParameters(c)
|
||||
}
|
||||
is ConeClassLikeType ->
|
||||
for (projection in type.typeArguments) {
|
||||
if (projection is ConeKotlinTypeProjection) {
|
||||
projection.type.collectTypeParameters(c)
|
||||
}
|
||||
}
|
||||
is ConeTypeParameterType -> c.add(lookupTag.typeParameterSymbol.fir)
|
||||
else -> Unit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.StringTableTypes.Record
|
||||
import org.jetbrains.kotlin.metadata.jvm.JvmProtoBuf.StringTableTypes.Record.Operation.*
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolver
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmNameResolverBase
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.getClassId
|
||||
@@ -81,7 +82,7 @@ class JvmNameResolverTest : KtUsefulTestCase() {
|
||||
}
|
||||
|
||||
fun testPredefined() {
|
||||
for ((index, predefined) in JvmNameResolver.PREDEFINED_STRINGS.withIndex()) {
|
||||
for ((index, predefined) in JvmNameResolverBase.PREDEFINED_STRINGS.withIndex()) {
|
||||
assertEquals("Predefined string failed: $predefined (index $index)", predefined, str("ignored", predefinedIndex = index))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user