[IR] Fixed fake override builder for lowerings

This commit is contained in:
Igor Chevdar
2020-09-04 22:26:12 +05:00
parent 7f4bda0d52
commit e39ce91253
13 changed files with 167 additions and 141 deletions
@@ -1,107 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.descriptors.*
import org.jetbrains.kotlin.ir.util.DescriptorsRemapper
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
object DescriptorsToIrRemapper : DescriptorsRemapper {
override fun remapDeclaredClass(descriptor: ClassDescriptor) =
WrappedClassDescriptor()
override fun remapDeclaredConstructor(descriptor: ClassConstructorDescriptor) =
WrappedClassConstructorDescriptor()
override fun remapDeclaredEnumEntry(descriptor: ClassDescriptor) =
WrappedClassDescriptor()
override fun remapDeclaredField(descriptor: PropertyDescriptor) =
WrappedFieldDescriptor()
override fun remapDeclaredSimpleFunction(descriptor: FunctionDescriptor) =
when (descriptor) {
is PropertyGetterDescriptor -> WrappedPropertyGetterDescriptor()
is PropertySetterDescriptor -> WrappedPropertySetterDescriptor()
else -> WrappedSimpleFunctionDescriptor()
}
override fun remapDeclaredProperty(descriptor: PropertyDescriptor) =
WrappedPropertyDescriptor()
override fun remapDeclaredTypeParameter(descriptor: TypeParameterDescriptor) =
WrappedTypeParameterDescriptor()
override fun remapDeclaredVariable(descriptor: VariableDescriptor) =
WrappedVariableDescriptor()
override fun remapDeclaredValueParameter(descriptor: ParameterDescriptor): ParameterDescriptor =
if (descriptor is ReceiverParameterDescriptor)
WrappedReceiverParameterDescriptor()
else
WrappedValueParameterDescriptor()
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
object WrappedDescriptorPatcher : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitClass(declaration: IrClass) {
(declaration.descriptor as WrappedClassDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitConstructor(declaration: IrConstructor) {
(declaration.descriptor as WrappedClassConstructorDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitEnumEntry(declaration: IrEnumEntry) {
(declaration.descriptor as WrappedClassDescriptor).bind(
declaration.correspondingClass ?: declaration.parentAsClass
)
declaration.acceptChildrenVoid(this)
}
override fun visitField(declaration: IrField) {
(declaration.descriptor as WrappedFieldDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitProperty(declaration: IrProperty) {
(declaration.descriptor as WrappedPropertyDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitFunction(declaration: IrFunction) {
(declaration.descriptor as WrappedSimpleFunctionDescriptor).bind(declaration as IrSimpleFunction)
declaration.acceptChildrenVoid(this)
}
override fun visitValueParameter(declaration: IrValueParameter) {
(declaration.descriptor as? WrappedValueParameterDescriptor)?.bind(declaration)
(declaration.descriptor as? WrappedReceiverParameterDescriptor)?.bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitTypeParameter(declaration: IrTypeParameter) {
(declaration.descriptor as WrappedTypeParameterDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
override fun visitVariable(declaration: IrVariable) {
(declaration.descriptor as WrappedVariableDescriptor).bind(declaration)
declaration.acceptChildrenVoid(this)
}
}
@@ -16,7 +16,6 @@ import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.builders.Scope
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.builders.declarations.buildReceiverParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
import org.jetbrains.kotlin.ir.declarations.*
@@ -25,8 +24,11 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPropertySymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.*
@@ -438,63 +440,41 @@ val IrFunction.allParameters: List<IrValueParameter>
explicitParameters
}
fun IrClass.addFakeOverridesViaIncorrectHeuristic(implementedMembers: List<IrSimpleFunction> = emptyList()) {
fun IrDeclaration.toList() = when (this) {
is IrSimpleFunction -> listOf(this)
is IrProperty -> listOfNotNull(getter, setter)
else -> emptyList()
private object FakeOverrideBuilder : FakeOverrideBuilderStrategy() {
override fun linkFakeOverride(fakeOverride: IrOverridableMember) {
when (fakeOverride) {
is IrFakeOverrideFunction -> linkFunctionFakeOverride(fakeOverride)
is IrFakeOverrideProperty -> linkPropertyFakeOverride(fakeOverride)
else -> error("Unexpected fake override: $fakeOverride")
}
}
val overriddenFunctions = (declarations + implementedMembers)
.flatMap { it.toList() }
.flatMap { it.overriddenSymbols.map { it.owner } }
.toSet()
val unoverriddenSuperFunctions = superTypes
.map { it.getClass()!! }
.flatMap { irClass ->
irClass.declarations
.flatMap { it.toList() }
.filter { it !in overriddenFunctions }
.filter { it.visibility != DescriptorVisibilities.PRIVATE }
}
.toMutableSet()
// TODO: A dirty hack.
val groupedUnoverriddenSuperFunctions = unoverriddenSuperFunctions.groupBy { it.name.asString() + it.allParameters.size }
fun createFakeOverride(overriddenFunctions: List<IrSimpleFunction>) =
overriddenFunctions.first().let { irFunction ->
irFunction.factory.buildFun {
origin = IrDeclarationOrigin.FAKE_OVERRIDE
name = irFunction.name
visibility = DescriptorVisibilities.PUBLIC
modality = irFunction.modality
returnType = irFunction.returnType
isInline = irFunction.isInline
isExternal = irFunction.isExternal
isTailrec = irFunction.isTailrec
isSuspend = irFunction.isSuspend
isOperator = irFunction.isOperator
isInfix = irFunction.isInfix
isExpect = irFunction.isExpect
isFakeOverride = true
}.apply {
parent = this@addFakeOverridesViaIncorrectHeuristic
overriddenSymbols = overriddenFunctions.map { it.symbol }
copyParameterDeclarationsFrom(irFunction)
copyAttributes(irFunction)
}
}
val fakeOverriddenFunctions = groupedUnoverriddenSuperFunctions
.asSequence()
.associate { it.value.first() to createFakeOverride(it.value) }
.toMutableMap()
for (fo in fakeOverriddenFunctions.values) {
addChild(fo)
private fun linkFunctionFakeOverride(declaration: IrFakeOverrideFunction) {
declaration.acquireSymbol(IrSimpleFunctionSymbolImpl(WrappedSimpleFunctionDescriptor()))
}
private fun linkPropertyFakeOverride(declaration: IrFakeOverrideProperty) {
val propertySymbol = IrPropertySymbolImpl(WrappedPropertyDescriptor())
declaration.getter?.let { it.correspondingPropertySymbol = propertySymbol }
declaration.setter?.let { it.correspondingPropertySymbol = propertySymbol }
declaration.acquireSymbol(propertySymbol)
declaration.getter?.let {
it.correspondingPropertySymbol = declaration.symbol
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override getter: $it"))
}
declaration.setter?.let {
it.correspondingPropertySymbol = declaration.symbol
linkFunctionFakeOverride(it as? IrFakeOverrideFunction ?: error("Unexpected fake override setter: $it"))
}
}
}
fun IrClass.addFakeOverrides(irBuiltIns: IrBuiltIns, implementedMembers: List<IrOverridableMember> = emptyList()) {
IrOverridingUtil(irBuiltIns, FakeOverrideBuilder)
.buildFakeOverridesForClassUsingOverriddenSymbols(this, implementedMembers)
.forEach { addChild(it) }
}
@OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -354,7 +354,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
}
coroutineClass.superTypes += superTypes
coroutineClass.addFakeOverridesViaIncorrectHeuristic()
coroutineClass.addFakeOverrides(context.irBuiltIns)
initializeStateMachine(coroutineConstructors, coroutineClassThis)
@@ -9,7 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.ScopeWithIr
import org.jetbrains.kotlin.backend.common.ir.addFakeOverridesViaIncorrectHeuristic
import org.jetbrains.kotlin.backend.common.ir.addFakeOverrides
import org.jetbrains.kotlin.backend.common.ir.copyTo
import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
@@ -225,7 +225,7 @@ abstract class SingleAbstractMethodLowering(val context: CommonBackendContext) :
if (superType.needEqualsHashCodeMethods)
generateEqualsHashCode(subclass, superType, field)
subclass.addFakeOverridesViaIncorrectHeuristic()
subclass.addFakeOverrides(context.irBuiltIns)
return subclass
}
@@ -5,9 +5,8 @@
package org.jetbrains.kotlin.backend.common.lower.inline
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.DescriptorsToIrRemapper
import org.jetbrains.kotlin.backend.common.WrappedDescriptorPatcher
import org.jetbrains.kotlin.ir.util.DescriptorsToIrRemapper
import org.jetbrains.kotlin.ir.util.WrappedDescriptorPatcher
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
import org.jetbrains.kotlin.ir.declarations.IrTypeParametersContainer