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:
committed by
Space Team
parent
e15894e98e
commit
39327a37cb
+3
-2
@@ -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>
|
||||
|
||||
+9
-2
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
-4
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user