JVM_IR. Mostly remove descriptors from InterfaceLowering

Descriptors are only used to generate a new method name via a call to
KotlinTypeMapper.
This commit is contained in:
Georgy Bronnikov
2018-10-25 13:07:08 +03:00
parent 55b65546fa
commit cbc46fe6e4
8 changed files with 99 additions and 121 deletions
@@ -153,10 +153,10 @@ fun IrClass.addSimpleDelegatingConstructor(
val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true val IrCall.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true val IrFunctionReference.isSuspend get() = (symbol.owner as? IrSimpleFunction)?.isSuspend == true
fun IrValueParameter.copyTo( fun IrValueParameter.copyTo(
irFunction: IrFunction, irFunction: IrFunction,
shift: Int = 0, shift: Int = 0,
index: Int? = null,
startOffset: Int = this.startOffset, startOffset: Int = this.startOffset,
endOffset: Int = this.endOffset, endOffset: Int = this.endOffset,
origin: IrDeclarationOrigin = this.origin, origin: IrDeclarationOrigin = this.origin,
@@ -164,13 +164,16 @@ fun IrValueParameter.copyTo(
type: IrType = this.type.remapTypeParameters(this.parent as IrTypeParametersContainer, irFunction), type: IrType = this.type.remapTypeParameters(this.parent as IrTypeParametersContainer, irFunction),
varargElementType: IrType? = this.varargElementType varargElementType: IrType? = this.varargElementType
): IrValueParameter { ): IrValueParameter {
// You cannot specify both index and nontrivial shift.
assert(index == null || shift == 0)
val newIndex = index ?: (shift + this.index)
val descriptor = WrappedValueParameterDescriptor(symbol.descriptor.annotations, symbol.descriptor.source) val descriptor = WrappedValueParameterDescriptor(symbol.descriptor.annotations, symbol.descriptor.source)
val symbol = IrValueParameterSymbolImpl(descriptor) val symbol = IrValueParameterSymbolImpl(descriptor)
val defaultValueCopy = defaultValue?.deepCopyWithVariables() val defaultValueCopy = defaultValue?.deepCopyWithVariables()
defaultValueCopy?.patchDeclarationParents(irFunction) defaultValueCopy?.patchDeclarationParents(irFunction)
return IrValueParameterImpl( return IrValueParameterImpl(
startOffset, endOffset, origin, symbol, startOffset, endOffset, origin, symbol,
name, shift + index, type, varargElementType, isCrossinline, isNoinline name, newIndex, type, varargElementType, isCrossinline, isNoinline
).also { ).also {
descriptor.bind(it) descriptor.bind(it)
it.parent = irFunction it.parent = irFunction
@@ -36,6 +36,8 @@ import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.types.ErrorUtils import org.jetbrains.kotlin.types.ErrorUtils
import org.jetbrains.org.objectweb.asm.Opcodes import org.jetbrains.org.objectweb.asm.Opcodes
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import java.io.File
import java.lang.RuntimeException
open class ClassCodegen protected constructor( open class ClassCodegen protected constructor(
internal val irClass: IrClass, internal val irClass: IrClass,
@@ -62,11 +64,15 @@ open class ClassCodegen protected constructor(
private val fileEntry = sourceManager.getFileEntry(irClass.fileParent) private val fileEntry = sourceManager.getFileEntry(irClass.fileParent)
val psiElement = irClass.descriptor.psiElement!! val psiElement = irClass.descriptor.psiElement
val visitor: ClassBuilder = createClassBuilder() val visitor: ClassBuilder = createClassBuilder()
open fun createClassBuilder() = state.factory.newVisitor(OtherOrigin(psiElement, descriptor), type, psiElement.containingFile) open fun createClassBuilder() = state.factory.newVisitor(
OtherOrigin(psiElement, descriptor),
type,
psiElement?.containingFile?.let { setOf(it) } ?: emptySet()
)
private var sourceMapper: DefaultSourceMapper? = null private var sourceMapper: DefaultSourceMapper? = null
@@ -83,8 +89,10 @@ open class ClassCodegen protected constructor(
signature.superclassName, signature.superclassName,
signature.interfaces.toTypedArray() signature.interfaces.toTypedArray()
) )
AnnotationCodegen.forClass(visitor.visitor, this, state).genAnnotations(descriptor, null) AnnotationCodegen.forClass(visitor.visitor, this, typeMapper).genAnnotations(descriptor, null)
visitor.visitSource(irClass.symbol.descriptor.source.containingFile.name!!, null) /* TODO: Temporary workaround: ClassBuilder needs a pathless name. */
val shortName = File(fileEntry.name).name
visitor.visitSource(shortName, null)
irClass.declarations.forEach { irClass.declarations.forEach {
generateDeclaration(it) generateDeclaration(it)
@@ -17,6 +17,7 @@ import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.resolve.source.PsiSourceElement
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
import java.io.File
class IrFrameMap : FrameMapBase<IrSymbol>() class IrFrameMap : FrameMapBase<IrSymbol>()
@@ -52,11 +53,12 @@ fun JvmBackendContext.getSourceMapper(declaration: IrClass): DefaultSourceMapper
// whole file the class is declared in rather than the class only. // whole file the class is declared in rather than the class only.
// TODO: revise // TODO: revise
val endLineNumber = fileEntry.getSourceRangeInfo(0, fileEntry.maxOffset).endLineNumber val endLineNumber = fileEntry.getSourceRangeInfo(0, fileEntry.maxOffset).endLineNumber
val shortName = File(declaration.fileParent.name).name
return DefaultSourceMapper( return DefaultSourceMapper(
SourceInfo.createInfoForIr( SourceInfo.createInfoForIr(
endLineNumber + 1, endLineNumber + 1,
this.state.typeMapper.mapType(declaration.descriptor).internalName, this.state.typeMapper.mapType(declaration.descriptor).internalName,
declaration.descriptor.psiElement!!.containingFile.name shortName
) )
) )
} }
@@ -5,24 +5,23 @@
package org.jetbrains.kotlin.backend.jvm.descriptors package org.jetbrains.kotlin.backend.jvm.descriptors
import org.jetbrains.kotlin.backend.common.descriptors.WrappedClassDescriptor
import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory import org.jetbrains.kotlin.backend.common.ir.DeclarationFactory
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.lower.createFunctionAndMapVariables
import org.jetbrains.kotlin.backend.jvm.lower.createStaticFunctionWithReceivers import org.jetbrains.kotlin.backend.jvm.lower.createStaticFunctionWithReceivers
import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject import org.jetbrains.kotlin.builtins.CompanionObjectMapping.isMappedIntrinsicCompanionObject
import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ClassConstructorDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.PropertyDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFieldImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrClassSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrConstructorSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
@@ -187,46 +186,39 @@ class JvmDeclarationFactory(
} }
fun getDefaultImplsFunction(interfaceFun: IrFunction): IrFunction { fun getDefaultImplsFunction(interfaceFun: IrFunction): IrFunction {
assert(interfaceFun.parentAsClass.isInterface) { "Parent of ${interfaceFun.dump()} should be interface" } val parent = interfaceFun.parentAsClass
assert(parent.isInterface) { "Parent of ${interfaceFun.dump()} should be interface" }
return defaultImplsMethods.getOrPut(interfaceFun) { return defaultImplsMethods.getOrPut(interfaceFun) {
val defaultImpls = getDefaultImplsClass(interfaceFun.parentAsClass) val defaultImpls = getDefaultImplsClass(interfaceFun.parentAsClass)
createDefaultImplFunDescriptor( val name = Name.identifier(state.typeMapper.mapAsmMethod(interfaceFun.descriptor.original).name)
defaultImpls.descriptor as DefaultImplsClassDescriptor, createStaticFunctionWithReceivers(
interfaceFun.descriptor.original, defaultImpls, name, interfaceFun,
interfaceFun.parentAsClass.descriptor, dispatchReceiverType = parent.defaultType,
state.typeMapper origin = JvmLoweredDeclarationOrigin.DEFAULT_IMPLS
).createFunctionAndMapVariables(
interfaceFun, defaultImpls, symbolTable = symbolTable, origin = JvmLoweredDeclarationOrigin.DEFAULT_IMPLS
) )
} }
} }
fun getDefaultImplsClass(interfaceClass: IrClass): IrClass = fun getDefaultImplsClass(interfaceClass: IrClass): IrClass =
defaultImplsClasses.getOrPut(interfaceClass) { defaultImplsClasses.getOrPut(interfaceClass) {
val descriptor = WrappedClassDescriptor()
IrClassImpl( IrClassImpl(
interfaceClass.startOffset, interfaceClass.endOffset, JvmLoweredDeclarationOrigin.DEFAULT_IMPLS, interfaceClass.startOffset, interfaceClass.endOffset,
createDefaultImplsClassDescriptor(interfaceClass.descriptor) JvmLoweredDeclarationOrigin.DEFAULT_IMPLS,
).also { IrClassSymbolImpl(descriptor),
it.parent = interfaceClass Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME),
ClassKind.CLASS,
Visibilities.PUBLIC,
Modality.FINAL,
isCompanion = false,
isInner = false,
isData = false,
isExternal = false,
isInline = false
).apply {
descriptor.bind(this)
parent = interfaceClass
} }
} }
companion object {
private fun createDefaultImplsClassDescriptor(interfaceDescriptor: ClassDescriptor): DefaultImplsClassDescriptorImpl {
return DefaultImplsClassDescriptorImpl(
Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME), interfaceDescriptor, interfaceDescriptor.source
)
}
private fun createDefaultImplFunDescriptor(
defaultImplsDescriptor: DefaultImplsClassDescriptor,
descriptor: FunctionDescriptor,
interfaceDescriptor: ClassDescriptor, typeMapper: KotlinTypeMapper
): SimpleFunctionDescriptorImpl {
val name = Name.identifier(typeMapper.mapAsmMethod(descriptor).name)
return createStaticFunctionWithReceivers(defaultImplsDescriptor, name, descriptor, interfaceDescriptor.defaultType)
}
}
} }
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.lower.irNot import org.jetbrains.kotlin.backend.common.lower.irNot
import org.jetbrains.kotlin.backend.common.makePhase import org.jetbrains.kotlin.backend.common.makePhase
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.descriptors.DefaultImplsClassDescriptor import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl import org.jetbrains.kotlin.backend.jvm.descriptors.JvmFunctionDescriptorImpl
import org.jetbrains.kotlin.codegen.AsmUtil.isAbstractMethod import org.jetbrains.kotlin.codegen.AsmUtil.isAbstractMethod
@@ -55,6 +56,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils.getSuperClassDescriptor
import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface import org.jetbrains.kotlin.resolve.DescriptorUtils.isInterface
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation import org.jetbrains.kotlin.resolve.jvm.annotations.hasJvmDefaultAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.org.objectweb.asm.Opcodes.* import org.jetbrains.org.objectweb.asm.Opcodes.*
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
@@ -71,7 +73,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
override fun lower(irClass: IrClass) { override fun lower(irClass: IrClass) {
val classDescriptor = irClass.descriptor val classDescriptor = irClass.descriptor
if (classDescriptor is DefaultImplsClassDescriptor) { if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
return /*TODO?*/ return /*TODO?*/
} }
@@ -88,7 +90,7 @@ class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
//additional bridges for inherited interface methods //additional bridges for inherited interface methods
if (!DescriptorUtils.isInterface(classDescriptor) && classDescriptor !is DefaultImplsClassDescriptor) { if (!DescriptorUtils.isInterface(classDescriptor) && irClass.origin != JvmLoweredDeclarationOrigin.DEFAULT_IMPLS) {
for (memberDescriptor in DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)) { for (memberDescriptor in DescriptorUtils.getAllDescriptors(classDescriptor.defaultType.memberScope)) {
if (memberDescriptor is CallableMemberDescriptor) { if (memberDescriptor is CallableMemberDescriptor) {
if (!memberDescriptor.kind.isReal && findInterfaceImplementation(memberDescriptor) == null) { if (!memberDescriptor.kind.isReal && findInterfaceImplementation(memberDescriptor) == null) {
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CodegenUtil import org.jetbrains.kotlin.backend.common.CodegenUtil
import org.jetbrains.kotlin.backend.common.makePhase import org.jetbrains.kotlin.backend.common.makePhase
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.JvmLoweredStatementOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface import org.jetbrains.kotlin.backend.jvm.codegen.isJvmInterface
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptor
@@ -43,7 +44,7 @@ class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTra
private fun generateInterfaceMethods(irClass: IrClass) { private fun generateInterfaceMethods(irClass: IrClass) {
val irClassDescriptor = irClass.descriptor val irClassDescriptor = irClass.descriptor
val actualClassDescriptor = (irClassDescriptor as? DefaultImplsClassDescriptor)?.correspondingInterface ?: irClassDescriptor val actualClassDescriptor = (irClass.takeIf { it.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS }?.parent as? IrClass)?.descriptor ?: irClassDescriptor
val isDefaultImplsGeneration = actualClassDescriptor !== irClassDescriptor val isDefaultImplsGeneration = actualClassDescriptor !== irClassDescriptor
for ((interfaceFun, value) in CodegenUtil.getNonPrivateTraitMethods(actualClassDescriptor, !isDefaultImplsGeneration)) { for ((interfaceFun, value) in CodegenUtil.getNonPrivateTraitMethods(actualClassDescriptor, !isDefaultImplsGeneration)) {
//skip java 8 default methods //skip java 8 default methods
@@ -6,27 +6,24 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass 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.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
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.VariableRemapperDesc
import org.jetbrains.kotlin.backend.common.makePhase import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl
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.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.createParameterDeclarations
import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.org.objectweb.asm.Opcodes
class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass { class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
@@ -40,10 +37,9 @@ class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVo
val members = defaultImplsIrClass.declarations val members = defaultImplsIrClass.declarations
irClass.declarations.filterIsInstance<IrFunction>().forEach { irClass.declarations.filterIsInstance<IrFunction>().forEach {
val descriptor = it.descriptor
if (it.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER) { if (it.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER) {
members.add(it) //just copy $default to DefaultImpls members.add(it) //just copy $default to DefaultImpls
} else if (descriptor.modality != Modality.ABSTRACT && it.origin != IrDeclarationOrigin.FAKE_OVERRIDE) { } else if (it is IrSimpleFunction && it.modality != Modality.ABSTRACT && it.origin != IrDeclarationOrigin.FAKE_OVERRIDE) {
val element = context.declarationFactory.getDefaultImplsFunction(it) val element = context.declarationFactory.getDefaultImplsFunction(it)
members.add(element) members.add(element)
element.body = it.body element.body = it.body
@@ -52,15 +48,11 @@ class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVo
} }
} }
irClass.transformChildrenVoid(this) irClass.transformChildrenVoid(this)
//REMOVE private methods //REMOVE private methods
val privateToRemove = irClass.declarations.filterIsInstance<IrFunction>().mapNotNull { val privateToRemove = irClass.declarations.filterIsInstance<IrFunction>().filter {
val visibility = AsmUtil.getVisibilityAccessFlag(it.descriptor) Visibilities.isPrivate(it.visibility) && (it as? IrSimpleFunction)?.name != clinitName
if (visibility == Opcodes.ACC_PRIVATE && it.descriptor.name != clinitName) {
it
} else null
} }
val defaultBodies = irClass.declarations.filterIsInstance<IrFunction>().filter { val defaultBodies = irClass.declarations.filterIsInstance<IrFunction>().filter {
@@ -73,60 +65,47 @@ class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVo
internal fun createStaticFunctionWithReceivers( internal fun createStaticFunctionWithReceivers(
owner: ClassOrPackageFragmentDescriptor, irParent: IrDeclarationParent,
name: Name, name: Name,
descriptor: FunctionDescriptor,
dispatchReceiverType: KotlinType
): SimpleFunctionDescriptorImpl {
val newFunction = SimpleFunctionDescriptorImpl.create(
owner,
Annotations.EMPTY,
name,
CallableMemberDescriptor.Kind.DECLARATION, descriptor.source
)
var offset = 0
val dispatchReceiver =
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
newFunction, null, offset++, Annotations.EMPTY, Name.identifier("this"),
dispatchReceiverType, false, false, false, null, descriptor.source, null
)
val extensionReceiver =
descriptor.extensionReceiverParameter?.let { extensionReceiver ->
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
newFunction, null, offset++, Annotations.EMPTY, Name.identifier("receiver"),
extensionReceiver.value.type, false, false, false, null, extensionReceiver.source, null
)
}
val valueParameters = listOfNotNull(dispatchReceiver, extensionReceiver) +
descriptor.valueParameters.map { it.copy(newFunction, it.name, it.index + offset) }
newFunction.initialize(
null, null, emptyList()/*TODO: type parameters*/,
valueParameters, descriptor.returnType, Modality.FINAL, descriptor.visibility
)
return newFunction
}
internal fun FunctionDescriptor.createFunctionAndMapVariables(
oldFunction: IrFunction, oldFunction: IrFunction,
parentClass: IrDeclarationParent, dispatchReceiverType: IrType? = oldFunction.dispatchReceiverParameter?.type,
visibility: Visibility = oldFunction.visibility,
symbolTable: SymbolTable? = null,
origin: IrDeclarationOrigin = oldFunction.origin origin: IrDeclarationOrigin = oldFunction.origin
) = ): IrSimpleFunction {
IrFunctionImpl( val descriptor = WrappedSimpleFunctionDescriptor(Annotations.EMPTY, oldFunction.descriptor.source)
oldFunction.startOffset, oldFunction.endOffset, origin, IrSimpleFunctionSymbolImpl(this), return IrFunctionImpl(
visibility = visibility, oldFunction.startOffset, oldFunction.endOffset,
returnType = oldFunction.returnType origin,
IrSimpleFunctionSymbolImpl(descriptor),
name,
oldFunction.visibility,
Modality.FINAL,
isInline = false, isExternal = false, isTailrec = false, isSuspend = false
).apply { ).apply {
parent = parentClass descriptor.bind(this)
body = oldFunction.body parent = irParent
createParameterDeclarations(symbolTable) returnType = oldFunction.returnType
// TODO: do we really need descriptor here? This workaround is about copying `dispatchReceiver` descriptor
val mapping: Map<ValueDescriptor, IrValueParameter> =
(listOfNotNull(oldFunction.dispatchReceiverParameter!!.descriptor, oldFunction.extensionReceiverParameter?.descriptor) + oldFunction.valueParameters.map { it.descriptor })
.zip(valueParameters).toMap()
body?.transform(VariableRemapperDesc(mapping), null) copyTypeParametersFrom(oldFunction)
var offset = 0
val dispatchReceiver = oldFunction.dispatchReceiverParameter?.copyTo(
this,
name = Name.identifier("this"),
index = offset++,
type = dispatchReceiverType!!
)
val extensionReceiver = oldFunction.extensionReceiverParameter?.copyTo(
this,
name = Name.identifier("receiver"),
index = offset++
)
valueParameters.addAll(listOfNotNull(dispatchReceiver, extensionReceiver) +
oldFunction.valueParameters.map { it.copyTo(this, shift = offset) }
)
val mapping: Map<IrValueParameter, IrValueParameter> =
(listOfNotNull(oldFunction.dispatchReceiverParameter, oldFunction.extensionReceiverParameter) + oldFunction.valueParameters)
.zip(valueParameters).toMap()
body = oldFunction.body?.transform(VariableRemapper(mapping), null)
} }
}
@@ -20,8 +20,6 @@ import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
import org.jetbrains.kotlin.backend.common.makePhase import org.jetbrains.kotlin.backend.common.makePhase
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
@@ -37,16 +35,9 @@ class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLowerin
override fun visitFunction(declaration: IrFunction): IrStatement { override fun visitFunction(declaration: IrFunction): IrStatement {
return if (declaration.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER && declaration.dispatchReceiverParameter != null) { return if (declaration.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER && declaration.dispatchReceiverParameter != null) {
val newFunction = createStaticFunctionWithReceivers( createStaticFunctionWithReceivers(declaration.parent, declaration.name, declaration)
declaration.descriptor.containingDeclaration as ClassDescriptor,
declaration.descriptor.name,
declaration.descriptor,
declaration.dispatchReceiverParameter!!.descriptor.type
)
// NOTE: Fix it
newFunction.createFunctionAndMapVariables(declaration, declaration.parent, Visibilities.PUBLIC)
} else { } else {
super.visitFunction(declaration) super.visitFunction(declaration)
} }
} }
} }