Support default function lowering
This commit is contained in:
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.backend.common.lower.LateinitLowering
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.LocalFunctionsLowering
|
import org.jetbrains.kotlin.backend.common.lower.LocalFunctionsLowering
|
||||||
import org.jetbrains.kotlin.backend.common.lower.SharedVariablesLowering
|
import org.jetbrains.kotlin.backend.common.lower.SharedVariablesLowering
|
||||||
import org.jetbrains.kotlin.backend.common.lower.TailrecLowering
|
import org.jetbrains.kotlin.backend.common.lower.TailrecLowering
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
@@ -33,6 +34,11 @@ class JvmLower(val context: JvmBackendContext) {
|
|||||||
LateinitLowering(context).lower(irFile)
|
LateinitLowering(context).lower(irFile)
|
||||||
ConstAndJvmFieldPropertiesLowering().lower(irFile)
|
ConstAndJvmFieldPropertiesLowering().lower(irFile)
|
||||||
PropertiesLowering().lower(irFile)
|
PropertiesLowering().lower(irFile)
|
||||||
|
|
||||||
|
//Should be before interface lowering
|
||||||
|
DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile)
|
||||||
|
StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile)
|
||||||
|
|
||||||
InterfaceLowering(context.state).runOnFilePostfix(irFile)
|
InterfaceLowering(context.state).runOnFilePostfix(irFile)
|
||||||
InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile)
|
InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile)
|
||||||
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
||||||
|
|||||||
+51
-40
@@ -17,6 +17,7 @@
|
|||||||
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.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptorImpl
|
import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptorImpl
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering.Companion.clinitName
|
import org.jetbrains.kotlin.backend.jvm.lower.InitializersLowering.Companion.clinitName
|
||||||
@@ -36,12 +37,11 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
|
|
||||||
class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass {
|
class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||||
|
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (!DescriptorUtils.isInterface(irClass.descriptor)) {
|
if (!DescriptorUtils.isInterface(irClass.descriptor)) {
|
||||||
return
|
return
|
||||||
@@ -58,18 +58,8 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
|
|||||||
val descriptor = it.descriptor
|
val descriptor = it.descriptor
|
||||||
if (descriptor.modality != Modality.ABSTRACT) {
|
if (descriptor.modality != Modality.ABSTRACT) {
|
||||||
val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper)
|
val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper)
|
||||||
|
members.add(functionDescriptorImpl.createFunctionAndMapVariables(it))
|
||||||
val newFunction = IrFunctionImpl(it.startOffset, it.endOffset, it.origin, functionDescriptorImpl, it.body)
|
|
||||||
members.add(newFunction)
|
|
||||||
it.body = null
|
it.body = null
|
||||||
|
|
||||||
val mapping: Map<ValueDescriptor, ValueDescriptor> =
|
|
||||||
(
|
|
||||||
listOf(it.descriptor.dispatchReceiverParameter!!, it.descriptor.extensionReceiverParameter).filterNotNull() +
|
|
||||||
it.descriptor.valueParameters
|
|
||||||
).zip(functionDescriptorImpl.valueParameters).toMap()
|
|
||||||
|
|
||||||
newFunction.body?.transform(VariableRemapper(mapping), null)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,7 +74,12 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
|
|||||||
}
|
}
|
||||||
else null
|
else null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val defaultBodies = irClass.declarations.filterIsInstance<IrFunction>().filter {
|
||||||
|
it.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
|
||||||
|
}
|
||||||
irClass.declarations.removeAll(privateToRemove)
|
irClass.declarations.removeAll(privateToRemove)
|
||||||
|
irClass.declarations.removeAll(defaultBodies)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -100,33 +95,49 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid()
|
|||||||
descriptor: FunctionDescriptor,
|
descriptor: FunctionDescriptor,
|
||||||
interfaceDescriptor: ClassDescriptor, typeMapper: KotlinTypeMapper
|
interfaceDescriptor: ClassDescriptor, typeMapper: KotlinTypeMapper
|
||||||
): SimpleFunctionDescriptorImpl {
|
): SimpleFunctionDescriptorImpl {
|
||||||
|
val name = Name.identifier(typeMapper.mapAsmMethod(descriptor).name)
|
||||||
val newFunction = SimpleFunctionDescriptorImpl.create(
|
return createStaticFunctionWithReceivers(defaultImplsDescriptor, name, descriptor, interfaceDescriptor.defaultType)
|
||||||
defaultImplsDescriptor, AnnotationsImpl(emptyList()),
|
|
||||||
Name.identifier(typeMapper.mapAsmMethod(descriptor).name),
|
|
||||||
CallableMemberDescriptor.Kind.DECLARATION, descriptor.source
|
|
||||||
)
|
|
||||||
|
|
||||||
val dispatchReceiver =
|
|
||||||
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
|
|
||||||
newFunction, null, 0, AnnotationsImpl(emptyList()), Name.identifier("this"),
|
|
||||||
interfaceDescriptor.defaultType, false, false, false, null, interfaceDescriptor.source, null)
|
|
||||||
val oldExtensionReceiver = descriptor.extensionReceiverParameter
|
|
||||||
val extensionReceiver = if (oldExtensionReceiver != null )
|
|
||||||
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
|
|
||||||
newFunction, null, 1, AnnotationsImpl(emptyList()), Name.identifier("receiver"),
|
|
||||||
oldExtensionReceiver.value.type, false, false, false, null, oldExtensionReceiver.source, null)
|
|
||||||
else null
|
|
||||||
|
|
||||||
val valueParameters = listOf(dispatchReceiver, extensionReceiver).filterNotNull() +
|
|
||||||
descriptor.valueParameters.map { it.copy(newFunction, it.name, it.index + 1) }
|
|
||||||
|
|
||||||
newFunction.initialize(
|
|
||||||
null, null, emptyList()/*TODO: type parameters*/,
|
|
||||||
valueParameters, descriptor.returnType, Modality.FINAL, descriptor.visibility
|
|
||||||
)
|
|
||||||
return newFunction
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal fun createStaticFunctionWithReceivers(owner: ClassOrPackageFragmentDescriptor, name: Name, descriptor: FunctionDescriptor, dispatchReceiverType: KotlinType): SimpleFunctionDescriptorImpl {
|
||||||
|
val newFunction = SimpleFunctionDescriptorImpl.create(
|
||||||
|
owner,
|
||||||
|
AnnotationsImpl(emptyList()),
|
||||||
|
name,
|
||||||
|
CallableMemberDescriptor.Kind.DECLARATION, descriptor.source
|
||||||
|
)
|
||||||
|
|
||||||
|
val dispatchReceiver =
|
||||||
|
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
|
||||||
|
newFunction, null, 0, AnnotationsImpl(emptyList()), Name.identifier("this"),
|
||||||
|
dispatchReceiverType, false, false, false, null, descriptor.source, null)
|
||||||
|
val extensionReceiver =
|
||||||
|
descriptor.extensionReceiverParameter?.let { extensionReceiver ->
|
||||||
|
ValueParameterDescriptorImpl.createWithDestructuringDeclarations(
|
||||||
|
newFunction, null, 1, AnnotationsImpl(emptyList()), Name.identifier("receiver"),
|
||||||
|
extensionReceiver.value.type, false, false, false, null, extensionReceiver.source, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val valueParameters = listOf(dispatchReceiver, extensionReceiver).filterNotNull() +
|
||||||
|
descriptor.valueParameters.map { it.copy(newFunction, it.name, it.index + 1) }
|
||||||
|
|
||||||
|
newFunction.initialize(
|
||||||
|
null, null, emptyList()/*TODO: type parameters*/,
|
||||||
|
valueParameters, descriptor.returnType, Modality.FINAL, descriptor.visibility
|
||||||
|
)
|
||||||
|
return newFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun FunctionDescriptor.createFunctionAndMapVariables(oldFunction: IrFunction) =
|
||||||
|
IrFunctionImpl(oldFunction.startOffset, oldFunction.endOffset, oldFunction.origin, this, oldFunction.body).also {
|
||||||
|
val mapping: Map<ValueDescriptor, ValueDescriptor> =
|
||||||
|
(
|
||||||
|
listOf(oldFunction.descriptor.dispatchReceiverParameter!!, oldFunction.descriptor.extensionReceiverParameter).filterNotNull() +
|
||||||
|
oldFunction.descriptor.valueParameters
|
||||||
|
).zip(this.valueParameters).toMap()
|
||||||
|
|
||||||
|
it.body?.transform(VariableRemapper(mapping), null)
|
||||||
|
}
|
||||||
|
|||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER
|
||||||
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
|
class StaticDefaultFunctionLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||||
|
|
||||||
|
override fun lower(irClass: IrClass) {
|
||||||
|
val descriptor = irClass.descriptor
|
||||||
|
if (DescriptorUtils.isInterface(descriptor) || DescriptorUtils.isAnnotationClass(descriptor)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
irClass.accept(this, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||||
|
if (declaration.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER && declaration.dispatchReceiverParameter != null) {
|
||||||
|
val newFunction = createStaticFunctionWithReceivers(declaration.descriptor.containingDeclaration as ClassDescriptor, declaration.descriptor.name, declaration.descriptor, declaration.descriptor.dispatchReceiverParameter!!.type)
|
||||||
|
return newFunction.createFunctionAndMapVariables(declaration)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return super.visitFunction(declaration)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user