IR: refactor resolveFakeOverride call sites

Split it to 4 functions for clarity: resolveFakeOverride,
resolveFakeOverrideOrFail, resolveFakeOverrideMaybeAbstract,
resolveFakeOverrideMaybeAbstractOrFail. Remove/inline duplicated
utilities and remove unused parameters.
This commit is contained in:
Alexander Udalov
2023-08-23 15:37:01 +02:00
committed by Space Team
parent e52529a1d1
commit b5ba9ee671
19 changed files with 72 additions and 80 deletions
@@ -469,7 +469,7 @@ internal abstract class IrExpectActualMatchingContext(
var ir = asIr() var ir = asIr()
if (ir.isFakeOverride && ir is IrOverridableDeclaration<*>) { if (ir.isFakeOverride && ir is IrOverridableDeclaration<*>) {
ir.resolveFakeOverrideOrNull()?.let { ir = it } ir.resolveFakeOverride()?.let { ir = it }
} }
return when (ir.origin) { return when (ir.origin) {
@@ -778,7 +778,7 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext): Boolean { fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext): Boolean {
val firstExportedRealOverride = runIf(isFakeOverride) { val firstExportedRealOverride = runIf(isFakeOverride) {
resolveFakeOverrideOrNull(allowAbstract = true) { it === this || it.parentClassOrNull?.isExported(context) != true } resolveFakeOverrideMaybeAbstract { it === this || it.parentClassOrNull?.isExported(context) != true }
} }
if (firstExportedRealOverride?.parentClassOrNull.isExportedInterface(context)) { if (firstExportedRealOverride?.parentClassOrNull.isExportedInterface(context)) {
@@ -6,14 +6,16 @@
package org.jetbrains.kotlin.ir.backend.js.ic package org.jetbrains.kotlin.ir.backend.js.ic
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.isFakeOverride import org.jetbrains.kotlin.ir.util.isFakeOverride
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.resolveFakeOverrideOrFail
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
@@ -35,12 +37,8 @@ internal class IdSignatureHashCalculator(private val icHasher: ICHasher) {
private val IrFunction.inlineFunctionFlatHash: ICHash private val IrFunction.inlineFunctionFlatHash: ICHash
get() = inlineFunctionFlatHashes.getOrPut(this) { get() = inlineFunctionFlatHashes.getOrPut(this) {
val flatHash = if (isFakeOverride && this is IrSimpleFunction) { val function = if (isFakeOverride && this is IrSimpleFunction) resolveFakeOverrideOrFail() else this
resolveFakeOverride()?.let { icHasher.calculateIrFunctionHash(it) } val flatHash = icHasher.calculateIrFunctionHash(function)
?: icError("can not resolve fake override for ${render()}")
} else {
icHasher.calculateIrFunctionHash(this)
}
ICHash(symbol.calculateSymbolHash().hash.combineWith(flatHash.hash)) ICHash(symbol.calculateSymbolHash().hash.combineWith(flatHash.hash))
} }
@@ -248,3 +248,9 @@ data class IrBasedFunctionHandle(val function: IrSimpleFunction) : FunctionHandl
override fun getOverridden() = override fun getOverridden() =
function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) } function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) }
} }
private fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
if (isReal) return null
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
}
@@ -195,7 +195,7 @@ fun translateCall(
expression.superQualifierSymbol?.let { superQualifier -> expression.superQualifierSymbol?.let { superQualifier ->
val (target: IrSimpleFunction, klass: IrClass) = if (superQualifier.owner.isInterface) { val (target: IrSimpleFunction, klass: IrClass) = if (superQualifier.owner.isInterface) {
val impl = function.resolveFakeOverride()!! val impl = function.resolveFakeOverrideOrFail()
Pair(impl, impl.parentAsClass) Pair(impl, impl.parentAsClass)
} else { } else {
Pair(function, superQualifier.owner) Pair(function, superQualifier.owner)
@@ -165,7 +165,8 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl
} }
val superCallee = expression.symbol.owner val superCallee = expression.symbol.owner
if (superCallee.isDefinitelyNotDefaultImplsMethod(context.config.jvmDefaultMode)) return super.visitCall(expression) if (superCallee.isDefinitelyNotDefaultImplsMethod(context.config.jvmDefaultMode, superCallee.resolveFakeOverride()))
return super.visitCall(expression)
val redirectTarget = context.cachedDeclarations.getDefaultImplsFunction(superCallee) val redirectTarget = context.cachedDeclarations.getDefaultImplsFunction(superCallee)
val newCall = createDelegatingCallWithPlaceholderTypeArguments(expression, redirectTarget, context.irBuiltIns) val newCall = createDelegatingCallWithPlaceholderTypeArguments(expression, redirectTarget, context.irBuiltIns)
@@ -235,7 +236,7 @@ private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : Ir
internal fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod( internal fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod(
jvmDefaultMode: JvmDefaultMode, jvmDefaultMode: JvmDefaultMode,
implementation: IrSimpleFunction? = resolveFakeOverride() implementation: IrSimpleFunction?,
): Boolean = ): Boolean =
implementation == null || implementation == null ||
implementation.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB || implementation.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB ||
@@ -22,7 +22,10 @@ import org.jetbrains.kotlin.ir.expressions.IrReturn
import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.functions
import org.jetbrains.kotlin.ir.util.isMethodOfAny
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.ir.util.resolveFakeOverrideOrFail
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
@@ -101,7 +104,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
if (function.name.asString().endsWith("\$default")) { if (function.name.asString().endsWith("\$default")) {
continue continue
} }
val implementation = function.resolveFakeOverride() ?: error("No single implementation found for: ${function.render()}") val implementation = function.resolveFakeOverrideOrFail()
when { when {
DescriptorVisibilities.isPrivate(implementation.visibility) || implementation.isMethodOfAny() -> DescriptorVisibilities.isPrivate(implementation.visibility) || implementation.isMethodOfAny() ->
@@ -83,13 +83,13 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
// to get the backing field which would no longer exist. // to get the backing field which would no longer exist.
val inInlineFunctionScope = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false } val inInlineFunctionScope = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
if (inInlineFunctionScope) return false if (inInlineFunctionScope) return false
val backingField = property.resolveFakeOverride()!!.backingField val backingField = property.resolveFakeOverrideOrFail().backingField
return backingField?.parent == currentClass?.irElement && return backingField?.parent == currentClass?.irElement &&
backingField?.origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD backingField?.origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD
} }
private fun IrBuilderWithScope.substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression { private fun IrBuilderWithScope.substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression {
val backingField = irProperty.resolveFakeOverride()!!.backingField!! val backingField = irProperty.resolveFakeOverrideOrFail().backingField!!
return patchReceiver( return patchReceiver(
irSetField( irSetField(
patchFieldAccessReceiver(expression, irProperty), patchFieldAccessReceiver(expression, irProperty),
@@ -100,7 +100,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
} }
private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression { private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression {
val backingField = irProperty.resolveFakeOverride()!!.backingField!! val backingField = irProperty.resolveFakeOverrideOrFail().backingField!!
val patchedReceiver = patchFieldAccessReceiver(expression, irProperty) val patchedReceiver = patchFieldAccessReceiver(expression, irProperty)
return if (irProperty.isLateinit) { return if (irProperty.isLateinit) {
irBlock { irBlock {
@@ -73,8 +73,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : FileL
return true return true
val declaration = when (declarationRaw) { val declaration = when (declarationRaw) {
is IrSimpleFunction -> declarationRaw.resolveFakeOverride(allowAbstract = true)!! is IrSimpleFunction -> declarationRaw.resolveFakeOverrideMaybeAbstractOrFail()
is IrField -> declarationRaw.resolveFakeOverride() is IrField -> declarationRaw.resolveFieldFakeOverride()
else -> declarationRaw else -> declarationRaw
} }
@@ -376,15 +376,13 @@ private class SyntheticAccessorTransformer(
} }
} }
private fun IrField.resolveFakeOverride(): IrField { private fun IrField.resolveFieldFakeOverride(): IrField {
val correspondingProperty = correspondingPropertySymbol?.owner val correspondingProperty = correspondingPropertySymbol?.owner
if (correspondingProperty == null || !correspondingProperty.isFakeOverride) if (correspondingProperty == null || !correspondingProperty.isFakeOverride)
return this return this
val realProperty = correspondingProperty.resolveFakeOverride() return correspondingProperty.resolveFakeOverrideOrFail().backingField
?: throw AssertionError("No real override for ${correspondingProperty.render()}")
return realProperty.backingField
?: throw AssertionError( ?: throw AssertionError(
"Fake override property ${correspondingProperty.render()} with backing field " + "Fake override property ${correspondingProperty.render()} with backing field " +
"overrides a real property with no backing field: ${realProperty.render()}" "overrides a real property with no backing field: ${correspondingProperty.resolveFakeOverrideOrFail().render()}"
) )
} }
@@ -201,7 +201,7 @@ class JvmCachedDeclarations(
// The classes are not actually related and `I2.DefaultImpls.f` is not a fake override but a bridge. // The classes are not actually related and `I2.DefaultImpls.f` is not a fake override but a bridge.
val defaultImplsOrigin = val defaultImplsOrigin =
if (!forCompatibilityMode && !interfaceFun.isFakeOverride) interfaceFun.origin if (!forCompatibilityMode && !interfaceFun.isFakeOverride) interfaceFun.origin
else interfaceFun.resolveFakeOverride()!!.origin else interfaceFun.resolveFakeOverrideOrFail().origin
// Interface functions are public or private, with one exception: clone in Cloneable, which is protected. // Interface functions are public or private, with one exception: clone in Cloneable, which is protected.
// However, Cloneable has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend. // However, Cloneable has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend.
@@ -225,7 +225,7 @@ class JvmCachedDeclarations(
).also { ).also {
it.copyCorrespondingPropertyFrom(interfaceFun) it.copyCorrespondingPropertyFrom(interfaceFun)
if (forCompatibilityMode && !interfaceFun.resolveFakeOverride()!!.origin.isSynthetic) { if (forCompatibilityMode && !interfaceFun.resolveFakeOverrideOrFail().origin.isSynthetic) {
context.createJvmIrBuilder(it.symbol).run { context.createJvmIrBuilder(it.symbol).run {
it.annotations = it.annotations it.annotations = it.annotations
.filterNot { it.symbol.owner.constructedClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) } .filterNot { it.symbol.owner.constructedClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) }
@@ -225,7 +225,7 @@ class MemoizedInlineClassReplacements(
// When using the new mangling scheme we might run into dependencies using the old scheme // When using the new mangling scheme we might run into dependencies using the old scheme
// for which we will fall back to the old mangling scheme as well. // for which we will fall back to the old mangling scheme as well.
if (!useOldManglingScheme && replacement.name.asString().contains('-') && function.parentClassId != null) { if (!useOldManglingScheme && replacement.name.asString().contains('-') && function.parentClassId != null) {
val resolved = (function as? IrSimpleFunction)?.resolveFakeOverride(true) val resolved = (function as? IrSimpleFunction)?.resolveFakeOverrideMaybeAbstractOrFail()
if (resolved?.parentClassId?.let { classFileContainsMethod(it, replacement, context) } == false) { if (resolved?.parentClassId?.let { classFileContainsMethod(it, replacement, context) } == false) {
return buildReplacementInner(function, replacementOrigin, noFakeOverride, true, body) return buildReplacementInner(function, replacementOrigin, noFakeOverride, true, body)
} }
@@ -35,10 +35,6 @@ internal interface Complex : State {
} }
} }
fun getRealFunction(owner: IrSimpleFunction): IrSimpleFunction {
return owner.resolveFakeOverride() as IrSimpleFunction
}
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? {
val receiver = expression.superQualifierSymbol?.owner ?: irClass val receiver = expression.superQualifierSymbol?.owner ?: irClass
val irFunction = getIrFunctionFromGivenClass(receiver, expression.symbol.owner) ?: return null val irFunction = getIrFunctionFromGivenClass(receiver, expression.symbol.owner) ?: return null
@@ -19,20 +19,18 @@ val IrDeclaration.isFakeOverride: Boolean
} }
val IrSimpleFunction.target: IrSimpleFunction val IrSimpleFunction.target: IrSimpleFunction
get() = if (modality == Modality.ABSTRACT) get() = if (modality == Modality.ABSTRACT) this else resolveFakeOverrideOrFail()
this
else
resolveFakeOverride() ?: error("Could not resolveFakeOverride() for ${this.render()}")
val IrFunction.target: IrFunction get() = when (this) { val IrFunction.target: IrFunction
is IrSimpleFunction -> this.target get() = when (this) {
is IrConstructor -> this is IrSimpleFunction -> this.target
else -> error(this) is IrConstructor -> this
} else -> error(this)
}
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.collectRealOverrides( fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.collectRealOverrides(
toSkip: (T) -> Boolean = { false }, toSkip: (T) -> Boolean = { false },
filter: (T) -> Boolean = { false } filter: (T) -> Boolean = { false },
): Set<T> { ): Set<T> {
if (isReal && !toSkip(this)) return setOf(this) if (isReal && !toSkip(this)) return setOf(this)
@@ -92,31 +90,29 @@ fun Collection<IrOverridableMember>.collectAndFilterRealOverrides(): Set<IrOverr
else -> error("all members should be of the same kind, got ${map { it.render() }}") else -> error("all members should be of the same kind, got ${map { it.render() }}")
} }
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverride( fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideMaybeAbstractOrFail(): T =
allowAbstract: Boolean = false, resolveFakeOverrideMaybeAbstract() ?: error("No real overrides for ${this.render()}")
toSkip: (T) -> Boolean = { false }
): T? =
resolveFakeOverrideOrNull(allowAbstract, toSkip).also {
if (allowAbstract && it == null) {
error("No real overrides for ${this.render()}")
}
}
// TODO: use this implementation instead of any other fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideMaybeAbstract(
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideOrNull( toSkip: (T) -> Boolean = { false },
allowAbstract: Boolean = false,
toSkip: (T) -> Boolean = { false }
): T? { ): T? {
if (!isFakeOverride && !toSkip(this)) return this if (!isFakeOverride && !toSkip(this)) return this
return if (allowAbstract) { return collectRealOverrides(toSkip).firstOrNull()
collectRealOverrides(toSkip).firstOrNull() }
} else {
collectRealOverrides(toSkip, { it.modality == Modality.ABSTRACT }) fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideOrFail(): T =
.let { realOverrides -> resolveFakeOverride() ?: error("No real overrides for ${this.render()}")
// Kotlin forbids conflicts between overrides, but they may trickle down from Java.
realOverrides.singleOrNull { (it.parent as? IrClass)?.isInterface != true } // TODO: use this implementation instead of any other
// TODO: We take firstOrNull instead of singleOrNull here because of KT-36188. fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverride(
?: realOverrides.firstOrNull() toSkip: (T) -> Boolean = { false },
} ): T? {
} if (!isFakeOverride && !toSkip(this)) return this
return collectRealOverrides(toSkip) { it.modality == Modality.ABSTRACT }
.let { realOverrides ->
// Kotlin forbids conflicts between overrides, but they may trickle down from Java.
realOverrides.singleOrNull { (it.parent as? IrClass)?.isInterface != true }
// TODO: We take firstOrNull instead of singleOrNull here because of KT-36188.
?: realOverrides.firstOrNull()
}
} }
@@ -306,12 +306,6 @@ fun IrClass.isSubclassOf(ancestor: IrClass): Boolean {
return this.hasAncestorInSuperTypes() return this.hasAncestorInSuperTypes()
} }
fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
if (isReal) return null
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
}
val IrClass.isAnnotationClass get() = kind == ClassKind.ANNOTATION_CLASS val IrClass.isAnnotationClass get() = kind == ClassKind.ANNOTATION_CLASS
val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS val IrClass.isEnumClass get() = kind == ClassKind.ENUM_CLASS
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.test.backend.handlers package org.jetbrains.kotlin.test.backend.handlers
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.declarations.lazy.AbstractIrLazyFunction import org.jetbrains.kotlin.ir.declarations.lazy.AbstractIrLazyFunction
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
import org.jetbrains.kotlin.ir.util.DeserializableClass import org.jetbrains.kotlin.ir.util.DeserializableClass
import org.jetbrains.kotlin.ir.util.IdSignature import org.jetbrains.kotlin.ir.util.IdSignature
import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.ir.util.resolveFakeOverrideOrFail
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
@@ -59,7 +59,7 @@ class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(test
assertions.assertTrue(symbol.isBound) assertions.assertTrue(symbol.isBound)
val callee = symbol.owner val callee = symbol.owner
if (callee.symbol.signature in declaredInlineFunctionSignatures) { if (callee.symbol.signature in declaredInlineFunctionSignatures) {
val trueCallee = (callee as IrSimpleFunction).resolveFakeOverride()!! val trueCallee = (callee as IrSimpleFunction).resolveFakeOverrideOrFail()
assertions.assertTrue(trueCallee.hasBody()) { assertions.assertTrue(trueCallee.hasBody()) {
"IrInlineBodiesHandler: function with body expected" "IrInlineBodiesHandler: function with body expected"
} }
@@ -307,7 +307,7 @@ internal fun KotlinStubs.generateObjCCall(
receiver: ObjCCallReceiver, receiver: ObjCCallReceiver,
arguments: List<IrExpression?> arguments: List<IrExpression?>
) = builder.irBlock { ) = builder.irBlock {
val resolved = method.resolveFakeOverride(allowAbstract = true)?: method val resolved = method.resolveFakeOverrideMaybeAbstract() ?: method
val isDirect = directSymbolName != null val isDirect = directSymbolName != null
val exceptionMode = ForeignExceptionMode.byValue( val exceptionMode = ForeignExceptionMode.byValue(
@@ -306,7 +306,7 @@ internal object VirtualTablesLookup {
} }
internal fun IrSimpleFunction.findOverriddenMethodOfAny() = internal fun IrSimpleFunction.findOverriddenMethodOfAny() =
resolveFakeOverride(allowAbstract = false).takeIf { it?.parentClassOrNull?.isAny() == true } resolveFakeOverride().takeIf { it?.parentClassOrNull?.isAny() == true }
/* /*
* Special trampoline function to call actual virtual implementation. This helps with reducing * Special trampoline function to call actual virtual implementation. This helps with reducing
@@ -1533,7 +1533,7 @@ private fun ObjCExportCodeGenerator.itablePlace(irFunction: IrSimpleFunction): C
assert(irFunction.isOverridable) assert(irFunction.isOverridable)
val irClass = irFunction.parentAsClass val irClass = irFunction.parentAsClass
return if (irClass.isInterface return if (irClass.isInterface
&& (irFunction.isReal || irFunction.resolveFakeOverride(allowAbstract = true)?.parent != context.irBuiltIns.anyClass.owner) && (irFunction.isReal || irFunction.resolveFakeOverrideMaybeAbstract()?.parent != context.irBuiltIns.anyClass.owner)
) { ) {
context.getLayoutBuilder(irClass).itablePlace(irFunction) context.getLayoutBuilder(irClass).itablePlace(irFunction)
} else { } else {
@@ -1088,7 +1088,7 @@ private class InteropTransformer(
builder.at(expression) builder.at(expression)
val function = expression.symbol.owner val function = expression.symbol.owner
if ((function as? IrSimpleFunction)?.resolveFakeOverride(allowAbstract = true)?.symbol if ((function as? IrSimpleFunction)?.resolveFakeOverrideMaybeAbstract()?.symbol
== symbols.interopNativePointedRawPtrGetter) { == symbols.interopNativePointedRawPtrGetter) {
// Replace by the intrinsic call to be handled by code generator: // Replace by the intrinsic call to be handled by code generator: