[K2] Pass FirFile to metadata serialization

This is needed to extract correct const value from `ConstValueProvider`.

#KT-57812
This commit is contained in:
Ivan Kylchik
2023-04-21 12:47:42 +02:00
committed by Space Team
parent d26e3871ba
commit 951e30b683
8 changed files with 53 additions and 39 deletions
@@ -78,7 +78,7 @@ class FirElementSerializer private constructor(
fun packagePartProto(
packageFqName: FqName,
files: List<FirFile>,
file: FirFile,
actualizedExpectDeclarations: Set<FirDeclaration>?
): ProtoBuf.Package.Builder {
val builder = ProtoBuf.Package.newBuilder()
@@ -88,7 +88,7 @@ class FirElementSerializer private constructor(
if (!declaration.shouldBeSerialized(actualizedExpectDeclarations)) return
when (declaration) {
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
is FirSimpleFunction -> privateFunctionProto(declaration)?.let { builder.addFunction(it) }
is FirTypeAlias -> typeAliasProto(declaration)?.let { builder.addTypeAlias(it) }
else -> onUnsupportedDeclaration(declaration)
}
@@ -97,18 +97,16 @@ class FirElementSerializer private constructor(
}
}
for (file in files) {
extension.processFile(file) {
for (declaration in file.declarations) {
addDeclaration(declaration) {}
}
processFile(file) {
for (declaration in file.declarations) {
addDeclaration(declaration) {}
}
}
extension.serializePackage(packageFqName, builder)
extension.serializePackage(packageFqName, builder)
for (declaration in providedDeclarationsService.getProvidedTopLevelDeclarations(packageFqName, scopeSession)) {
addDeclaration(declaration) {
error("Unsupported top-level declaration type: ${it.render()}")
for (declaration in providedDeclarationsService.getProvidedTopLevelDeclarations(packageFqName, scopeSession)) {
addDeclaration(declaration) {
error("Unsupported top-level declaration type: ${it.render()}")
}
}
}
@@ -118,7 +116,20 @@ class FirElementSerializer private constructor(
return builder
}
fun classProto(klass: FirClass): ProtoBuf.Class.Builder = whileAnalysing(session, klass) {
private inline fun <T> processFile(firFile: FirFile, crossinline action: () -> T): T {
return extension.processFile(firFile) {
action()
}
}
// Note: we could try to extract FirFile from `session.firProvider.getFirClassifierContainerFile` but it doesn't work for anonymous objects
fun classProto(klass: FirClass, firFile: FirFile): ProtoBuf.Class.Builder {
return processFile(firFile) {
privateClassProto(klass)
}
}
private fun privateClassProto(klass: FirClass): ProtoBuf.Class.Builder = whileAnalysing(session, klass) {
val builder = ProtoBuf.Class.newBuilder()
val regularClass = klass as? FirRegularClass
@@ -198,7 +209,7 @@ class FirElementSerializer private constructor(
if (declaration !is FirEnumEntry && declaration.isStatic) continue // ??? Miss values() & valueOf()
when (declaration) {
is FirProperty -> propertyProto(declaration)?.let { builder.addProperty(it) }
is FirSimpleFunction -> functionProto(declaration)?.let { builder.addFunction(it) }
is FirSimpleFunction -> privateFunctionProto(declaration)?.let { builder.addFunction(it) }
is FirEnumEntry -> enumEntryProto(declaration).let { builder.addEnumEntry(it) }
else -> {}
}
@@ -489,7 +500,13 @@ class FirElementSerializer private constructor(
return builder
}
fun functionProto(function: FirFunction): ProtoBuf.Function.Builder? = whileAnalysing(session, function) {
fun functionProto(function: FirFunction, firFile: FirFile): ProtoBuf.Function.Builder? {
return processFile(firFile) {
privateFunctionProto(function)
}
}
fun privateFunctionProto(function: FirFunction): ProtoBuf.Function.Builder? = whileAnalysing(session, function) {
val builder = ProtoBuf.Function.newBuilder()
val simpleFunction = function as? FirSimpleFunction
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.fir.serialization
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirAnnotation
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProviderInternals
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProvider
import org.jetbrains.kotlin.fir.serialization.constant.ConstValueProviderInternals
import org.jetbrains.kotlin.fir.types.ConeErrorType
import org.jetbrains.kotlin.fir.types.ConeFlexibleType
import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -29,7 +29,7 @@ abstract class FirSerializerExtension {
protected abstract val constValueProvider: ConstValueProvider?
@OptIn(ConstValueProviderInternals::class)
internal inline fun <T> processFile(firFile: FirFile, action: () -> T): T {
internal inline fun <T> processFile(firFile: FirFile, crossinline action: () -> T): T {
val previousFile = constValueProvider?.processingFirFile
constValueProvider?.processingFirFile = firFile
return try {
@@ -35,7 +35,7 @@ fun serializeSingleFirFile(
// TODO: split package fragment (see klib serializer)
// TODO: handle incremental/monolothic (see klib serializer) - maybe externally
val packageProto = packageSerializer.packagePartProto(file.packageFqName, listOf(file), actualizedExpectDeclarations).build()
val packageProto = packageSerializer.packagePartProto(file.packageFqName, file, actualizedExpectDeclarations).build()
val classesProto = mutableListOf<Pair<ProtoBuf.Class, Int>>()
@@ -51,14 +51,12 @@ fun serializeSingleFirFile(
)
val index = classSerializer.stringTable.getFqNameIndex(klass)
classesProto += classSerializer.classProto(klass).build() to index
classesProto += classSerializer.classProto(klass, file).build() to index
classSerializer.computeNestedClassifiersForClass(symbol).filterIsInstance<FirClassSymbol<*>>().makeClassesProtoWithNested()
}
}
serializerExtension.processFile(file) {
file.declarations.mapNotNull { it.symbol as? FirClassSymbol<*> }.makeClassesProtoWithNested()
}
file.declarations.mapNotNull { it.symbol as? FirClassSymbol<*> }.makeClassesProtoWithNested()
val hasTopLevelDeclarations = file.declarations.any {
it is FirMemberDeclaration && it.shouldBeSerialized(actualizedExpectDeclarations) &&