diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 2c919b6fb0d..1f53ff9db91 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -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.SharedVariablesLowering 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.jvm.lower.* import org.jetbrains.kotlin.ir.declarations.IrFile @@ -33,6 +34,11 @@ class JvmLower(val context: JvmBackendContext) { LateinitLowering(context).lower(irFile) ConstAndJvmFieldPropertiesLowering().lower(irFile) PropertiesLowering().lower(irFile) + + //Should be before interface lowering + DefaultArgumentStubGenerator(context).runOnFilePostfix(irFile) + StaticDefaultFunctionLowering(context.state).runOnFilePostfix(irFile) + InterfaceLowering(context.state).runOnFilePostfix(irFile) InterfaceDelegationLowering(context.state).runOnFilePostfix(irFile) SharedVariablesLowering(context).runOnFilePostfix(irFile) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt index b0c9aab9824..f250e46d055 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/InterfaceLowering.kt @@ -17,6 +17,7 @@ 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.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.descriptors.DefaultImplsClassDescriptorImpl 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.name.Name import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.org.objectweb.asm.Opcodes - class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass { - override fun lower(irClass: IrClass) { if (!DescriptorUtils.isInterface(irClass.descriptor)) { return @@ -58,18 +58,8 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() val descriptor = it.descriptor if (descriptor.modality != Modality.ABSTRACT) { val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper) - - val newFunction = IrFunctionImpl(it.startOffset, it.endOffset, it.origin, functionDescriptorImpl, it.body) - members.add(newFunction) + members.add(functionDescriptorImpl.createFunctionAndMapVariables(it)) it.body = null - - val mapping: Map = - ( - 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 } + + val defaultBodies = irClass.declarations.filterIsInstance().filter { + it.origin == DECLARATION_ORIGIN_FUNCTION_FOR_DEFAULT_PARAMETER + } irClass.declarations.removeAll(privateToRemove) + irClass.declarations.removeAll(defaultBodies) } companion object { @@ -100,33 +95,49 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() descriptor: FunctionDescriptor, interfaceDescriptor: ClassDescriptor, typeMapper: KotlinTypeMapper ): SimpleFunctionDescriptorImpl { - - val newFunction = SimpleFunctionDescriptorImpl.create( - 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 + val name = Name.identifier(typeMapper.mapAsmMethod(descriptor).name) + return createStaticFunctionWithReceivers(defaultImplsDescriptor, name, descriptor, interfaceDescriptor.defaultType) } } - } + + +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 = + ( + listOf(oldFunction.descriptor.dispatchReceiverParameter!!, oldFunction.descriptor.extensionReceiverParameter).filterNotNull() + + oldFunction.descriptor.valueParameters + ).zip(this.valueParameters).toMap() + + it.body?.transform(VariableRemapper(mapping), null) + } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt new file mode 100644 index 00000000000..2275b41c111 --- /dev/null +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt @@ -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) + } + } +} \ No newline at end of file