Write "hasEnumEntries" flag into metadata when feature enabled

^KT-53929 Fixed
This commit is contained in:
Roman Efremov
2023-01-02 11:47:10 +01:00
parent 3c5e556ba6
commit 14b4cdc7c4
35 changed files with 210 additions and 80 deletions
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
@@ -64,6 +65,7 @@ class FirElementSerializer private constructor(
private val versionRequirementTable: MutableVersionRequirementTable?,
private val serializeTypeTableToFunction: Boolean,
private val typeApproximator: AbstractTypeApproximator,
private val languageVersionSettings: LanguageVersionSettings,
) {
private val contractSerializer = FirContractSerializer()
@@ -94,6 +96,8 @@ class FirElementSerializer private constructor(
val regularClass = klass as? FirRegularClass
val modality = regularClass?.modality ?: Modality.FINAL
val hasEnumEntries = klass.classKind == ClassKind.ENUM_CLASS && languageVersionSettings.supportsFeature(LanguageFeature.EnumEntries)
val flags = Flags.getClassFlags(
klass.nonSourceAnnotations(session).isNotEmpty(),
ProtoEnumFlags.visibility(regularClass?.let { normalizeVisibility(it) } ?: Visibilities.Local),
@@ -104,7 +108,8 @@ class FirElementSerializer private constructor(
regularClass?.isExternal == true,
regularClass?.isExpect == true,
regularClass?.isInline == true,
regularClass?.isFun == true
regularClass?.isFun == true,
hasEnumEntries,
)
if (flags != builder.flags) {
builder.flags = flags
@@ -880,7 +885,7 @@ class FirElementSerializer private constructor(
FirElementSerializer(
session, scopeSession, declaration, Interner(typeParameters), extension,
typeTable, versionRequirementTable, serializeTypeTableToFunction = false,
typeApproximator
typeApproximator, languageVersionSettings
)
val stringTable: FirElementAwareStringTable
@@ -1010,12 +1015,14 @@ class FirElementSerializer private constructor(
scopeSession: ScopeSession,
extension: FirSerializerExtension,
typeApproximator: AbstractTypeApproximator,
languageVersionSettings: LanguageVersionSettings,
): FirElementSerializer =
FirElementSerializer(
session, scopeSession, null,
Interner(), extension, MutableTypeTable(), MutableVersionRequirementTable(),
serializeTypeTableToFunction = false,
typeApproximator
typeApproximator,
languageVersionSettings,
)
@JvmStatic
@@ -1024,12 +1031,14 @@ class FirElementSerializer private constructor(
scopeSession: ScopeSession,
extension: FirSerializerExtension,
typeApproximator: AbstractTypeApproximator,
languageVersionSettings: LanguageVersionSettings,
): FirElementSerializer =
FirElementSerializer(
session, scopeSession, null,
Interner(), extension, MutableTypeTable(),
versionRequirementTable = null, serializeTypeTableToFunction = true,
typeApproximator
typeApproximator,
languageVersionSettings,
)
@JvmStatic
@@ -1040,13 +1049,17 @@ class FirElementSerializer private constructor(
extension: FirSerializerExtension,
parentSerializer: FirElementSerializer?,
typeApproximator: AbstractTypeApproximator,
languageVersionSettings: LanguageVersionSettings,
): FirElementSerializer {
val parentClassId = klass.symbol.classId.outerClassId
val parent = if (parentClassId != null && !parentClassId.isLocal) {
val parentClass = session.symbolProvider.getClassLikeSymbolByClassId(parentClassId)!!.fir as FirRegularClass
parentSerializer ?: create(session, scopeSession, parentClass, extension, null, typeApproximator)
parentSerializer ?: create(
session, scopeSession, parentClass, extension, null, typeApproximator,
languageVersionSettings,
)
} else {
createTopLevel(session, scopeSession, extension, typeApproximator)
createTopLevel(session, scopeSession, extension, typeApproximator, languageVersionSettings)
}
// Calculate type parameter ids for the outer class beforehand, as it would've had happened if we were always
@@ -1065,7 +1078,8 @@ class FirElementSerializer private constructor(
MutableVersionRequirementTable()
},
serializeTypeTableToFunction = false,
typeApproximator
typeApproximator,
languageVersionSettings,
)
for (typeParameter in klass.typeParameters) {
if (typeParameter !is FirTypeParameter) continue
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.backend.common.serialization.metadata.buildKlibPackageFragment
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.declarations.utils.classId
@@ -17,9 +18,14 @@ import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.SerializableStringTable
fun serializeSingleFirFile(file: FirFile, session: FirSession, scopeSession: ScopeSession, serializerExtension: FirKLibSerializerExtension): ProtoBuf.PackageFragment {
fun serializeSingleFirFile(
file: FirFile, session: FirSession, scopeSession: ScopeSession,
serializerExtension: FirKLibSerializerExtension,
languageVersionSettings: LanguageVersionSettings,
): ProtoBuf.PackageFragment {
val approximator = TypeApproximatorForMetadataSerializer(session)
val packageSerializer = FirElementSerializer.createTopLevel(session, scopeSession, serializerExtension, approximator)
val packageSerializer = FirElementSerializer.createTopLevel(session, scopeSession, serializerExtension, approximator,
languageVersionSettings)
// TODO: typealiases (see klib serializer)
// TODO: split package fragment (see klib serializer)
@@ -30,7 +36,8 @@ fun serializeSingleFirFile(file: FirFile, session: FirSession, scopeSession: Sco
fun List<FirDeclaration>.makeClassesProtoWithNested(): List<Pair<ProtoBuf.Class, Int>> =
// TODO: filter out expects
filterIsInstance<FirClass>().sortedBy { it.classId.asFqNameString() }.flatMap {
val classSerializer = FirElementSerializer.create(session, scopeSession, it, serializerExtension, null, approximator)
val classSerializer = FirElementSerializer.create(session, scopeSession, it, serializerExtension, null,
approximator, languageVersionSettings)
val index = classSerializer.stringTable.getFqNameIndex(it)
listOf(classSerializer.classProto(it).build() to index) + it.declarations.makeClassesProtoWithNested()
}
@@ -10,6 +10,7 @@ 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.JvmDefaultMode
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.fir.FirSession
@@ -18,6 +19,7 @@ import org.jetbrains.kotlin.fir.backend.FirMetadataSource
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.languageVersionSettings
import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.fir.resolve.ScopeSession
import org.jetbrains.kotlin.fir.resolve.providers.firProvider
@@ -156,8 +158,9 @@ class FirJvmSerializerExtension(
proto: BuilderType,
extension: GeneratedMessageLite.GeneratedExtension<MessageType, List<ProtoBuf.Property>>
) {
val languageVersionSettings = session.languageVersionSettings
for (localVariable in localDelegatedProperties) {
val serializer = FirElementSerializer.createForLambda(session, scopeSession,this, approximator)
val serializer = FirElementSerializer.createForLambda(session, scopeSession,this, approximator, languageVersionSettings)
proto.addExtension(extension, serializer.propertyProto(localVariable)?.build() ?: continue)
}
}
@@ -61,7 +61,10 @@ fun makeFirMetadataSerializerForIrClass(
serializationBindings,
firSerializerExtension,
approximator,
makeElementSerializer(irClass.metadata, components.session, components.scopeSession, firSerializerExtension, approximator, parent)
makeElementSerializer(
irClass.metadata, components.session, components.scopeSession, firSerializerExtension, approximator, parent,
context.state.configuration.languageVersionSettings,
)
)
}
@@ -102,7 +105,10 @@ fun makeLocalFirMetadataSerializerForMetadataSource(
serializationBindings,
firSerializerExtension,
approximator,
makeElementSerializer(metadata, session, scopeSession, firSerializerExtension, approximator, parent)
makeElementSerializer(
metadata, session, scopeSession, firSerializerExtension, approximator, parent,
configuration.languageVersionSettings,
)
)
}
@@ -162,7 +168,8 @@ internal fun makeElementSerializer(
scopeSession: ScopeSession,
serializerExtension: FirJvmSerializerExtension,
approximator: AbstractTypeApproximator,
parent: MetadataSerializer?
parent: MetadataSerializer?,
languageVersionSettings: LanguageVersionSettings
): FirElementSerializer? =
when (metadata) {
is FirMetadataSource.Class -> FirElementSerializer.create(
@@ -170,17 +177,20 @@ internal fun makeElementSerializer(
metadata.fir,
serializerExtension,
(parent as? FirMetadataSerializer)?.serializer,
approximator
approximator,
languageVersionSettings,
)
is FirMetadataSource.File -> FirElementSerializer.createTopLevel(
session, scopeSession,
serializerExtension,
approximator
approximator,
languageVersionSettings,
)
is FirMetadataSource.Function -> FirElementSerializer.createForLambda(
session, scopeSession,
serializerExtension,
approximator
approximator,
languageVersionSettings,
)
else -> null
}