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
|
package org.jetbrains.kotlin.backend.jvm.ir
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||||
import org.jetbrains.kotlin.ir.types.classifierOrNull
|
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.
|
* 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
|
is IrTypeParameterSymbol -> classifier.owner.erasedUpperBound
|
||||||
else -> throw IllegalStateException()
|
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.descriptors.WrappedSimpleFunctionDescriptor
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||||
import org.jetbrains.kotlin.backend.common.ir.copyTypeParametersFrom
|
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.InitializersLowering.Companion.clinitName
|
||||||
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
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.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
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.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.isInterface
|
import org.jetbrains.kotlin.ir.util.isInterface
|
||||||
@@ -51,8 +57,15 @@ private class InterfaceLowering(val context: JvmBackendContext) : IrElementTrans
|
|||||||
val element = context.declarationFactory.getDefaultImplsFunction(function)
|
val element = context.declarationFactory.getDefaultImplsFunction(function)
|
||||||
members.add(element)
|
members.add(element)
|
||||||
element.body = function.body?.patchDeclarationParents(element)
|
element.body = function.body?.patchDeclarationParents(element)
|
||||||
function.body = null
|
if (function.hasJvmDefault() &&
|
||||||
//TODO reset modality to abstract
|
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 ||
|
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
|
||||||
|
|
||||||
|
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
|
// !JVM_DEFAULT_MODE: compatibility
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: Simple.java
|
// FILE: Simple.java
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: compatibility
|
// !JVM_DEFAULT_MODE: compatibility
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: Simple.java
|
// FILE: Simple.java
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: compatibility
|
// !JVM_DEFAULT_MODE: compatibility
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: Simple.java
|
// FILE: Simple.java
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
// !JVM_DEFAULT_MODE: enable
|
// !JVM_DEFAULT_MODE: enable
|
||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|||||||
@@ -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