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
|
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
|
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)
|
// (Otherwise, delegation will be present in the parent class)
|
||||||
if (!isDefaultImplsGeneration &&
|
if (!isDefaultImplsGeneration &&
|
||||||
function.overriddenSymbols.any {
|
function.overriddenSymbols.any {
|
||||||
@@ -92,7 +92,9 @@ private class InterfaceDelegationLowering(val context: JvmBackendContext) : IrEl
|
|||||||
val implementation = function.resolveFakeOverride() ?: continue
|
val implementation = function.resolveFakeOverride() ?: continue
|
||||||
if (!implementation.hasInterfaceParent() ||
|
if (!implementation.hasInterfaceParent() ||
|
||||||
Visibilities.isPrivate(implementation.visibility) ||
|
Visibilities.isPrivate(implementation.visibility) ||
|
||||||
implementation.isDefinitelyNotDefaultImplsMethod() || implementation.isMethodOfAny()
|
implementation.isDefinitelyNotDefaultImplsMethod() ||
|
||||||
|
implementation.isMethodOfAny() ||
|
||||||
|
(!context.state.jvmDefaultMode.isCompatibility && implementation.hasJvmDefault())
|
||||||
) {
|
) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@@ -205,8 +207,9 @@ private class InterfaceSuperCallsLowering(val context: JvmBackendContext) : IrEl
|
|||||||
if (expression.superQualifierSymbol?.owner?.isInterface != true) {
|
if (expression.superQualifierSymbol?.owner?.isInterface != true) {
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
val superCallee = (expression.symbol.owner as IrSimpleFunction).resolveFakeOverride()!!
|
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 redirectTarget = context.declarationFactory.getDefaultImplsFunction(superCallee)
|
||||||
val newCall = irCall(expression, redirectTarget, receiversAsArguments = true)
|
val newCall = irCall(expression, redirectTarget, receiversAsArguments = true)
|
||||||
@@ -222,7 +225,7 @@ internal val interfaceDefaultCallsPhase = makeIrFilePhase(
|
|||||||
)
|
)
|
||||||
|
|
||||||
private class InterfaceDefaultCallsLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
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) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildrenVoid(this)
|
||||||
}
|
}
|
||||||
|
|||||||
+6
-3
@@ -45,6 +45,7 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
|||||||
if (!irClass.isInterface) return
|
if (!irClass.isInterface) return
|
||||||
|
|
||||||
val defaultImplsIrClass = context.declarationFactory.getDefaultImplsClass(irClass)
|
val defaultImplsIrClass = context.declarationFactory.getDefaultImplsClass(irClass)
|
||||||
|
//TODO: Don't add DefaultImpls if it's empty. Just like the old backend...?
|
||||||
irClass.declarations.add(defaultImplsIrClass)
|
irClass.declarations.add(defaultImplsIrClass)
|
||||||
val members = defaultImplsIrClass.declarations
|
val members = defaultImplsIrClass.declarations
|
||||||
|
|
||||||
@@ -52,8 +53,11 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
|||||||
if (function !is IrSimpleFunction) continue
|
if (function !is IrSimpleFunction) continue
|
||||||
|
|
||||||
if (function.modality != Modality.ABSTRACT && function.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
|
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 {
|
val element = context.declarationFactory.getDefaultImplsFunction(function).also {
|
||||||
if (shouldRemoveFunction(function))
|
if (mustMoveToDefaultImpls(function))
|
||||||
removedFunctions[function.symbol] = it.symbol
|
removedFunctions[function.symbol] = it.symbol
|
||||||
}
|
}
|
||||||
members.add(element)
|
members.add(element)
|
||||||
@@ -64,7 +68,6 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
|||||||
if (function.hasJvmDefault() &&
|
if (function.hasJvmDefault() &&
|
||||||
function.origin != JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
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))
|
function.body = IrExpressionBodyImpl(callDefaultImpls(element, function))
|
||||||
} else {
|
} else {
|
||||||
function.body = null
|
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 ||
|
Visibilities.isPrivate(function.visibility) && function.name != clinitName ||
|
||||||
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||||
function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
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.IrSimpleFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
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.ir.visitors.IrElementVisitor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user