JVM_IR: support @JvmDefaults in compatibility mode.
This commit is contained in:
committed by
max-kammerer
parent
1c32941949
commit
a447c748bc
@@ -6,13 +6,14 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_DEFAULT_FQ_NAME
|
||||
|
||||
/**
|
||||
* Computes the erased class for this type parameter according to the java erasure rules.
|
||||
@@ -37,3 +38,8 @@ val IrType.erasedUpperBound: IrClass
|
||||
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
|
||||
val IrFunction.propertyIfAccessor: IrDeclaration
|
||||
get() = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: this
|
||||
|
||||
fun IrFunction.hasJvmDefault(): Boolean = propertyIfAccessor.hasAnnotation(JVM_DEFAULT_FQ_NAME)
|
||||
|
||||
+35
-2
@@ -9,16 +9,22 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
||||
import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom
|
||||
import org.jetbrains.kotlin.backend.common.lower.InitializersLowering.Companion.clinitName
|
||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||
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.hasJvmDefault
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrExpressionBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
@@ -51,8 +57,15 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
val element = context.declarationFactory.getDefaultImplsFunction(function)
|
||||
members.add(element)
|
||||
element.body = function.body?.patchDeclarationParents(element)
|
||||
function.body = null
|
||||
//TODO reset modality to abstract
|
||||
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
|
||||
//TODO reset modality to abstract
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +80,26 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
||||
Visibilities.isPrivate(function.visibility) && function.name != clinitName ||
|
||||
function.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER ||
|
||||
function.origin == JvmLoweredDeclarationOrigin.SYNTHETIC_METHOD_FOR_PROPERTY_ANNOTATIONS
|
||||
|
||||
private fun callDefaultImpls(defaultImpls: IrFunction, interfaceMethod: IrFunction): IrCall {
|
||||
val startOffset = interfaceMethod.startOffset
|
||||
val endOffset = interfaceMethod.endOffset
|
||||
|
||||
return IrCallImpl(interfaceMethod.startOffset, interfaceMethod.endOffset, interfaceMethod.returnType, defaultImpls.symbol).apply {
|
||||
passTypeArgumentsFrom(interfaceMethod)
|
||||
|
||||
var offset = 0
|
||||
interfaceMethod.dispatchReceiverParameter?.let {
|
||||
putValueArgument(offset++, IrGetValueImpl(startOffset, endOffset, it.symbol))
|
||||
}
|
||||
interfaceMethod.extensionReceiverParameter?.let {
|
||||
putValueArgument(offset++, IrGetValueImpl(startOffset, endOffset, it.symbol))
|
||||
}
|
||||
interfaceMethod.valueParameters.forEachIndexed { i, it ->
|
||||
putValueArgument(i + offset, IrGetValueImpl(startOffset, endOffset, it.symbol))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// !JVM_DEFAULT_MODE: compatibility
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
// FILE: Simple.java
|
||||
|
||||
|
||||
-1
@@ -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_RUNTIME
|
||||
|
||||
@@ -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