From 567b174e157a252ae3dc0184044bf32ae06c5720 Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Wed, 28 Sep 2016 16:44:41 +0300 Subject: [PATCH] Funther default impl support --- .../backend/jvm/codegen/ExpressionCodegen.kt | 11 ++++--- .../backend/jvm/lower/InterfaceLowering.kt | 33 +++++++++++++++---- .../impl/IrPropertyAccessorCall.kt | 6 ++++ 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index 8c3783fa099..56d8cd1c9b3 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -162,16 +162,19 @@ class ExpressionCodegen( gen(receiver, callable.dispatchReceiverType!!, data) } - val args = (listOf(expression.extensionReceiver).filterNotNull() + - expression.descriptor.valueParameters.mapIndexed { i, valueParameterDescriptor -> + expression.extensionReceiver?.apply { + gen(this, callable.extensionReceiverType!!, data) + } + + val args = expression.descriptor.valueParameters.mapIndexed { i, valueParameterDescriptor -> expression.getValueArgument(i) ?: DefaultArg(i) - }) + } val defaultMask = DefaultCallArgs(callable.valueParameterTypes.size) args.forEachIndexed { i, expression -> when (expression) { is IrExpression -> { - gen(expression, callable.parameterTypes[i], data) + gen(expression, callable.valueParameterTypes[i], data) } is DefaultArg -> { pushDefaultValueOnStack(callable.parameterTypes[i], mv) 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 e00519bce2c..3a651b905e2 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 @@ -20,17 +20,21 @@ import org.jetbrains.kotlin.backend.jvm.ClassLoweringPass import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper -import org.jetbrains.kotlin.descriptors.ClassDescriptor -import org.jetbrains.kotlin.descriptors.FunctionDescriptor -import org.jetbrains.kotlin.descriptors.Modality -import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ValueParameterDescriptorImpl +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.declarations.IrVariable import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl +import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrGetVariable +import org.jetbrains.kotlin.ir.expressions.impl.IrGetVariableImpl +import org.jetbrains.kotlin.ir.util.transform +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.load.java.JvmAbi @@ -40,6 +44,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid(), ClassLoweringPass { + override fun lower(irClass: IrClass) { if (!DescriptorUtils.isInterface(irClass.descriptor)) { return @@ -57,8 +62,13 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() if (descriptor.modality != Modality.ABSTRACT) { val functionDescriptorImpl = createDefaultImplFunDescriptor(defaultImplsDescriptor, descriptor, interfaceDescriptor, state.typeMapper) - members.add(IrFunctionImpl(it.startOffset, it.endOffset, it.origin, functionDescriptorImpl, it.body)) + val newFunction = IrFunctionImpl(it.startOffset, it.endOffset, it.origin, functionDescriptorImpl, it.body) + members.add(newFunction) it.body = null + + val mapping: Map = (listOf(it.descriptor.containingDeclaration) + it.descriptor.valueParameters).zip(functionDescriptorImpl.valueParameters).toMap() + + newFunction.body?.transform(VariableRemapper(mapping), null) } } @@ -66,6 +76,9 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() irClass.transformChildrenVoid(this) } + override fun visitGetVariable(expression: IrGetVariable): IrExpression { + return super.visitGetVariable(expression) + } companion object { @@ -84,7 +97,7 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() val newFunction = SimpleFunctionDescriptorImpl.create( defaultImplsDescriptor, AnnotationsImpl(emptyList()), Name.identifier(typeMapper.mapAsmMethod(descriptor).name), - descriptor.kind, descriptor.source + CallableMemberDescriptor.Kind.DECLARATION, descriptor.source ) val valueParameters = @@ -102,3 +115,11 @@ class InterfaceLowering(val state: GenerationState) : IrElementTransformerVoid() } } + +class VariableRemapper(val mapping: Map): IrElementTransformerVoid() { + + override fun visitGetVariable(expression: IrGetVariable): IrExpression = + mapping[expression.descriptor]?.let { loweredParameter -> + IrGetVariableImpl(expression.startOffset, expression.endOffset, loweredParameter, expression.origin) + } ?: expression +} \ No newline at end of file diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt index 9c04af0bb09..9a13c26b545 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/expressions/impl/IrPropertyAccessorCall.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCallWithShallowCopy import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin +import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.types.KotlinType import java.lang.AssertionError @@ -115,4 +116,9 @@ class IrSetterCallImpl( override fun shallowCopy(newOrigin: IrStatementOrigin?, newCallee: CallableDescriptor, newSuperQualifier: ClassDescriptor?) = IrSetterCallImpl(startOffset, endOffset, newCallee, typeArguments, newOrigin, newSuperQualifier) + + override fun transformChildren(transformer: IrElementTransformer, data: D) { + super.transformChildren(transformer, data) + argumentImpl = argumentImpl?.transform(transformer, data) + } }