From f07be024b7b94d301cd578075f4b6858159e9824 Mon Sep 17 00:00:00 2001 From: Ting-Yuan Huang Date: Mon, 3 Jun 2019 15:55:48 -0700 Subject: [PATCH] JVM_IR: handle JvmDefault for bridges. --- .../backend/jvm/lower/BridgeLowering.kt | 22 ++++++++++++------- .../jvm/lower/InterfaceDelegationLowering.kt | 14 ++++++++---- .../box/jvm8/defaults/bridgeInInterface2.kt | 1 - .../bridgeInInterfaceWithProperties2.kt | 1 - .../box/jvm8/defaults/bridgeWithJava.kt | 1 - .../compatibility/bridgeWithProperties.kt | 1 - .../compatibility/bridgeWithProperties2.kt | 1 - .../compatibility/bridgeWithProperties3.kt | 1 - .../codegen/box/jvm8/defaults/diamond.kt | 1 - .../codegen/box/jvm8/defaults/kt14243.kt | 1 - .../codegen/box/jvm8/defaults/kt14243_2.kt | 1 - .../noDelegationToDefaultMethodInClass.kt | 1 - 12 files changed, 24 insertions(+), 22 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt index 93331e042ab..d59cda0870c 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/BridgeLowering.kt @@ -6,8 +6,6 @@ package org.jetbrains.kotlin.backend.jvm.lower import org.jetbrains.kotlin.backend.common.ClassLoweringPass -import org.jetbrains.kotlin.backend.common.lower.SpecialBridgeMethods -import org.jetbrains.kotlin.backend.common.lower.allOverridden import org.jetbrains.kotlin.backend.common.bridges.FunctionHandle import org.jetbrains.kotlin.backend.common.bridges.findAllReachableDeclarations import org.jetbrains.kotlin.backend.common.bridges.findConcreteSuperDeclaration @@ -15,12 +13,15 @@ import org.jetbrains.kotlin.backend.common.bridges.generateBridges import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor import org.jetbrains.kotlin.backend.common.descriptors.WrappedValueParameterDescriptor import org.jetbrains.kotlin.backend.common.ir.* +import org.jetbrains.kotlin.backend.common.lower.SpecialBridgeMethods +import org.jetbrains.kotlin.backend.common.lower.allOverridden import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.ir.erasedUpperBound +import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET @@ -58,13 +59,13 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass private val specialBridgeMethods = SpecialBridgeMethods(context) override fun lower(irClass: IrClass) { - // TODO: Bridges should be generated for @JvmDefaults, so the interface check is too optimistic. - if (irClass.isInterface || irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { + if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) { return } for (member in irClass.declarations.filterIsInstance()) { - createBridges(member) + if (!irClass.isInterface || member.hasJvmDefault()) + createBridges(member) } } @@ -74,7 +75,13 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass if (irFunction.isMethodOfAny()) return if (irFunction.origin === IrDeclarationOrigin.FAKE_OVERRIDE && - irFunction.overriddenSymbols.all { it.owner.modality !== Modality.ABSTRACT && !it.owner.comesFromJava() } + irFunction.overriddenSymbols.all { + !it.owner.comesFromJava() && + if ((it.owner.parent as? IrClass)?.isInterface == true) + it.owner.hasJvmDefault() // TODO: Remove this after modality is corrected in InterfaceLowering. + else + it.owner.modality !== Modality.ABSTRACT + } ) { // All needed bridges will be generated where functions are implemented. return @@ -372,11 +379,10 @@ private class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass } - private inner class FunctionHandleForIrFunction(val irFunction: IrSimpleFunction) : FunctionHandle { override val isDeclaration get() = irFunction.origin != IrDeclarationOrigin.FAKE_OVERRIDE override val isAbstract get() = irFunction.modality == Modality.ABSTRACT - override val mayBeUsedAsSuperImplementation get() = !irFunction.parentAsClass.isInterface + override val mayBeUsedAsSuperImplementation get() = !irFunction.parentAsClass.isInterface || irFunction.hasJvmDefault() override fun getOverridden() = irFunction.overriddenSymbols.map { FunctionHandleForIrFunction(it.owner) } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt index f22969b5cfe..3ff459788c5 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceDelegationLowering.kt @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface +import org.jetbrains.kotlin.backend.jvm.ir.hasJvmDefault import org.jetbrains.kotlin.codegen.OwnerKind import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.descriptors.Modality @@ -22,14 +23,19 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET -import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.builders.irBlockBody +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irGet +import org.jetbrains.kotlin.ir.builders.irReturn +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction 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.impl.IrSimpleFunctionSymbolImpl -import org.jetbrains.kotlin.ir.types.defaultType import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.visitors.* import org.jetbrains.kotlin.name.Name @@ -80,7 +86,7 @@ private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrEl // (Otherwise, delegation will be present in the parent class) if (!isDefaultImplsGeneration && function.overriddenSymbols.any { - !it.owner.parentAsClass.isInterface && + (!it.owner.parentAsClass.isInterface || it.owner.hasJvmDefault()) && it.owner.modality != Modality.ABSTRACT } ) { diff --git a/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterface2.kt b/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterface2.kt index c760b298842..3f03978245e 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterface2.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterface2.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterfaceWithProperties2.kt b/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterfaceWithProperties2.kt index ab4e420d616..0f8d192acad 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterfaceWithProperties2.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/bridgeInInterfaceWithProperties2.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvm8/defaults/bridgeWithJava.kt b/compiler/testData/codegen/box/jvm8/defaults/bridgeWithJava.kt index 0f00dd3ea6f..73255fd30a3 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/bridgeWithJava.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/bridgeWithJava.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties.kt b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties.kt index 4e3338fa955..e39bc76d620 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: Simple.java diff --git a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties2.kt b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties2.kt index 6ee5e3d8826..eb72cc03ac2 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties2.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties2.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: Simple.java diff --git a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties3.kt b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties3.kt index 9439fa1065c..55df395bf87 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties3.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/compatibility/bridgeWithProperties3.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: compatibility -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // FILE: Simple.java diff --git a/compiler/testData/codegen/box/jvm8/defaults/diamond.kt b/compiler/testData/codegen/box/jvm8/defaults/diamond.kt index 744ec0da45e..1fd254baecb 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/diamond.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/diamond.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_REFLECT diff --git a/compiler/testData/codegen/box/jvm8/defaults/kt14243.kt b/compiler/testData/codegen/box/jvm8/defaults/kt14243.kt index a18bbb494e2..e55cba6b123 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/kt14243.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/kt14243.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvm8/defaults/kt14243_2.kt b/compiler/testData/codegen/box/jvm8/defaults/kt14243_2.kt index 5208f38f382..7f35ea1eaf8 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/kt14243_2.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/kt14243_2.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/jvm8/defaults/noDelegation/noDelegationToDefaultMethodInClass.kt b/compiler/testData/codegen/box/jvm8/defaults/noDelegation/noDelegationToDefaultMethodInClass.kt index 03e74d1a93f..23a69b0086d 100644 --- a/compiler/testData/codegen/box/jvm8/defaults/noDelegation/noDelegationToDefaultMethodInClass.kt +++ b/compiler/testData/codegen/box/jvm8/defaults/noDelegation/noDelegationToDefaultMethodInClass.kt @@ -1,5 +1,4 @@ // !JVM_DEFAULT_MODE: enable -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // JVM_TARGET: 1.8 // WITH_RUNTIME