From 39327a37cbe5a22fb55b6f2eaf42c3bd26cced32 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 31 Oct 2023 12:14:36 +0100 Subject: [PATCH] IR: pass also unsubstituted member to external conditions In the future version of JavaIncompatibilityRulesOverridabilityCondition for IR, we need to compute the original JVM signature of a declaration. In descriptors, it's possible simply by using `original`. --- .../actualizer/ActualFakeOverridesAdder.kt | 5 ++- .../IrObjCOverridablilityCondidtion.kt | 11 +++++- .../IrExternalOverridabilityCondition.kt | 6 +-- .../ir/overrides/IrFakeOverrideBuilder.kt | 11 ++++-- .../kotlin/ir/overrides/IrOverrideChecker.kt | 37 ++++++++++--------- 5 files changed, 41 insertions(+), 29 deletions(-) diff --git a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/ActualFakeOverridesAdder.kt b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/ActualFakeOverridesAdder.kt index 7b44ceb9d0e..2391166225b 100644 --- a/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/ActualFakeOverridesAdder.kt +++ b/compiler/ir/ir.actualization/src/main/kotlin/org/jetbrains/kotlin/backend/common/actualizer/ActualFakeOverridesAdder.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.overrides.IrOverrideChecker +import org.jetbrains.kotlin.ir.overrides.MemberWithOriginal import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol @@ -91,8 +92,8 @@ internal class ActualFakeOverridesAdder( val override = klass.declarations.firstOrNull { it is IrOverridableMember && overrideChecker.isOverridableBy( - superMember = memberFromSupertype, - subMember = it, + superMember = MemberWithOriginal(memberFromSupertype), + subMember = MemberWithOriginal(it), checkIsInlineFlag = false, ).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE } as? IrOverridableDeclaration diff --git a/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/IrObjCOverridablilityCondidtion.kt b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/IrObjCOverridablilityCondidtion.kt index 305afe342db..d34c3c5d8ee 100644 --- a/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/IrObjCOverridablilityCondidtion.kt +++ b/compiler/ir/ir.objcinterop/src/org/jetbrains/kotlin/ir/objcinterop/IrObjCOverridablilityCondidtion.kt @@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrOverridableMember import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.overrides.IrExternalOverridabilityCondition +import org.jetbrains.kotlin.ir.overrides.MemberWithOriginal /** * Describes method overriding rules for Objective-C methods. @@ -25,8 +26,14 @@ object IrObjCOverridabilityCondition : IrExternalOverridabilityCondition { override val contract = IrExternalOverridabilityCondition.Contract.BOTH override fun isOverridable( + superMember: MemberWithOriginal, + subMember: MemberWithOriginal, + ): IrExternalOverridabilityCondition.Result = + isOverridableImpl(superMember.member, subMember.member) + + private fun isOverridableImpl( superMember: IrOverridableMember, - subMember: IrOverridableMember + subMember: IrOverridableMember, ): IrExternalOverridabilityCondition.Result { if (superMember.name == subMember.name) { // Slow path: if (superMember is IrFunction && subMember is IrFunction) { @@ -74,4 +81,4 @@ object IrObjCOverridabilityCondition : IrExternalOverridabilityCondition { return true } -} \ No newline at end of file +} diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrExternalOverridabilityCondition.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrExternalOverridabilityCondition.kt index 8cbc71c1058..3848c6195c0 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrExternalOverridabilityCondition.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrExternalOverridabilityCondition.kt @@ -5,8 +5,6 @@ package org.jetbrains.kotlin.ir.overrides -import org.jetbrains.kotlin.ir.declarations.IrOverridableMember - interface IrExternalOverridabilityCondition { enum class Result { OVERRIDABLE, @@ -31,8 +29,8 @@ interface IrExternalOverridabilityCondition { * will be based on the general override checking algorithm and the other external overridability conditions. */ fun isOverridable( - superMember: IrOverridableMember, - subMember: IrOverridableMember, + superMember: MemberWithOriginal, + subMember: MemberWithOriginal, ): Result /** diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrFakeOverrideBuilder.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrFakeOverrideBuilder.kt index b4bc2cdf110..36c3a12c6a0 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrFakeOverrideBuilder.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrFakeOverrideBuilder.kt @@ -36,7 +36,7 @@ class IrFakeOverrideBuilder( ) { private val overrideChecker = IrOverrideChecker(typeSystem, externalOverridabilityConditions) - private data class FakeOverride(val override: IrOverridableMember, val original: IrOverridableMember) + internal data class FakeOverride(val override: IrOverridableMember, val original: IrOverridableMember) private var IrOverridableMember.overriddenSymbols: List get() = when (this) { @@ -153,7 +153,12 @@ class IrFakeOverrideBuilder( for (fromSupertype in membersFromSuper) { // Note: We do allow overriding multiple FOs at once one of which is `isInline=true`. - when (overrideChecker.isOverridableBy(fromSupertype.override, fromCurrent, checkIsInlineFlag = true).result) { + val overridability = overrideChecker.isOverridableBy( + MemberWithOriginal(fromSupertype), + MemberWithOriginal(fromCurrent), + checkIsInlineFlag = true, + ) + when (overridability.result) { OverrideCompatibilityInfo.Result.OVERRIDABLE -> { overridden += fromSupertype bound += fromSupertype @@ -465,7 +470,7 @@ class IrFakeOverrideBuilder( iterator.remove() continue } - val finalResult = overrideChecker.getBothWaysOverridability(overrider.override, candidate.override) + val finalResult = overrideChecker.getBothWaysOverridability(MemberWithOriginal(overrider), MemberWithOriginal(candidate)) if (finalResult == OverrideCompatibilityInfo.Result.OVERRIDABLE) { overridable.add(candidate) iterator.remove() diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverrideChecker.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverrideChecker.kt index 16e032155a3..51133720364 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverrideChecker.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/overrides/IrOverrideChecker.kt @@ -17,35 +17,36 @@ import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.* import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.TypeCheckerState +/** + * @param member declaration that should be checked for overridability. + * @param original the original, unsubstituted version of the declaration if the declaration is a fake override. + */ +class MemberWithOriginal(val member: IrOverridableMember, original: IrOverridableMember? = null) { + internal constructor(fakeOverride: IrFakeOverrideBuilder.FakeOverride) : this(fakeOverride.override, fakeOverride.original) + + val original: IrOverridableMember = original ?: member +} + class IrOverrideChecker( private val typeSystem: IrTypeSystemContext, private val externalOverridabilityConditions: List, ) { fun getBothWaysOverridability( - overriderDescriptor: IrOverridableMember, - candidateDescriptor: IrOverridableMember, + overrider: MemberWithOriginal, + candidate: MemberWithOriginal, ): Result { - val result1 = isOverridableBy( - candidateDescriptor, - overriderDescriptor, - checkIsInlineFlag = false, - ).result - - val result2 = isOverridableBy( - overriderDescriptor, - candidateDescriptor, - checkIsInlineFlag = false, - ).result + val result1 = isOverridableBy(candidate, overrider, checkIsInlineFlag = false).result + val result2 = isOverridableBy(overrider, candidate, checkIsInlineFlag = false).result return if (result1 == result2) result1 else Result.INCOMPATIBLE } fun isOverridableBy( - superMember: IrOverridableMember, - subMember: IrOverridableMember, + superMember: MemberWithOriginal, + subMember: MemberWithOriginal, checkIsInlineFlag: Boolean, ): OverrideCompatibilityInfo { - val basicResult = isOverridableByWithoutExternalConditions(superMember, subMember, checkIsInlineFlag) + val basicResult = isOverridableByWithoutExternalConditions(superMember.member, subMember.member, checkIsInlineFlag) return runExternalOverridabilityConditions(superMember, subMember, basicResult) } @@ -146,8 +147,8 @@ class IrOverrideChecker( private fun runExternalOverridabilityConditions( - superMember: IrOverridableMember, - subMember: IrOverridableMember, + superMember: MemberWithOriginal, + subMember: MemberWithOriginal, basicResult: OverrideCompatibilityInfo, ): OverrideCompatibilityInfo { var wasSuccess = basicResult.result == OverrideCompatibilityInfo.Result.OVERRIDABLE