[IrFakeOverrideBuilder] Support fake overrides for java static methods

^KT-64150
This commit is contained in:
Pavel Kunyavskiy
2024-01-11 18:33:47 +01:00
committed by Space Team
parent 8f046d36e0
commit 15094eb03a
4 changed files with 12 additions and 21 deletions
@@ -39,7 +39,7 @@ abstract class FakeOverrideBuilderStrategy(
* if no fake override should be created for this member
*/
fun fakeOverrideMember(superType: IrType, member: IrOverridableMember, clazz: IrClass): IrOverridableMember? {
return if (isVisibleForOverrideInClass(member, clazz))
return if (member.isOverridableMemberOrAccessor() && isVisibleForOverrideInClass(member, clazz))
buildFakeOverrideMember(superType, member, clazz, unimplementedOverridesStrategy)
else
null
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.collectAndFilterRealOverrides
import org.jetbrains.kotlin.ir.util.fileOrNull
import org.jetbrains.kotlin.ir.util.isFromJava
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -68,16 +69,15 @@ class IrFakeOverrideBuilder(
val allFromSuper = clazz.superTypes.flatMap { superType ->
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations
.filter { it.isOverridableMemberOrAccessor() }
.filterIsInstance<IrOverridableMember>()
.mapNotNull {
val overriddenMember = it as IrOverridableMember
val fakeOverride = strategy.fakeOverrideMember(superType, overriddenMember, clazz) ?: return@mapNotNull null
FakeOverride(fakeOverride, overriddenMember)
val fakeOverride = strategy.fakeOverrideMember(superType, it, clazz) ?: return@mapNotNull null
FakeOverride(fakeOverride, it)
}
}
val allFromSuperByName = allFromSuper.groupBy { it.override.name }
val allFromCurrentByName = clazz.declarations.filterIsInstanceAnd<IrOverridableMember> { !it.isStaticMember }.groupBy { it.name }
val allFromCurrentByName = clazz.declarations.filterIsInstance<IrOverridableMember>().groupBy { it.name }
allFromSuperByName.forEach { (name, superMembers) ->
generateOverridesInFunctionGroup(
@@ -110,7 +110,7 @@ class IrFakeOverrideBuilder(
val superClass = superType.getClass() ?: error("Unexpected super type: $superType")
superClass.declarations
.filterIsInstanceAnd<IrOverridableMember> {
it !in overriddenMembers && it.symbol !in ignoredParentSymbols && !it.isStaticMember
it !in overriddenMembers && it.symbol !in ignoredParentSymbols
}
.mapNotNull { overriddenMember ->
val fakeOverride = strategy.fakeOverrideMember(superType, overriddenMember, clazz) ?: return@mapNotNull null
@@ -126,16 +126,6 @@ class IrFakeOverrideBuilder(
return fakeOverrides
}
private val IrOverridableMember.isStaticMember: Boolean
get() = when (this) {
is IrFunction ->
dispatchReceiverParameter == null
is IrProperty ->
backingField?.isStatic == true ||
getter?.let { it.dispatchReceiverParameter == null } == true
else -> error("Unknown overridable member: ${render()}")
}
private fun generateOverridesInFunctionGroup(
membersFromSupertypes: List<FakeOverride>,
membersFromCurrent: List<IrOverridableMember>,
@@ -177,7 +167,7 @@ class IrFakeOverrideBuilder(
// because of binary incompatible changes, it's possible to have private member colliding with fake override
// In that case we shouldn't generate fake override, but also shouldn't mark them as overridden
if (!DescriptorVisibilities.isPrivate(fromCurrent.visibility)) {
if (fromCurrent.isOverridableMemberOrAccessor()) {
fromCurrent.overriddenSymbols = overridden.memoryOptimizedMap { it.original.symbol }
}
@@ -502,10 +492,10 @@ private val IrOverridableMember.returnType: IrType
}
fun IrSimpleFunction.isOverridableFunction(): Boolean =
!DescriptorVisibilities.isPrivate(visibility) && hasDispatchReceiver
!DescriptorVisibilities.isPrivate(visibility) && (hasDispatchReceiver || isFromJava())
fun IrProperty.isOverridableProperty(): Boolean =
!DescriptorVisibilities.isPrivate(visibility) && (getter.hasDispatchReceiver || setter.hasDispatchReceiver)
!DescriptorVisibilities.isPrivate(visibility) && (getter.hasDispatchReceiver || setter.hasDispatchReceiver || isFromJava())
fun IrDeclaration.isOverridableMemberOrAccessor(): Boolean = when (this) {
is IrSimpleFunction -> isOverridableFunction()
@@ -65,6 +65,7 @@ class IrOverrideChecker(
is IrSimpleFunction -> when {
subMember !is IrSimpleFunction -> return incompatible("Member kind mismatch")
superMember.hasExtensionReceiver != subMember.hasExtensionReceiver -> return incompatible("Receiver presence mismatch")
superMember.hasDispatchReceiver != subMember.hasDispatchReceiver -> return incompatible("Incompatible staticness")
superMember.isSuspend != subMember.isSuspend -> return incompatible("Incompatible suspendability")
checkIsInlineFlag && superMember.isInline -> return incompatible("Inline function can't be overridden")
@@ -78,6 +79,7 @@ class IrOverrideChecker(
is IrProperty -> when {
subMember !is IrProperty -> return incompatible("Member kind mismatch")
superMember.getter.hasExtensionReceiver != subMember.getter.hasExtensionReceiver -> return incompatible("Receiver presence mismatch")
superMember.getter.hasDispatchReceiver != subMember.getter.hasDispatchReceiver -> return incompatible("Incompatible staticness")
checkIsInlineFlag && superMember.isInline -> return incompatible("Inline property can't be overridden")
else -> {
@@ -1,5 +1,4 @@
// TARGET_BACKEND: JVM_IR
// IGNORE_CODEGEN_WITH_IR_FAKE_OVERRIDE_GENERATION: KT-64150
// FILE: AbstractBlackBoxCodegenTest.java
public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase {}