JVM_IR. Mostly remove descriptors from InterfaceDelegationLowering
This commit is contained in:
+2
-1
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.lower.createStaticFunctionWithReceivers
|
||||
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
@@ -191,7 +192,7 @@ class JvmDeclarationFactory(
|
||||
return defaultImplsMethods.getOrPut(interfaceFun) {
|
||||
val defaultImpls = getDefaultImplsClass(interfaceFun.parentAsClass)
|
||||
|
||||
val name = Name.identifier(state.typeMapper.mapAsmMethod(interfaceFun.descriptor.original).name)
|
||||
val name = Name.identifier(state.typeMapper.mapFunctionName(interfaceFun.descriptor.original, OwnerKind.IMPLEMENTATION))
|
||||
createStaticFunctionWithReceivers(
|
||||
defaultImpls, name, interfaceFun,
|
||||
dispatchReceiverType = parent.defaultType,
|
||||
|
||||
+81
-31
@@ -6,29 +6,35 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.CodegenUtil
|
||||
import org.jetbrains.kotlin.backend.common.makePhase
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyParameterDeclarationsFrom
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
|
||||
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
|
||||
import org.jetbrains.kotlin.codegen.FunctionCodegen
|
||||
import org.jetbrains.kotlin.codegen.isDefinitelyNotDefaultImplsMethod
|
||||
import org.jetbrains.kotlin.codegen.OwnerKind
|
||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||
import org.jetbrains.kotlin.descriptors.deserialization.PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrReturnImpl
|
||||
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.ir.util.isInterface
|
||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||
|
||||
@@ -43,44 +49,67 @@ class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTra
|
||||
|
||||
|
||||
private fun generateInterfaceMethods(irClass: IrClass) {
|
||||
val irClassDescriptor = irClass.descriptor
|
||||
val actualClassDescriptor = (irClass.takeIf { it.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS }?.parent as? IrClass)?.descriptor ?: irClassDescriptor
|
||||
val isDefaultImplsGeneration = actualClassDescriptor !== irClassDescriptor
|
||||
for ((interfaceFun, value) in CodegenUtil.getNonPrivateTraitMethods(actualClassDescriptor, !isDefaultImplsGeneration)) {
|
||||
val (actualClass, isDefaultImplsGeneration) = if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
|
||||
Pair(irClass.parent as IrClass, true)
|
||||
} else {
|
||||
Pair(irClass, false)
|
||||
}
|
||||
for ((interfaceFun, value) in actualClass.getNonPrivateInterfaceMethods()) {
|
||||
//skip java 8 default methods
|
||||
if (!interfaceFun.isDefinitelyNotDefaultImplsMethod() && !FunctionCodegen.isMethodOfAny(interfaceFun)) {
|
||||
generateDelegationToDefaultImpl(
|
||||
irClass, context.ir.symbols.externalSymbolTable.referenceSimpleFunction(
|
||||
interfaceFun.original
|
||||
).owner, value, isDefaultImplsGeneration
|
||||
)
|
||||
if (!interfaceFun.isDefinitelyNotDefaultImplsMethod() && !interfaceFun.isMethodOfAny()) {
|
||||
generateDelegationToDefaultImpl(irClass, interfaceFun, value, isDefaultImplsGeneration)
|
||||
}
|
||||
}
|
||||
|
||||
// CodegenUtil.getNonPrivateTraitMethods(actualClass.descriptor, !isDefaultImplsGeneration)) {
|
||||
// //skip java 8 default methods
|
||||
// if (!interfaceFun.isDefinitelyNotDefaultImplsMethod() && !FunctionCodegen.isMethodOfAny(interfaceFun)) {
|
||||
// generateDelegationToDefaultImpl(
|
||||
// irClass, context.ir.symbols.externalSymbolTable.referenceSimpleFunction(
|
||||
// interfaceFun.original
|
||||
// ).owner, value, isDefaultImplsGeneration
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
private fun generateDelegationToDefaultImpl(
|
||||
irClass: IrClass,
|
||||
interfaceFun: IrFunction,
|
||||
inheritedFun: FunctionDescriptor,
|
||||
inheritedFun: IrSimpleFunction,
|
||||
isDefaultImplsGeneration: Boolean
|
||||
) {
|
||||
val defaultImplFun = context.declarationFactory.getDefaultImplsFunction(interfaceFun)
|
||||
|
||||
val irFunction =
|
||||
if (!isDefaultImplsGeneration) IrFunctionImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
inheritedFun,
|
||||
defaultImplFun.returnType
|
||||
).also {
|
||||
it.createParameterDeclarations()
|
||||
}
|
||||
else context.declarationFactory.getDefaultImplsFunction(
|
||||
context.ir.symbols.externalSymbolTable.referenceSimpleFunction(
|
||||
inheritedFun.original
|
||||
).owner
|
||||
)
|
||||
if (!isDefaultImplsGeneration) {
|
||||
val descriptor = WrappedSimpleFunctionDescriptor(inheritedFun.descriptor.annotations, inheritedFun.descriptor.source)
|
||||
/*
|
||||
By using WrappedDescriptor, we lose information whether the function is an accessor.
|
||||
`KotlinTypeMapper` needs that info to generate JVM name.
|
||||
TODO: streamline name generation.
|
||||
*/
|
||||
val name = Name.identifier(context.state.typeMapper.mapFunctionName(inheritedFun.descriptor, OwnerKind.IMPLEMENTATION))
|
||||
IrFunctionImpl(
|
||||
UNDEFINED_OFFSET,
|
||||
UNDEFINED_OFFSET,
|
||||
IrDeclarationOrigin.DEFINED,
|
||||
IrSimpleFunctionSymbolImpl(descriptor),
|
||||
name,
|
||||
Visibilities.PUBLIC,
|
||||
inheritedFun.modality,
|
||||
isInline = inheritedFun.isInline,
|
||||
isExternal = false,
|
||||
isTailrec = false,
|
||||
isSuspend = inheritedFun.isSuspend
|
||||
).apply {
|
||||
descriptor.bind(this)
|
||||
parent = inheritedFun.parent
|
||||
returnType = inheritedFun.returnType
|
||||
overriddenSymbols.addAll(inheritedFun.overriddenSymbols)
|
||||
copyParameterDeclarationsFrom(inheritedFun)
|
||||
}
|
||||
} else context.declarationFactory.getDefaultImplsFunction(inheritedFun)
|
||||
val irBody = IrBlockBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET)
|
||||
irFunction.body = irBody
|
||||
irClass.declarations.add(irFunction)
|
||||
@@ -126,4 +155,25 @@ class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTra
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrSimpleFunction.isMethodOfAny() =
|
||||
((valueParameters.size == 0 && name.asString() in setOf("hashCode", "toString")) ||
|
||||
(valueParameters.size == 1 && name.asString() == "equals" && valueParameters[0].type == context.irBuiltIns.anyType))
|
||||
|
||||
private fun IrSimpleFunction.isDefinitelyNotDefaultImplsMethod() =
|
||||
resolveFakeOverride()?.let {
|
||||
origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB && descriptor is JavaCallableMemberDescriptor
|
||||
} == true ||
|
||||
hasAnnotation(PLATFORM_DEPENDENT_ANNOTATION_FQ_NAME)
|
||||
|
||||
private fun IrClass.getNonPrivateInterfaceMethods(): List<Pair<IrSimpleFunction, IrSimpleFunction>> {
|
||||
return declarations.filterIsInstance<IrSimpleFunction>().mapNotNull { function ->
|
||||
val resolved = function.resolveFakeOverride()
|
||||
resolved?.takeIf {
|
||||
resolved !== function && // TODO: take a better look
|
||||
(resolved.parent as? IrClass)?.isInterface == true &&
|
||||
!Visibilities.isPrivate(resolved.visibility) &&
|
||||
resolved.visibility != Visibilities.INVISIBLE_FAKE
|
||||
}?.let { Pair(resolved, function) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user