From 7d433be68b66ab95931ffadb02222c88bb7e18c1 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Fri, 3 Mar 2017 16:46:36 +0300 Subject: [PATCH] Added lowering of property callable reference for provideDelegate. PropertyDelegationLowering is now lowering all callable references to properties. --- .../backend/konan/lower/DelegationLowering.kt | 61 ++++++++----------- 1 file changed, 24 insertions(+), 37 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt index f34047b1e94..4dfe4a61bf3 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/DelegationLowering.kt @@ -46,7 +46,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa } override fun lower(irFile: IrFile) { - val kProperties = mutableListOf() + val kProperties = mutableMapOf>() val getter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND).single() val typeParameterT = genericArrayType.declaredTypeParameters[0] @@ -63,62 +63,49 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement { declaration.transformChildrenVoid(this) - val name = declaration.descriptor.name.asString() - val type = declaration.descriptor.type val initializer = declaration.delegate.initializer!! return IrVariableImpl(declaration.startOffset, declaration.endOffset, declaration.origin, declaration.delegate.descriptor, IrBlockImpl(initializer.startOffset, initializer.endOffset, initializer.type, null, listOf( - transformBridgeToDelegate(name, type, declaration.getter), - transformBridgeToDelegate(name, type, declaration.setter), + declaration.getter, + declaration.setter, initializer ).filterNotNull()) ) } - override fun visitProperty(declaration: IrProperty): IrStatement { - declaration.transformChildrenVoid(this) - if (declaration.isDelegated) { - val name = declaration.descriptor.name.asString() - val type = declaration.descriptor.returnType!! - declaration.getter = transformBridgeToDelegate(name, type, declaration.getter) - declaration.setter = transformBridgeToDelegate(name, type, declaration.setter) - } - return declaration - } - - private fun transformBridgeToDelegate(name: String, type: KotlinType, irFunction: IrFunction?): IrFunction? { - irFunction?.transformChildrenVoid(object : IrElementTransformerVoid() { - override fun visitCallableReference(expression: IrCallableReference): IrExpression { - val fieldInitializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, - getKPropertyImplConstructorDescriptorWithProjection(type)).apply { - putValueArgument(0, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, - context.builtIns.stringType, IrConstKind.String, name)) - } - - val index = kProperties.size - kProperties.add(fieldInitializer) - - return IrCallImpl(expression.startOffset, expression.endOffset, substitutedGetter).apply { - dispatchReceiver = IrGetFieldImpl(expression.startOffset, expression.endOffset, kPropertiesField) - putValueArgument(0, IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, index)) - } + override fun visitCallableReference(expression: IrCallableReference): IrExpression { + expression.transformChildrenVoid(this) + val propertyDescriptor = expression.descriptor as? VariableDescriptorWithAccessors + if (propertyDescriptor == null) return expression + val field = kProperties.getOrPut(propertyDescriptor) { + val initializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, + getKPropertyImplConstructorDescriptorWithProjection(propertyDescriptor.type)).apply { + putValueArgument(0, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, + context.builtIns.stringType, IrConstKind.String, propertyDescriptor.name.asString())) } - }) - return irFunction - } + val index = kProperties.size + initializer to index + } + + return IrCallImpl(expression.startOffset, expression.endOffset, substitutedGetter).apply { + dispatchReceiver = IrGetFieldImpl(expression.startOffset, expression.endOffset, kPropertiesField) + putValueArgument(0, IrConstImpl.int(startOffset, endOffset, context.builtIns.intType, field.second)) + } + } }) - if (kProperties.size > 0) { + if (kProperties.isNotEmpty()) { + val initializers = kProperties.values.sortedBy { it.second }.map { it.first } irFile.declarations.add(0, IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION, kPropertiesField, IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, - context.createArrayOfExpression(kPropertyImplType, kProperties)))) + context.createArrayOfExpression(kPropertyImplType, initializers)))) } }