[IR] Fixed fake override builder for lowerings
This commit is contained in:
-107
@@ -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)
|
||||
|
||||
+1
-1
@@ -354,7 +354,7 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
||||
}
|
||||
|
||||
coroutineClass.superTypes += superTypes
|
||||
coroutineClass.addFakeOverridesViaIncorrectHeuristic()
|
||||
coroutineClass.addFakeOverrides(context.irBuiltIns)
|
||||
|
||||
initializeStateMachine(coroutineConstructors, coroutineClassThis)
|
||||
|
||||
|
||||
+2
-2
@@ -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
|
||||
}
|
||||
|
||||
+2
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user