Added lowering of property callable reference for provideDelegate.
PropertyDelegationLowering is now lowering all callable references to properties.
This commit is contained in:
+24
-37
@@ -46,7 +46,7 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
val kProperties = mutableListOf<IrExpression>()
|
val kProperties = mutableMapOf<VariableDescriptorWithAccessors, Pair<IrExpression, Int>>()
|
||||||
|
|
||||||
val getter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND).single()
|
val getter = genericArrayType.unsubstitutedMemberScope.getContributedFunctions(Name.identifier("get"), NoLookupLocation.FROM_BACKEND).single()
|
||||||
val typeParameterT = genericArrayType.declaredTypeParameters[0]
|
val typeParameterT = genericArrayType.declaredTypeParameters[0]
|
||||||
@@ -63,62 +63,49 @@ internal class PropertyDelegationLowering(val context: Context) : FileLoweringPa
|
|||||||
|
|
||||||
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement {
|
override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement {
|
||||||
declaration.transformChildrenVoid(this)
|
declaration.transformChildrenVoid(this)
|
||||||
val name = declaration.descriptor.name.asString()
|
|
||||||
val type = declaration.descriptor.type
|
|
||||||
|
|
||||||
val initializer = declaration.delegate.initializer!!
|
val initializer = declaration.delegate.initializer!!
|
||||||
return IrVariableImpl(declaration.startOffset, declaration.endOffset,
|
return IrVariableImpl(declaration.startOffset, declaration.endOffset,
|
||||||
declaration.origin, declaration.delegate.descriptor,
|
declaration.origin, declaration.delegate.descriptor,
|
||||||
IrBlockImpl(initializer.startOffset, initializer.endOffset, initializer.type, null,
|
IrBlockImpl(initializer.startOffset, initializer.endOffset, initializer.type, null,
|
||||||
listOf(
|
listOf(
|
||||||
transformBridgeToDelegate(name, type, declaration.getter),
|
declaration.getter,
|
||||||
transformBridgeToDelegate(name, type, declaration.setter),
|
declaration.setter,
|
||||||
initializer
|
initializer
|
||||||
).filterNotNull())
|
).filterNotNull())
|
||||||
)
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitProperty(declaration: IrProperty): IrStatement {
|
override fun visitCallableReference(expression: IrCallableReference): IrExpression {
|
||||||
declaration.transformChildrenVoid(this)
|
expression.transformChildrenVoid(this)
|
||||||
if (declaration.isDelegated) {
|
val propertyDescriptor = expression.descriptor as? VariableDescriptorWithAccessors
|
||||||
val name = declaration.descriptor.name.asString()
|
if (propertyDescriptor == null) return expression
|
||||||
val type = declaration.descriptor.returnType!!
|
val field = kProperties.getOrPut(propertyDescriptor) {
|
||||||
declaration.getter = transformBridgeToDelegate(name, type, declaration.getter)
|
val initializer = IrCallImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
declaration.setter = transformBridgeToDelegate(name, type, declaration.setter)
|
getKPropertyImplConstructorDescriptorWithProjection(propertyDescriptor.type)).apply {
|
||||||
}
|
putValueArgument(0, IrConstImpl<String>(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
return declaration
|
context.builtIns.stringType, IrConstKind.String, propertyDescriptor.name.asString()))
|
||||||
}
|
|
||||||
|
|
||||||
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<String>(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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
val index = kProperties.size
|
||||||
return irFunction
|
|
||||||
}
|
|
||||||
|
|
||||||
|
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,
|
irFile.declarations.add(0, IrFieldImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION,
|
DECLARATION_ORIGIN_KPROPERTIES_FOR_DELEGATION,
|
||||||
kPropertiesField,
|
kPropertiesField,
|
||||||
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
IrExpressionBodyImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||||
context.createArrayOfExpression(kPropertyImplType, kProperties))))
|
context.createArrayOfExpression(kPropertyImplType, initializers))))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user