Fake override construction fallback mode
This commit is contained in:
+5
-10
@@ -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<IrClass>()
|
||||
override val propertyOverriddenSymbols = mutableMapOf<IrOverridableMember, List<IrSymbol>>()
|
||||
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)
|
||||
|
||||
+26
-14
@@ -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<IrSymbol, IdSignature>
|
||||
abstract fun deserializeIrSymbol(code: Long): IrSymbol
|
||||
@@ -120,6 +128,7 @@ abstract class IrFileDeserializer(val logger: LoggingContext, val builtIns: IrBu
|
||||
private val delegatedSymbolMap = mutableMapOf<IrSymbol, IrSymbol>()
|
||||
|
||||
abstract val deserializeInlineFunctions: Boolean
|
||||
abstract val platformFakeOverrideClassFilter: PlatformFakeOverrideClassFilter
|
||||
|
||||
fun deserializeFqName(fqn: List<Int>): 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) =
|
||||
|
||||
+16
-12
@@ -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<ModuleDescriptor>
|
||||
private val exportedDependencies: List<ModuleDescriptor>,
|
||||
private val deserializeFakeOverrides: Boolean
|
||||
) : IrDeserializer {
|
||||
|
||||
// Kotlin-MPP related data. Consider some refactoring
|
||||
@@ -67,7 +68,7 @@ abstract class KotlinIrLinker(
|
||||
|
||||
protected val deserializersForModules = mutableMapOf<ModuleDescriptor, IrModuleDeserializer>()
|
||||
|
||||
abstract val fakeOverrideBuilderImpl: FakeOverrideBuilderImpl
|
||||
abstract val fakeOverrideBuilder: FakeOverrideBuilder
|
||||
|
||||
private val haveSeen = mutableSetOf<IrSymbol>()
|
||||
|
||||
@@ -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<Int, IrLoopBase>()
|
||||
|
||||
@@ -237,6 +238,8 @@ abstract class KotlinIrLinker(
|
||||
|
||||
override val deserializeInlineFunctions: Boolean = inlineBodies
|
||||
|
||||
override val platformFakeOverrideClassFilter = fakeOverrideBuilder.platformSpecificClassFilter
|
||||
|
||||
var reversedSignatureIndex = emptyMap<IdSignature, Int>()
|
||||
|
||||
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),
|
||||
|
||||
Reference in New Issue
Block a user