JVM_IR: handle JvmDefault for bridges.

This commit is contained in:
Ting-Yuan Huang
2019-06-03 15:55:48 -07:00
committed by max-kammerer
parent b78d84c120
commit f07be024b7
12 changed files with 24 additions and 22 deletions
@@ -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<IrSimpleFunction>()) {
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) }
@@ -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
}
) {
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: compatibility
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: Simple.java
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: compatibility
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: Simple.java
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: compatibility
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// FILE: Simple.java
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_REFLECT
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME
@@ -1,5 +1,4 @@
// !JVM_DEFAULT_MODE: enable
// IGNORE_BACKEND: JVM_IR
// TARGET_BACKEND: JVM
// JVM_TARGET: 1.8
// WITH_RUNTIME