[Private fake overrides] Private fake override construction

This commit is contained in:
Alexander Gorshenev
2020-10-21 22:40:18 +03:00
parent c90556a883
commit 223d1dd5e6
8 changed files with 63 additions and 58 deletions
@@ -101,26 +101,16 @@ class IrOverridingUtil(
}
}
// We need to get Any's members if all the parents are private.
private fun allPublicApiSuperTypesOrAny(clazz: IrClass): List<IrType> {
val superTypes = clazz.superTypes
val superClasses = superTypes.map { it.getClass() ?: error("Unexpected super type: $it") }
return if (superClasses.isEmpty() || superClasses.any { it.symbol.isPublicApi })
superTypes
else
listOf(irBuiltIns.anyType)
}
fun buildFakeOverridesForClass(clazz: IrClass) {
val superTypes = allPublicApiSuperTypesOrAny(clazz)
val superTypes = clazz.superTypes
@Suppress("UNCHECKED_CAST")
val fromCurrent = clazz.declarations.filter { it is IrOverridableMember && it.symbol.isPublicApi } as List<IrOverridableMember>
val fromCurrent = clazz.declarations.filter { it is IrOverridableMember } as List<IrOverridableMember>
val allFromSuper = superTypes.flatMap { superType ->
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations
.filter { it is IrOverridableMember && it.symbol.isPublicApi }
.filter { it.isOverridableMemberOrAccessor() }
.map {
val overridenMember = it as IrOverridableMember
val fakeOverride = fakeOverrideBuilder.fakeOverrideMember(superType, overridenMember, clazz)
@@ -76,9 +76,6 @@ class FakeOverrideChecker(
validateFakeOverrides(declaration)
super.visitClass(declaration)
}
override fun visitFunction(declaration: IrFunction) {
// Don't go for function local classes
}
})
}
}
@@ -23,20 +23,13 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.descriptors.WrappedPropertyDescriptor
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
import org.jetbrains.kotlin.ir.overrides.DeepCopyIrTreeWithSymbolsForFakeOverrides
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.IrTypeProjection
import org.jetbrains.kotlin.ir.types.extractTypeParameters
import org.jetbrains.kotlin.ir.types.getClass
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.ir.util.*
class FakeOverrideGlobalDeclarationTable(signatureSerializer: IdSignatureSerializer)
: GlobalDeclarationTable(signatureSerializer, signatureSerializer.mangler) {
@@ -54,7 +47,18 @@ class FakeOverrideDeclarationTable(
}
}
object DefaultFakeOverrideClassFilter : PlatformFakeOverrideClassFilter
interface FakeOverrideClassFilter {
fun needToConstructFakeOverrides(clazz: IrClass): Boolean
}
interface FileLocalAwareLinker {
fun tryReferencingSimpleFunctionByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrSimpleFunctionSymbol?
fun tryReferencingPropertyByLocalSignature(parent: IrDeclaration, idSignature: IdSignature): IrPropertySymbol?
}
object DefaultFakeOverrideClassFilter : FakeOverrideClassFilter {
override fun needToConstructFakeOverrides(clazz: IrClass): Boolean = true
}
object FakeOverrideControl {
// If set to true: all fake overrides go to klib serialized IR.
@@ -70,15 +74,25 @@ object FakeOverrideControl {
class FakeOverrideBuilder(
val symbolTable: SymbolTable,
val signaturer: IdSignatureSerializer,
val irBuiltIns: IrBuiltIns,
val platformSpecificClassFilter: PlatformFakeOverrideClassFilter = DefaultFakeOverrideClassFilter
irBuiltIns: IrBuiltIns,
val platformSpecificClassFilter: FakeOverrideClassFilter = DefaultFakeOverrideClassFilter
) : FakeOverrideBuilderStrategy() {
private val haveFakeOverrides = mutableSetOf<IrClass>()
private val irOverridingUtil = IrOverridingUtil(irBuiltIns, this)
fun buildFakeOverrideChainsForClass(clazz: IrClass) {
// TODO: The declaration table is needed for the signaturer.
private val fakeOverrideDeclarationTable = FakeOverrideDeclarationTable(signaturer)
private val fakeOverrideClassQueue = mutableListOf<IrClass>()
fun enqueueClass(clazz: IrClass, signature: IdSignature) {
fakeOverrideDeclarationTable.assumeDeclarationSignature(clazz, signature)
fakeOverrideClassQueue.add(clazz)
}
private fun buildFakeOverrideChainsForClass(clazz: IrClass) {
if (haveFakeOverrides.contains(clazz)) return
if (!platformSpecificClassFilter.constructFakeOverrides(clazz) || !clazz.symbol.isPublicApi) return
if (!platformSpecificClassFilter.needToConstructFakeOverrides(clazz)) return
val superTypes = clazz.superTypes
@@ -127,11 +141,8 @@ class FakeOverrideBuilder(
it.correspondingPropertySymbol = tempSymbol
}
val signature = signaturer.composePublicIdSignature(declaration)
symbolTable.declarePropertyFromLinker(WrappedPropertyDescriptor(), signature) {
declaration.acquireSymbol(it)
}
val signature = composeSignature(declaration)
declarePropertyFakeOverride(declaration, signature)
declaration.getter?.let {
it.correspondingPropertySymbol = declaration.symbol
@@ -149,4 +160,11 @@ class FakeOverrideBuilder(
irOverridingUtil.clear()
haveFakeOverrides.add(klass)
}
fun provideFakeOverrides() {
while (fakeOverrideClassQueue.isNotEmpty()) {
val klass = fakeOverrideClassQueue.removeLast()
provideFakeOverrides(klass)
}
}
}
@@ -8,7 +8,8 @@ package org.jetbrains.kotlin.backend.common.serialization
import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.ir.ir2string
import org.jetbrains.kotlin.backend.common.lower.InnerClassesSupport
import org.jetbrains.kotlin.backend.common.overrides.PlatformFakeOverrideClassFilter
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideBuilder
import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideClassFilter
import org.jetbrains.kotlin.backend.common.peek
import org.jetbrains.kotlin.backend.common.pop
import org.jetbrains.kotlin.backend.common.push
@@ -114,7 +115,7 @@ abstract class IrFileDeserializer(
val symbolTable: SymbolTable,
protected var deserializeBodies: Boolean,
private val deserializeFakeOverrides: Boolean,
private val fakeOverrideQueue: MutableList<IrClass>,
private val fakeOverrideBuilder: FakeOverrideBuilder,
private val allowErrorNodes: Boolean
) {
protected val irFactory: IrFactory get() = symbolTable.irFactory
@@ -134,7 +135,7 @@ abstract class IrFileDeserializer(
private val delegatedSymbolMap = mutableMapOf<IrSymbol, IrSymbol>()
abstract val deserializeInlineFunctions: Boolean
abstract val platformFakeOverrideClassFilter: PlatformFakeOverrideClassFilter
abstract val platformFakeOverrideClassFilter: FakeOverrideClassFilter
fun deserializeFqName(fqn: List<Int>): String =
fqn.joinToString(".", transform = ::deserializeString)
@@ -1088,11 +1089,7 @@ abstract class IrFileDeserializer(
(descriptor as? WrappedClassDescriptor)?.bind(this)
if (!deserializeFakeOverrides) {
if (symbol.isPublicApi) {
fakeOverrideQueue.add(this)
}
}
fakeOverrideBuilder.enqueueClass(this, signature)
}
}
@@ -1470,7 +1467,7 @@ abstract class IrFileDeserializer(
// or reconstruct them after IR linker completes.
private fun isSkippableFakeOverride(proto: ProtoDeclaration, parent: IrClass): Boolean {
if (deserializeFakeOverrides) return false
if (!platformFakeOverrideClassFilter.constructFakeOverrides(parent)) return false
if (!platformFakeOverrideClassFilter.needToConstructFakeOverrides(parent)) return false
val symbol = when (proto.declaratorCase!!) {
IR_FUNCTION -> deserializeIrSymbol(proto.irFunction.base.base.symbol)
@@ -1245,9 +1245,8 @@ open class IrFileSerializer(
assert(member.parent is IrClass)
if (FakeOverrideControl.serializeFakeOverrides) return true
if (backendSpecificSerializeAllMembers(member.parent as IrClass)) return true
// TODO: we can, probably, maintain a privacy bit while traversing the tree
// instead of running the parent hierarchy for isExported every time.
return !(member.isFakeOverride && declarationTable.isExportedDeclaration(member))
return (!member.isFakeOverride)
}
private fun fillPlatformExplicitlyExported(file: IrFile, proto: ProtoFile.Builder) {
@@ -73,7 +73,6 @@ abstract class KotlinIrLinker(
abstract val translationPluginContext: TranslationPluginContext?
private val haveSeen = mutableSetOf<IrSymbol>()
private val fakeOverrideClassQueue = mutableListOf<IrClass>()
private lateinit var linkerExtensions: Collection<IrDeserializer.IrLinkerExtension>
@@ -234,7 +233,17 @@ abstract class KotlinIrLinker(
deserializeFakeOverrides: Boolean,
private val moduleDeserializer: IrModuleDeserializer,
allowErrorNodes: Boolean
) : IrFileDeserializer(logger, builtIns, symbolTable, !onlyHeaders, deserializeFakeOverrides, fakeOverrideClassQueue, allowErrorNodes) {
) :
IrFileDeserializer(
logger,
builtIns,
symbolTable,
!onlyHeaders,
deserializeFakeOverrides,
fakeOverrideBuilder,
allowErrorNodes
)
{
private var fileLoops = mutableMapOf<Int, IrLoop>()
@@ -600,12 +609,7 @@ abstract class KotlinIrLinker(
override fun postProcess() {
finalizeExpectActualLinker()
while (fakeOverrideClassQueue.isNotEmpty()) {
val klass = fakeOverrideClassQueue.removeLast()
fakeOverrideBuilder.provideFakeOverrides(klass)
}
fakeOverrideBuilder.provideFakeOverrides()
haveSeen.clear()
// TODO: fix IrPluginContext to make it not produce additional external reference
@@ -31,7 +31,7 @@ class JsIrLinker(
deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides
) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) {
override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JsManglerIr), builtIns)
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, IdSignatureSerializer(JsManglerIr), builtIns)
override fun isBuiltInModule(moduleDescriptor: ModuleDescriptor): Boolean =
moduleDescriptor === moduleDescriptor.builtIns.builtInsModule
@@ -44,7 +44,7 @@ class JvmIrLinker(
deserializeFakeOverrides: Boolean = FakeOverrideControl.deserializeFakeOverrides
) : KotlinIrLinker(currentModule, logger, builtIns, symbolTable, emptyList(), deserializeFakeOverrides) {
override val fakeOverrideBuilder = FakeOverrideBuilder(symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns)
override val fakeOverrideBuilder = FakeOverrideBuilder(this, symbolTable, IdSignatureSerializer(JvmManglerIr), builtIns)
private val javaName = Name.identifier("java")