JVM_IR: redirect super calls to DefaultImpls where necessary
This commit is contained in:
@@ -76,6 +76,7 @@ val jvmPhases = namedIrFilePhase<JvmBackendContext>(
|
|||||||
|
|
||||||
interfacePhase then
|
interfacePhase then
|
||||||
interfaceDelegationPhase then
|
interfaceDelegationPhase then
|
||||||
|
interfaceSuperCallsPhase then
|
||||||
sharedVariablesPhase then
|
sharedVariablesPhase then
|
||||||
|
|
||||||
makePatchParentsPhase(1) then
|
makePatchParentsPhase(1) then
|
||||||
|
|||||||
+38
-5
@@ -24,11 +24,14 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
|||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.util.function.UnaryOperator
|
import java.util.function.UnaryOperator
|
||||||
|
|
||||||
internal val interfaceDelegationPhase = makeIrFilePhase(
|
internal val interfaceDelegationPhase = makeIrFilePhase(
|
||||||
@@ -171,9 +174,39 @@ private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrEl
|
|||||||
|
|
||||||
private fun IrSimpleFunction.hasInterfaceParent() =
|
private fun IrSimpleFunction.hasInterfaceParent() =
|
||||||
(parent as? IrClass)?.isInterface == true
|
(parent as? IrClass)?.isInterface == true
|
||||||
|
|
||||||
private fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod() =
|
|
||||||
resolveFakeOverride()?.let { origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB } == true ||
|
|
||||||
origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
|
||||||
hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal val interfaceSuperCallsPhase = makeIrFilePhase(
|
||||||
|
lowering = ::InterfaceSuperCallsLowering,
|
||||||
|
name = "InterfaceSuperCalls",
|
||||||
|
description = "Redirect super interface calls to DefaultImpls"
|
||||||
|
)
|
||||||
|
|
||||||
|
private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||||
|
|
||||||
|
override fun lower(irFile: IrFile) {
|
||||||
|
irFile.transformChildrenVoid(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
if (expression.superQualifierSymbol?.owner?.isInterface != true) {
|
||||||
|
return super.visitCall(expression)
|
||||||
|
}
|
||||||
|
val superCallee = (expression.symbol.owner as IrSimpleFunction).resolveFakeOverride()!!
|
||||||
|
if (superCallee.isDefinitelyNotDefaultImplsMethod()) return super.visitCall(expression)
|
||||||
|
|
||||||
|
val redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee)
|
||||||
|
val newCall = irCall(expression, redirectTarget, dispatchReceiverAsFirstArgument = true)
|
||||||
|
|
||||||
|
return super.visitCall(newCall)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod() =
|
||||||
|
resolveFakeOverride()?.let { origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB } == true ||
|
||||||
|
origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||||
|
hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME) ||
|
||||||
|
(name.asString() == "clone" &&
|
||||||
|
parent.safeAs<IrClass>()?.fqNameWhenAvailable?.asString() == "kotlin.Cloneable" &&
|
||||||
|
valueParameters.isEmpty())
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// IGNORE_BACKEND: JS_IR
|
// IGNORE_BACKEND: JS_IR
|
||||||
// TODO: muted automatically, investigate should it be ran for JS or not
|
// TODO: muted automatically, investigate should it be ran for JS or not
|
||||||
// IGNORE_BACKEND: JS, NATIVE
|
// IGNORE_BACKEND: JS, NATIVE
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
interface Test {
|
interface Test {
|
||||||
fun test(): String {
|
fun test(): String {
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
interface Test {
|
interface Test {
|
||||||
fun test(): String {
|
fun test(): String {
|
||||||
|
|||||||
Reference in New Issue
Block a user