From 8350226bad05bbe32b69ed6b759846d950269178 Mon Sep 17 00:00:00 2001 From: Dmitriy Novozhilov Date: Tue, 31 Jan 2023 12:40:20 +0200 Subject: [PATCH] [FIR] Collect constructors from scope instead of .declarations in metadata serialization This is needed to save in metadata constructors, generated by plugins with FirDeclarationGenerationExtension --- .../fir/serialization/FirElementSerializer.kt | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt index a61b78b60cd..9f01efd828f 100644 --- a/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt +++ b/compiler/fir/fir-serialization/src/org/jetbrains/kotlin/fir/serialization/FirElementSerializer.kt @@ -29,10 +29,7 @@ import org.jetbrains.kotlin.fir.extensions.extensionService import org.jetbrains.kotlin.fir.extensions.typeAttributeExtensions import org.jetbrains.kotlin.fir.resolve.* import org.jetbrains.kotlin.fir.resolve.providers.symbolProvider -import org.jetbrains.kotlin.fir.scopes.FakeOverrideTypeCalculator -import org.jetbrains.kotlin.fir.scopes.getSingleClassifier -import org.jetbrains.kotlin.fir.scopes.processAllFunctions -import org.jetbrains.kotlin.fir.scopes.processAllProperties +import org.jetbrains.kotlin.fir.scopes.* import org.jetbrains.kotlin.fir.serialization.constant.EnumValue import org.jetbrains.kotlin.fir.serialization.constant.IntValue import org.jetbrains.kotlin.fir.serialization.constant.StringValue @@ -139,7 +136,7 @@ class FirElementSerializer private constructor( } if (regularClass != null && regularClass.classKind != ClassKind.ENUM_ENTRY) { - for (constructor in regularClass.declarations.filterIsInstance()) { + for (constructor in regularClass.constructors()) { builder.addConstructor(constructorProto(constructor)) } } @@ -233,26 +230,40 @@ class FirElementSerializer private constructor( return builder } - private fun FirClass.declarations(): List = buildList { - val memberScope = - defaultType().scope(session, scopeSession, FakeOverrideTypeCalculator.DoNothing, requiredPhase = null) - ?: error("Null scope for $this") + private fun FirClass.memberDeclarations(): List { + return collectDeclarations> { memberScope, addDeclarationIfNeeded -> + memberScope.processAllFunctions { addDeclarationIfNeeded(it) } + memberScope.processAllProperties { addDeclarationIfNeeded(it) } + } + } - fun addDeclarationIfNeeded(symbol: FirCallableSymbol<*>) { - val declaration = symbol.fir - if (declaration.isSubstitutionOrIntersectionOverride) return + private fun FirClass.constructors(): List { + return collectDeclarations { memberScope, addDeclarationIfNeeded -> + memberScope.processDeclaredConstructors { addDeclarationIfNeeded(it) } + } + } + + private inline fun > FirClass.collectDeclarations( + processScope: (FirTypeScope, ((S) -> Unit)) -> Unit + ): List = buildList { + val memberScope = unsubstitutedScope(session, scopeSession, withForcedTypeCalculator = false) + + processScope(memberScope) l@{ + val declaration = it.fir as T + if (declaration.isSubstitutionOrIntersectionOverride) return@l // non-intersection or substitution fake override - if (!declaration.isStatic && declaration.dispatchReceiverClassLookupTagOrNull() != this@declarations.symbol.toLookupTag()) return + if (!(declaration.isStatic || declaration is FirConstructor)) { + if (declaration.dispatchReceiverClassLookupTagOrNull()!= this@collectDeclarations.symbol.toLookupTag()) { + return@l + } + } add(declaration) } - memberScope.processAllFunctions(::addDeclarationIfNeeded) - memberScope.processAllProperties(::addDeclarationIfNeeded) - for (declaration in declarations) { - if (declaration is FirCallableDeclaration && declaration.isStatic) { + if (declaration is T && declaration.isStatic) { add(declaration) } }