JVM IR: Implement -Xjvm-default=enable
This commit is contained in:
committed by
max-kammerer
parent
48e2e1f0c1
commit
5cefd4e443
+7
-4
@@ -78,7 +78,7 @@ private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrEl
|
||||
for (function in actualClass.functions.toList()) { // Copy the list, because we are adding new declarations from the loop
|
||||
if (function.origin !== IrDeclarationOrigin.FAKE_OVERRIDE) continue
|
||||
|
||||
// In classes, only generate interface delegation for functions immediately inherited from am interface.
|
||||
// In classes, only generate interface delegation for functions immediately inherited from an interface.
|
||||
// (Otherwise, delegation will be present in the parent class)
|
||||
if (!isDefaultImplsGeneration &&
|
||||
function.overriddenSymbols.any {
|
||||
@@ -92,7 +92,9 @@ private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrEl
|
||||
val implementation = function.resolveFakeOverride() ?: continue
|
||||
if (!implementation.hasInterfaceParent() ||
|
||||
Visibilities.isPrivate(implementation.visibility) ||
|
||||
implementation.isDefinitelyNotDefaultImplsMethod() || implementation.isMethodOfAny()
|
||||
implementation.isDefinitelyNotDefaultImplsMethod() ||
|
||||
implementation.isMethodOfAny() ||
|
||||
(!context.state.jvmDefaultMode.isCompatibility && implementation.hasJvmDefault())
|
||||
) {
|
||||
continue
|
||||
}
|
||||
@@ -205,8 +207,9 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl
|
||||
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)
|
||||
if (superCallee.isDefinitelyNotDefaultImplsMethod() || superCallee.hasJvmDefault()) return super.visitCall(expression)
|
||||
|
||||
val redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee)
|
||||
val newCall = irCall(expression, redirectTarget, receiversAsArguments = true)
|
||||
@@ -222,7 +225,7 @@ internal val interfaceDefaultCallsPhase = makeIrFilePhase(
|
||||
)
|
||||
|
||||
private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||
|
||||
// TODO If there are no default _implementations_ we can avoid generating defaultImpls class entirely by moving default arg dispatchers to the interface class
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(this)
|
||||
}
|
||||
|
||||
+6
-3
@@ -45,6 +45,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
if (!irClass.isInterface) return
|
||||
|
||||
val defaultImplsIrClass = context.declarationFactory.getDefaultImplsClass(irClass)
|
||||
//TODO: Don't add DefaultImpls if it's empty. Just like the old backend...?
|
||||
irClass.declarations.add(defaultImplsIrClass)
|
||||
val members = defaultImplsIrClass.declarations
|
||||
|
||||
@@ -52,8 +53,11 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
if (function !is IrSimpleFunction) continue
|
||||
|
||||
if (function.modality != Modality.ABSTRACT && function.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
|
||||
|
||||
if(function.hasJvmDefault() && !context.state.jvmDefaultMode.isCompatibility && !mustMoveToDefaultImpls(function)) continue
|
||||
|
||||
val element = context.declarationFactory.getDefaultImplsFunction(function).also {
|
||||
if (shouldRemoveFunction(function))
|
||||
if (mustMoveToDefaultImpls(function))
|
||||
removedFunctions[function.symbol] = it.symbol
|
||||
}
|
||||
members.add(element)
|
||||
@@ -64,7 +68,6 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
if (function.hasJvmDefault() &&
|
||||
function.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
||||
) {
|
||||
// TODO: don't touch function and only generate element / DefaultImpls when needed.
|
||||
function.body = IrExpressionBodyImpl(callDefaultImpls(element, function))
|
||||
} else {
|
||||
function.body = null
|
||||
@@ -98,7 +101,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
}
|
||||
}
|
||||
|
||||
private fun shouldRemoveFunction(function: IrFunction): Boolean =
|
||||
private fun mustMoveToDefaultImpls(function: IrFunction): Boolean =
|
||||
Visibilities.isPrivate(function.visibility) && function.name != clinitName ||
|
||||
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||
function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
||||
|
||||
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.name
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: enable
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// JVM_TARGET: 1.8
|
||||
// WITH_RUNTIME
|
||||
|
||||
|
||||
Reference in New Issue
Block a user