diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt index f7918fcd766..e4f187702b9 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.kt @@ -340,6 +340,12 @@ abstract class CommonCompilerArguments : CommonToolArguments() { ) var explicitApi: String by FreezableVar(ExplicitApiMode.DISABLED.state) + @Argument( + value = "-Xdeserialize-fake-overrides", + description = "Fallback to deserializing fake overrides" + ) + var deserializeFakeOverrides: Boolean by FreezableVar(false) + open fun configureAnalysisFlags(collector: MessageCollector): MutableMap, Any> { return HashMap, Any>().apply { put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt index e12391d8989..272809785ca 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/arguments.kt @@ -26,6 +26,7 @@ fun CompilerConfiguration.setupCommonArguments( put(CommonConfigurationKeys.EXPECT_ACTUAL_LINKER, arguments.expectActualLinker) putIfNotNull(CLIConfigurationKeys.INTELLIJ_PLUGIN_ROOT, arguments.intellijPluginRoot) put(CommonConfigurationKeys.REPORT_OUTPUT_FILES, arguments.reportOutputFiles) + put(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES, arguments.deserializeFakeOverrides) val metadataVersionString = arguments.metadataVersion if (metadataVersionString != null) { diff --git a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 4fc5f368965..cef760c0c95 100644 --- a/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/config/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -47,6 +47,9 @@ object CommonConfigurationKeys { @JvmField val EXPECT_ACTUAL_LINKER = CompilerConfigurationKey.create("Experimental expext/actual linker") + + @JvmField + val DESERIALIZE_FAKE_OVERRIDES = CompilerConfigurationKey.create("Deserialize fake overrides") } var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt index 2379b568e01..50860fad7ec 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/overrides/FakeOverrides.kt @@ -39,10 +39,6 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.types.Variance -interface FakeOverrideBuilder { - fun buildFakeOverridesForClass(clazz: IrClass) -} - interface PlatformFakeOverrideClassFilter { fun constructFakeOverrides(clazz: IrClass): Boolean = true } @@ -52,19 +48,20 @@ object DefaultFakeOverrideClassFilter : PlatformFakeOverrideClassFilter object FakeOverrideControl { // If set to true: all fake overrides go to klib serialized IR. // If set to false: eligible fake overrides are not serialized. - val serializeFakeOverrides: Boolean = false + val serializeFakeOverrides: Boolean = true // If set to true: fake overrides are deserialized from klib serialized IR. // If set to false: eligible fake overrides are constructed within IR linker. + // This is the default in the absence of -Xdeserialize-fake-overrides flag. val deserializeFakeOverrides: Boolean = false } -class FakeOverrideBuilderImpl( +class FakeOverrideBuilder( val symbolTable: SymbolTable, val signaturer: IdSignatureSerializer, val irBuiltIns: IrBuiltIns, - private val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter -) : FakeOverrideBuilder, FakeOverrideBuilderStrategy { + val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter +) : FakeOverrideBuilderStrategy { private val haveFakeOverrides = mutableSetOf() override val propertyOverriddenSymbols = mutableMapOf>() private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this) @@ -117,8 +114,6 @@ class FakeOverrideBuilderImpl( irOverridingUtil.buildFakeOverridesForClass(clazz) } - override fun buildFakeOverridesForClass(clazz: IrClass) = irOverridingUtil.buildFakeOverridesForClass(clazz) - override fun linkFakeOverride(fakeOverride: IrOverridableMember) { when (fakeOverride) { is IrFakeOverrideFunctionImpl -> linkFunctionFakeOverride(fakeOverride) diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt index cadda51a82e..750310774fd 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/IrFileDeserializer.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory import org.jetbrains.kotlin.backend.common.ir.ir2string +import org.jetbrains.kotlin.backend.common.overrides.PlatformFakeOverrideClassFilter import org.jetbrains.kotlin.backend.common.peek import org.jetbrains.kotlin.backend.common.pop import org.jetbrains.kotlin.backend.common.push @@ -27,6 +28,7 @@ import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.* +import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.* import org.jetbrains.kotlin.ir.util.* @@ -103,7 +105,13 @@ import org.jetbrains.kotlin.backend.common.serialization.proto.Loop as ProtoLoop import org.jetbrains.kotlin.backend.common.serialization.proto.MemberAccessCommon as ProtoMemberAccessCommon import org.jetbrains.kotlin.backend.common.serialization.proto.PublicIdSignature as ProtoPublicIdSignature -abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBuiltIns, val symbolTable: SymbolTable, var constructFakeOverrides: Boolean, protected var deserializeBodies: Boolean) { +abstract class IrFileDeserializer( + val logger: LoggingContext, + val builtIns: IrBuiltIns, + val symbolTable: SymbolTable, + protected var deserializeBodies: Boolean, + private val deserializeFakeOverrides: Boolean +) { abstract fun deserializeIrSymbolToDeclare(code: Long): Pair abstract fun deserializeIrSymbol(code: Long): IrSymbol @@ -120,6 +128,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu private val delegatedSymbolMap = mutableMapOf() abstract val deserializeInlineFunctions: Boolean + abstract val platformFakeOverrideClassFilter: PlatformFakeOverrideClassFilter fun deserializeFqName(fqn: List): String = fqn.joinToString(".", transform = ::deserializeString) @@ -1033,14 +1042,14 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu }.usingParent { typeParameters = deserializeTypeParameters(proto.typeParameterList, true) + superTypes = proto.superTypeList.map { deserializeIrType(it) } + proto.declarationList - //.filterNot { isSkippableFakeOverride(it) } + .filterNot { isSkippableFakeOverride(it, this) } .mapTo(declarations) { deserializeDeclaration(it) } thisReceiver = deserializeIrValueParameter(proto.thisReceiver, -1) - superTypes = proto.superTypeList.map { deserializeIrType(it) } - (descriptor as? WrappedClassDescriptor)?.bind(this) } } @@ -1361,22 +1370,25 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu // Depending on deserialization strategy we either deserialize public api fake overrides // or reconstruct them after IR linker completes. - private fun isSkippableFakeOverride(proto: ProtoDeclaration): Boolean { - if (!constructFakeOverrides) return false + private fun isSkippableFakeOverride(proto: ProtoDeclaration, parent: IrClass): Boolean { + if (deserializeFakeOverrides) return false + if (!platformFakeOverrideClassFilter.constructFakeOverrides(parent)) return false - val isFakeOverride = when (proto.declaratorCase!!) { + val symbol = when (proto.declaratorCase!!) { + IR_FUNCTION -> deserializeIrSymbol(proto.irFunction.base.base.symbol) + IR_PROPERTY -> deserializeIrSymbol(proto.irProperty.base.symbol) + // Don't consider IR_FIELDS here. + else -> return false + } + if (symbol !is IrPublicSymbolBase<*>) return false + if (!symbol.signature.isPublic) return false + + return when (proto.declaratorCase!!) { IR_FUNCTION -> FunctionFlags.decode(proto.irFunction.base.base.flags).isFakeOverride IR_PROPERTY -> PropertyFlags.decode(proto.irProperty.base.flags).isFakeOverride // Don't consider IR_FIELDS here. else -> false } - val isPublicApi = when (proto.declaratorCase!!) { - IR_FUNCTION -> deserializeIrSymbol(proto.irFunction.base.base.symbol).signature.isPublic - IR_PROPERTY -> deserializeIrSymbol(proto.irProperty.base.symbol).signature.isPublic - // Don't consider IR_FIELDS here. - else -> false - } - return isFakeOverride && isPublicApi } fun deserializeDeclaration(proto: ProtoDeclaration, parent: IrDeclarationParent) = diff --git a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt index 29923740dad..c28d0f5e86d 100644 --- a/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt +++ b/compiler/ir/serialization.common/src/org/jetbrains/kotlin/backend/common/serialization/KotlinIrLinker.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.backend.common.serialization import org.jetbrains.kotlin.backend.common.LoggingContext -import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilderImpl +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideControl import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor @@ -54,7 +54,8 @@ abstract class KotlinIrLinker( val logger: LoggingContext, val builtIns: IrBuiltIns, val symbolTable: SymbolTable, - private val exportedDependencies: List + private val exportedDependencies: List, + private val deserializeFakeOverrides: Boolean ) : IrDeserializer { // Kotlin-MPP related data. Consider some refactoring @@ -67,7 +68,7 @@ abstract class KotlinIrLinker( protected val deserializersForModules = mutableMapOf() - abstract val fakeOverrideBuilderImpl: FakeOverrideBuilderImpl + abstract val fakeOverrideBuilder: FakeOverrideBuilder private val haveSeen = mutableSetOf() @@ -163,7 +164,7 @@ abstract class KotlinIrLinker( fileIndex, !strategy.needBodies, strategy.inlineBodies, - !strategy.fakeOverrides, + deserializeFakeOverrides, moduleDeserializer).apply { // Explicitly exported declarations (e.g. top-level initializers) must be deserialized before all other declarations. @@ -225,9 +226,9 @@ abstract class KotlinIrLinker( private val fileIndex: Int, onlyHeaders: Boolean, inlineBodies: Boolean, - constructFakeOverrrides: Boolean, - private val moduleDeserializer: IrModuleDeserializer, - ) : IrFileDeserializer(logger, builtIns, symbolTable, constructFakeOverrrides, !onlyHeaders) { + deserializeFakeOverrides: Boolean, + private val moduleDeserializer: IrModuleDeserializer + ) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides) { private var fileLoops = mutableMapOf() @@ -237,6 +238,8 @@ abstract class KotlinIrLinker( override val deserializeInlineFunctions: Boolean = inlineBodies + override val platformFakeOverrideClassFilter = fakeOverrideBuilder.platformSpecificClassFilter + var reversedSignatureIndex = emptyMap() inner class FileDeserializationState { @@ -586,9 +589,11 @@ abstract class KotlinIrLinker( override fun postProcess() { finalizeExpectActualLinker() - deserializersForModules.values.forEach { - it.postProcess { - fakeOverrideBuilderImpl.provideFakeOverrides(it) + if (!deserializeFakeOverrides) { + deserializersForModules.values.forEach { + it.postProcess { + fakeOverrideBuilder.provideFakeOverrides(it) + } } } @@ -676,8 +681,7 @@ enum class DeserializationStrategy( val needBodies: Boolean, val explicitlyExported: Boolean, val theWholeWorld: Boolean, - val inlineBodies: Boolean, - val fakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides + val inlineBodies: Boolean ) { ONLY_REFERENCED(true, false, false, true), ALL(true, true, true, true), diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt index c2184d79a88..74201710f85 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/klib.kt @@ -147,6 +147,7 @@ fun generateKLib( irBuiltIns.functionFactory = functionFactory val expectDescriptorToSymbol = mutableMapOf() + val deserializeFakeOverrides = configuration.getBoolean(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES) val irLinker = JsIrLinker( psi2IrContext.moduleDescriptor, @@ -154,7 +155,8 @@ fun generateKLib( psi2IrContext.irBuiltIns, psi2IrContext.symbolTable, functionFactory, - serializedIrFiles + serializedIrFiles, + deserializeFakeOverrides ) val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { @@ -216,6 +218,7 @@ fun loadIr( friendDependencies: List ): IrModuleInfo { val depsDescriptors = ModulesStructure(project, mainModule, analyzer, configuration, allDependencies, friendDependencies) + val deserializeFakeOverrides = configuration.getBoolean(CommonConfigurationKeys.DESERIALIZE_FAKE_OVERRIDES) when (mainModule) { is MainModule.SourceFiles -> { @@ -224,9 +227,7 @@ fun loadIr( val symbolTable = psi2IrContext.symbolTable val functionFactory = IrFunctionFactory(irBuiltIns, symbolTable) irBuiltIns.functionFactory = functionFactory - - val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable, functionFactory, null) - + val irLinker = JsIrLinker(psi2IrContext.moduleDescriptor, emptyLoggingContext, irBuiltIns, symbolTable, functionFactory, null, deserializeFakeOverrides) val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { irLinker.deserializeIrModuleHeader(depsDescriptors.getModuleDescriptor(it), it) } @@ -262,7 +263,7 @@ fun loadIr( constantValueGenerator.typeTranslator = typeTranslator val irBuiltIns = IrBuiltIns(moduleDescriptor.builtIns, typeTranslator, symbolTable) val functionFactory = IrFunctionFactory(irBuiltIns, symbolTable) - val irLinker = JsIrLinker(null, emptyLoggingContext, irBuiltIns, symbolTable, functionFactory, null) + val irLinker = JsIrLinker(null, emptyLoggingContext, irBuiltIns, symbolTable, functionFactory, null, deserializeFakeOverrides) val deserializedModuleFragments = sortDependencies(allDependencies.getFullList(), depsDescriptors.descriptors).map { val strategy = diff --git a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt index 30998859130..9072b59ddee 100644 --- a/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt +++ b/compiler/ir/serialization.js/src/org/jetbrains/kotlin/ir/backend/js/lower/serialization/ir/JsIrLinker.kt @@ -6,7 +6,8 @@ package org.jetbrains.kotlin.ir.backend.js.lower.serialization.ir import org.jetbrains.kotlin.backend.common.LoggingContext -import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilderImpl +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideControl import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer import org.jetbrains.kotlin.descriptors.ModuleDescriptor @@ -20,11 +21,11 @@ import org.jetbrains.kotlin.library.SerializedIrFile class JsIrLinker( private val currentModule: ModuleDescriptor?, logger: LoggingContext, builtIns: IrBuiltIns, symbolTable: SymbolTable, override val functionalInterfaceFactory: IrAbstractFunctionFactory, - private val icData: List? = null -) : - KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList()) { + private val icData: List? = null, + deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides +) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { - override val fakeOverrideBuilderImpl = FakeOverrideBuilderImpl(symbolTable, IdSignatureSerializer(JsManglerIr), builtIns) + override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JsManglerIr), builtIns) override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean = moduleDescriptor === moduleDescriptor.builtIns.builtInsModule diff --git a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt index 63c727ddc2a..fd75240bbd7 100644 --- a/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt +++ b/compiler/ir/serialization.jvm/src/org/jetbrains/kotlin/ir/backend/jvm/serialization/JvmIrLinker.kt @@ -6,7 +6,8 @@ package org.jetbrains.kotlin.ir.backend.jvm.serialization import org.jetbrains.kotlin.backend.common.LoggingContext -import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilderImpl +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder +import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideControl import org.jetbrains.kotlin.backend.common.serialization.* import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolData import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer @@ -37,10 +38,11 @@ class JvmIrLinker( symbolTable: SymbolTable, override val functionalInterfaceFactory: IrAbstractFunctionFactory, private val stubGenerator: DeclarationStubGenerator, - private val manglerDesc: JvmManglerDesc -) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList()) { + private val manglerDesc: JvmManglerDesc, + deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides +) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) { - override val fakeOverrideBuilderImpl = FakeOverrideBuilderImpl(symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns) + override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns) private val javaName = Name.identifier("java")