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`.
This commit is contained in:
Alexander Udalov
2023-10-31 12:14:36 +01:00
committed by Space Team
parent e15894e98e
commit 39327a37cb
5 changed files with 41 additions and 29 deletions
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.overrides.IrOverrideChecker 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.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -91,8 +92,8 @@ internal class ActualFakeOverridesAdder(
val override = klass.declarations.firstOrNull { val override = klass.declarations.firstOrNull {
it is IrOverridableMember && it is IrOverridableMember &&
overrideChecker.isOverridableBy( overrideChecker.isOverridableBy(
superMember = memberFromSupertype, superMember = MemberWithOriginal(memberFromSupertype),
subMember = it, subMember = MemberWithOriginal(it),
checkIsInlineFlag = false, checkIsInlineFlag = false,
).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE ).result == OverridingUtil.OverrideCompatibilityInfo.Result.OVERRIDABLE
} as? IrOverridableDeclaration<IrSymbol> } as? IrOverridableDeclaration<IrSymbol>
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.overrides.IrExternalOverridabilityCondition import org.jetbrains.kotlin.ir.overrides.IrExternalOverridabilityCondition
import org.jetbrains.kotlin.ir.overrides.MemberWithOriginal
/** /**
* Describes method overriding rules for Objective-C methods. * Describes method overriding rules for Objective-C methods.
@@ -25,8 +26,14 @@ object IrObjCOverridabilityCondition : IrExternalOverridabilityCondition {
override val contract = IrExternalOverridabilityCondition.Contract.BOTH override val contract = IrExternalOverridabilityCondition.Contract.BOTH
override fun isOverridable( override fun isOverridable(
superMember: MemberWithOriginal,
subMember: MemberWithOriginal,
): IrExternalOverridabilityCondition.Result =
isOverridableImpl(superMember.member, subMember.member)
private fun isOverridableImpl(
superMember: IrOverridableMember, superMember: IrOverridableMember,
subMember: IrOverridableMember subMember: IrOverridableMember,
): IrExternalOverridabilityCondition.Result { ): IrExternalOverridabilityCondition.Result {
if (superMember.name == subMember.name) { // Slow path: if (superMember.name == subMember.name) { // Slow path:
if (superMember is IrFunction && subMember is IrFunction) { if (superMember is IrFunction && subMember is IrFunction) {
@@ -74,4 +81,4 @@ object IrObjCOverridabilityCondition : IrExternalOverridabilityCondition {
return true return true
} }
} }
@@ -5,8 +5,6 @@
package org.jetbrains.kotlin.ir.overrides package org.jetbrains.kotlin.ir.overrides
import org.jetbrains.kotlin.ir.declarations.IrOverridableMember
interface IrExternalOverridabilityCondition { interface IrExternalOverridabilityCondition {
enum class Result { enum class Result {
OVERRIDABLE, OVERRIDABLE,
@@ -31,8 +29,8 @@ interface IrExternalOverridabilityCondition {
* will be based on the general override checking algorithm and the other external overridability conditions. * will be based on the general override checking algorithm and the other external overridability conditions.
*/ */
fun isOverridable( fun isOverridable(
superMember: IrOverridableMember, superMember: MemberWithOriginal,
subMember: IrOverridableMember, subMember: MemberWithOriginal,
): Result ): Result
/** /**
@@ -36,7 +36,7 @@ class IrFakeOverrideBuilder(
) { ) {
private val overrideChecker = IrOverrideChecker(typeSystem, externalOverridabilityConditions) 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<IrSymbol> private var IrOverridableMember.overriddenSymbols: List<IrSymbol>
get() = when (this) { get() = when (this) {
@@ -153,7 +153,12 @@ class IrFakeOverrideBuilder(
for (fromSupertype in membersFromSuper) { for (fromSupertype in membersFromSuper) {
// Note: We do allow overriding multiple FOs at once one of which is `isInline=true`. // 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 -> { OverrideCompatibilityInfo.Result.OVERRIDABLE -> {
overridden += fromSupertype overridden += fromSupertype
bound += fromSupertype bound += fromSupertype
@@ -465,7 +470,7 @@ class IrFakeOverrideBuilder(
iterator.remove() iterator.remove()
continue continue
} }
val finalResult = overrideChecker.getBothWaysOverridability(overrider.override, candidate.override) val finalResult = overrideChecker.getBothWaysOverridability(MemberWithOriginal(overrider), MemberWithOriginal(candidate))
if (finalResult == OverrideCompatibilityInfo.Result.OVERRIDABLE) { if (finalResult == OverrideCompatibilityInfo.Result.OVERRIDABLE) {
overridable.add(candidate) overridable.add(candidate)
iterator.remove() iterator.remove()
@@ -17,35 +17,36 @@ import org.jetbrains.kotlin.resolve.OverridingUtil.OverrideCompatibilityInfo.*
import org.jetbrains.kotlin.types.AbstractTypeChecker import org.jetbrains.kotlin.types.AbstractTypeChecker
import org.jetbrains.kotlin.types.TypeCheckerState 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( class IrOverrideChecker(
private val typeSystem: IrTypeSystemContext, private val typeSystem: IrTypeSystemContext,
private val externalOverridabilityConditions: List<IrExternalOverridabilityCondition>, private val externalOverridabilityConditions: List<IrExternalOverridabilityCondition>,
) { ) {
fun getBothWaysOverridability( fun getBothWaysOverridability(
overriderDescriptor: IrOverridableMember, overrider: MemberWithOriginal,
candidateDescriptor: IrOverridableMember, candidate: MemberWithOriginal,
): Result { ): Result {
val result1 = isOverridableBy( val result1 = isOverridableBy(candidate, overrider, checkIsInlineFlag = false).result
candidateDescriptor, val result2 = isOverridableBy(overrider, candidate, checkIsInlineFlag = false).result
overriderDescriptor,
checkIsInlineFlag = false,
).result
val result2 = isOverridableBy(
overriderDescriptor,
candidateDescriptor,
checkIsInlineFlag = false,
).result
return if (result1 == result2) result1 else Result.INCOMPATIBLE return if (result1 == result2) result1 else Result.INCOMPATIBLE
} }
fun isOverridableBy( fun isOverridableBy(
superMember: IrOverridableMember, superMember: MemberWithOriginal,
subMember: IrOverridableMember, subMember: MemberWithOriginal,
checkIsInlineFlag: Boolean, checkIsInlineFlag: Boolean,
): OverrideCompatibilityInfo { ): OverrideCompatibilityInfo {
val basicResult = isOverridableByWithoutExternalConditions(superMember, subMember, checkIsInlineFlag) val basicResult = isOverridableByWithoutExternalConditions(superMember.member, subMember.member, checkIsInlineFlag)
return runExternalOverridabilityConditions(superMember, subMember, basicResult) return runExternalOverridabilityConditions(superMember, subMember, basicResult)
} }
@@ -146,8 +147,8 @@ class IrOverrideChecker(
private fun runExternalOverridabilityConditions( private fun runExternalOverridabilityConditions(
superMember: IrOverridableMember, superMember: MemberWithOriginal,
subMember: IrOverridableMember, subMember: MemberWithOriginal,
basicResult: OverrideCompatibilityInfo, basicResult: OverrideCompatibilityInfo,
): OverrideCompatibilityInfo { ): OverrideCompatibilityInfo {
var wasSuccess = basicResult.result == OverrideCompatibilityInfo.Result.OVERRIDABLE var wasSuccess = basicResult.result == OverrideCompatibilityInfo.Result.OVERRIDABLE