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:
committed by
Space Team
parent
e52529a1d1
commit
b5ba9ee671
+1
-1
@@ -469,7 +469,7 @@ internal abstract class IrExpectActualMatchingContext(
|
||||
var ir = asIr()
|
||||
|
||||
if (ir.isFakeOverride && ir is IrOverridableDeclaration<*>) {
|
||||
ir.resolveFakeOverrideOrNull()?.let { ir = it }
|
||||
ir.resolveFakeOverride()?.let { ir = it }
|
||||
}
|
||||
|
||||
return when (ir.origin) {
|
||||
|
||||
+1
-1
@@ -778,7 +778,7 @@ private fun shouldDeclarationBeExported(declaration: IrDeclarationWithName, cont
|
||||
|
||||
fun IrOverridableDeclaration<*>.isAllowedFakeOverriddenDeclaration(context: JsIrBackendContext): Boolean {
|
||||
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)) {
|
||||
|
||||
+7
-9
@@ -6,14 +6,16 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.ic
|
||||
|
||||
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.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.IdSignature
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverride
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
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.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
@@ -35,12 +37,8 @@ internal class IdSignatureHashCalculator(private val icHasher: ICHasher) {
|
||||
|
||||
private val IrFunction.inlineFunctionFlatHash: ICHash
|
||||
get() = inlineFunctionFlatHashes.getOrPut(this) {
|
||||
val flatHash = if (isFakeOverride && this is IrSimpleFunction) {
|
||||
resolveFakeOverride()?.let { icHasher.calculateIrFunctionHash(it) }
|
||||
?: icError("can not resolve fake override for ${render()}")
|
||||
} else {
|
||||
icHasher.calculateIrFunctionHash(this)
|
||||
}
|
||||
val function = if (isFakeOverride && this is IrSimpleFunction) resolveFakeOverrideOrFail() else this
|
||||
val flatHash = icHasher.calculateIrFunctionHash(function)
|
||||
ICHash(symbol.calculateSymbolHash().hash.combineWith(flatHash.hash))
|
||||
}
|
||||
|
||||
|
||||
+6
@@ -248,3 +248,9 @@ data class IrBasedFunctionHandle(val function: IrSimpleFunction) : FunctionHandl
|
||||
override fun getOverridden() =
|
||||
function.overriddenSymbols.map { IrBasedFunctionHandle(it.owner) }
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.findInterfaceImplementation(): IrSimpleFunction? {
|
||||
if (isReal) return null
|
||||
|
||||
return resolveFakeOverride()?.run { if (parentAsClass.isInterface) this else null }
|
||||
}
|
||||
|
||||
+1
-1
@@ -195,7 +195,7 @@ fun translateCall(
|
||||
|
||||
expression.superQualifierSymbol?.let { superQualifier ->
|
||||
val (target: IrSimpleFunction, klass: IrClass) = if (superQualifier.owner.isInterface) {
|
||||
val impl = function.resolveFakeOverride()!!
|
||||
val impl = function.resolveFakeOverrideOrFail()
|
||||
Pair(impl, impl.parentAsClass)
|
||||
} else {
|
||||
Pair(function, superQualifier.owner)
|
||||
|
||||
+3
-2
@@ -165,7 +165,8 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl
|
||||
}
|
||||
|
||||
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 newCall = createDelegatingCallWithPlaceholderTypeArguments(expression, redirectTarget, context.irBuiltIns)
|
||||
@@ -235,7 +236,7 @@ private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : Ir
|
||||
|
||||
internal fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod(
|
||||
jvmDefaultMode: JvmDefaultMode,
|
||||
implementation: IrSimpleFunction? = resolveFakeOverride()
|
||||
implementation: IrSimpleFunction?,
|
||||
): Boolean =
|
||||
implementation == null ||
|
||||
implementation.origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB ||
|
||||
|
||||
+5
-2
@@ -22,7 +22,10 @@ import org.jetbrains.kotlin.ir.expressions.IrReturn
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
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.transformChildrenVoid
|
||||
|
||||
@@ -101,7 +104,7 @@ internal class InterfaceLowering(val context: JvmBackendContext) : IrElementTran
|
||||
if (function.name.asString().endsWith("\$default")) {
|
||||
continue
|
||||
}
|
||||
val implementation = function.resolveFakeOverride() ?: error("No single implementation found for: ${function.render()}")
|
||||
val implementation = function.resolveFakeOverrideOrFail()
|
||||
|
||||
when {
|
||||
DescriptorVisibilities.isPrivate(implementation.visibility) || implementation.isMethodOfAny() ->
|
||||
|
||||
+3
-3
@@ -83,13 +83,13 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
// to get the backing field which would no longer exist.
|
||||
val inInlineFunctionScope = allScopes.any { scope -> (scope.irElement as? IrFunction)?.isInline ?: false }
|
||||
if (inInlineFunctionScope) return false
|
||||
val backingField = property.resolveFakeOverride()!!.backingField
|
||||
val backingField = property.resolveFakeOverrideOrFail().backingField
|
||||
return backingField?.parent == currentClass?.irElement &&
|
||||
backingField?.origin == JvmLoweredDeclarationOrigin.COMPANION_PROPERTY_BACKING_FIELD
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.substituteSetter(irProperty: IrProperty, expression: IrCall): IrExpression {
|
||||
val backingField = irProperty.resolveFakeOverride()!!.backingField!!
|
||||
val backingField = irProperty.resolveFakeOverrideOrFail().backingField!!
|
||||
return patchReceiver(
|
||||
irSetField(
|
||||
patchFieldAccessReceiver(expression, irProperty),
|
||||
@@ -100,7 +100,7 @@ class JvmPropertiesLowering(private val backendContext: JvmBackendContext) : IrE
|
||||
}
|
||||
|
||||
private fun IrBuilderWithScope.substituteGetter(irProperty: IrProperty, expression: IrCall): IrExpression {
|
||||
val backingField = irProperty.resolveFakeOverride()!!.backingField!!
|
||||
val backingField = irProperty.resolveFakeOverrideOrFail().backingField!!
|
||||
val patchedReceiver = patchFieldAccessReceiver(expression, irProperty)
|
||||
return if (irProperty.isLateinit) {
|
||||
irBlock {
|
||||
|
||||
+5
-7
@@ -73,8 +73,8 @@ internal class SyntheticAccessorLowering(val context: JvmBackendContext) : FileL
|
||||
return true
|
||||
|
||||
val declaration = when (declarationRaw) {
|
||||
is IrSimpleFunction -> declarationRaw.resolveFakeOverride(allowAbstract = true)!!
|
||||
is IrField -> declarationRaw.resolveFakeOverride()
|
||||
is IrSimpleFunction -> declarationRaw.resolveFakeOverrideMaybeAbstractOrFail()
|
||||
is IrField -> declarationRaw.resolveFieldFakeOverride()
|
||||
else -> declarationRaw
|
||||
}
|
||||
|
||||
@@ -376,15 +376,13 @@ private class SyntheticAccessorTransformer(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrField.resolveFakeOverride(): IrField {
|
||||
private fun IrField.resolveFieldFakeOverride(): IrField {
|
||||
val correspondingProperty = correspondingPropertySymbol?.owner
|
||||
if (correspondingProperty == null || !correspondingProperty.isFakeOverride)
|
||||
return this
|
||||
val realProperty = correspondingProperty.resolveFakeOverride()
|
||||
?: throw AssertionError("No real override for ${correspondingProperty.render()}")
|
||||
return realProperty.backingField
|
||||
return correspondingProperty.resolveFakeOverrideOrFail().backingField
|
||||
?: throw AssertionError(
|
||||
"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()}"
|
||||
)
|
||||
}
|
||||
|
||||
+2
-2
@@ -201,7 +201,7 @@ class JvmCachedDeclarations(
|
||||
// The classes are not actually related and `I2.DefaultImpls.f` is not a fake override but a bridge.
|
||||
val defaultImplsOrigin =
|
||||
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.
|
||||
// However, Cloneable has no DefaultImpls, so this merely replicates the incorrect behavior of the old backend.
|
||||
@@ -225,7 +225,7 @@ class JvmCachedDeclarations(
|
||||
).also {
|
||||
it.copyCorrespondingPropertyFrom(interfaceFun)
|
||||
|
||||
if (forCompatibilityMode && !interfaceFun.resolveFakeOverride()!!.origin.isSynthetic) {
|
||||
if (forCompatibilityMode && !interfaceFun.resolveFakeOverrideOrFail().origin.isSynthetic) {
|
||||
context.createJvmIrBuilder(it.symbol).run {
|
||||
it.annotations = it.annotations
|
||||
.filterNot { it.symbol.owner.constructedClass.hasEqualFqName(DeprecationResolver.JAVA_DEPRECATED) }
|
||||
|
||||
+1
-1
@@ -225,7 +225,7 @@ class MemoizedInlineClassReplacements(
|
||||
// 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.
|
||||
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) {
|
||||
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? {
|
||||
val receiver = expression.superQualifierSymbol?.owner ?: irClass
|
||||
val irFunction = getIrFunctionFromGivenClass(receiver, expression.symbol.owner) ?: return null
|
||||
|
||||
@@ -19,20 +19,18 @@ val IrDeclaration.isFakeOverride: Boolean
|
||||
}
|
||||
|
||||
val IrSimpleFunction.target: IrSimpleFunction
|
||||
get() = if (modality == Modality.ABSTRACT)
|
||||
this
|
||||
else
|
||||
resolveFakeOverride() ?: error("Could not resolveFakeOverride() for ${this.render()}")
|
||||
get() = if (modality == Modality.ABSTRACT) this else resolveFakeOverrideOrFail()
|
||||
|
||||
val IrFunction.target: IrFunction get() = when (this) {
|
||||
is IrSimpleFunction -> this.target
|
||||
is IrConstructor -> this
|
||||
else -> error(this)
|
||||
}
|
||||
val IrFunction.target: IrFunction
|
||||
get() = when (this) {
|
||||
is IrSimpleFunction -> this.target
|
||||
is IrConstructor -> this
|
||||
else -> error(this)
|
||||
}
|
||||
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.collectRealOverrides(
|
||||
toSkip: (T) -> Boolean = { false },
|
||||
filter: (T) -> Boolean = { false }
|
||||
filter: (T) -> Boolean = { false },
|
||||
): Set<T> {
|
||||
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() }}")
|
||||
}
|
||||
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverride(
|
||||
allowAbstract: Boolean = false,
|
||||
toSkip: (T) -> Boolean = { false }
|
||||
): T? =
|
||||
resolveFakeOverrideOrNull(allowAbstract, toSkip).also {
|
||||
if (allowAbstract && it == null) {
|
||||
error("No real overrides for ${this.render()}")
|
||||
}
|
||||
}
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideMaybeAbstractOrFail(): T =
|
||||
resolveFakeOverrideMaybeAbstract() ?: error("No real overrides for ${this.render()}")
|
||||
|
||||
// TODO: use this implementation instead of any other
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideOrNull(
|
||||
allowAbstract: Boolean = false,
|
||||
toSkip: (T) -> Boolean = { false }
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideMaybeAbstract(
|
||||
toSkip: (T) -> Boolean = { false },
|
||||
): T? {
|
||||
if (!isFakeOverride && !toSkip(this)) return this
|
||||
return if (allowAbstract) {
|
||||
collectRealOverrides(toSkip).firstOrNull()
|
||||
} else {
|
||||
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()
|
||||
}
|
||||
}
|
||||
return collectRealOverrides(toSkip).firstOrNull()
|
||||
}
|
||||
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverrideOrFail(): T =
|
||||
resolveFakeOverride() ?: error("No real overrides for ${this.render()}")
|
||||
|
||||
// TODO: use this implementation instead of any other
|
||||
fun <S : IrSymbol, T : IrOverridableDeclaration<S>> T.resolveFakeOverride(
|
||||
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()
|
||||
}
|
||||
|
||||
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.isEnumClass get() = kind == ClassKind.ENUM_CLASS
|
||||
val IrClass.isEnumEntry get() = kind == ClassKind.ENUM_ENTRY
|
||||
|
||||
+3
-3
@@ -6,14 +6,14 @@
|
||||
package org.jetbrains.kotlin.test.backend.handlers
|
||||
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
|
||||
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.lazy.AbstractIrLazyFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.ir.util.DeserializableClass
|
||||
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.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.test.backend.ir.IrBackendInput
|
||||
@@ -59,7 +59,7 @@ class IrInlineBodiesHandler(testServices: TestServices) : AbstractIrHandler(test
|
||||
assertions.assertTrue(symbol.isBound)
|
||||
val callee = symbol.owner
|
||||
if (callee.symbol.signature in declaredInlineFunctionSignatures) {
|
||||
val trueCallee = (callee as IrSimpleFunction).resolveFakeOverride()!!
|
||||
val trueCallee = (callee as IrSimpleFunction).resolveFakeOverrideOrFail()
|
||||
assertions.assertTrue(trueCallee.hasBody()) {
|
||||
"IrInlineBodiesHandler: function with body expected"
|
||||
}
|
||||
|
||||
+1
-1
@@ -307,7 +307,7 @@ internal fun KotlinStubs.generateObjCCall(
|
||||
receiver: ObjCCallReceiver,
|
||||
arguments: List<IrExpression?>
|
||||
) = builder.irBlock {
|
||||
val resolved = method.resolveFakeOverride(allowAbstract = true)?: method
|
||||
val resolved = method.resolveFakeOverrideMaybeAbstract() ?: method
|
||||
val isDirect = directSymbolName != null
|
||||
|
||||
val exceptionMode = ForeignExceptionMode.byValue(
|
||||
|
||||
+1
-1
@@ -306,7 +306,7 @@ internal object VirtualTablesLookup {
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
+1
-1
@@ -1533,7 +1533,7 @@ private fun ObjCExportCodeGenerator.itablePlace(irFunction: IrSimpleFunction): C
|
||||
assert(irFunction.isOverridable)
|
||||
val irClass = irFunction.parentAsClass
|
||||
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)
|
||||
} else {
|
||||
|
||||
+1
-1
@@ -1088,7 +1088,7 @@ private class InteropTransformer(
|
||||
builder.at(expression)
|
||||
val function = expression.symbol.owner
|
||||
|
||||
if ((function as? IrSimpleFunction)?.resolveFakeOverride(allowAbstract = true)?.symbol
|
||||
if ((function as? IrSimpleFunction)?.resolveFakeOverrideMaybeAbstract()?.symbol
|
||||
== symbols.interopNativePointedRawPtrGetter) {
|
||||
|
||||
// Replace by the intrinsic call to be handled by code generator:
|
||||
|
||||
Reference in New Issue
Block a user