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.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>
|
||||||
|
|||||||
+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.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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user