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.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<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.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
}
}
}
@@ -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
/**
@@ -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<IrSymbol>
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()
@@ -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<IrExternalOverridabilityCondition>,
) {
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