From 6c6847448915b62debd16668eb860953ac2a2d65 Mon Sep 17 00:00:00 2001 From: pyos Date: Fri, 15 Mar 2019 15:25:47 +0100 Subject: [PATCH] JVM_IR: use correct signatures for local delegated property references Which is `` where N is the index of that property in the containing class. --- .../jvm/lower/PropertyReferenceLowering.kt | 35 +++++++++++++++---- .../properties/localDelegated/defaultImpls.kt | 1 - .../localDelegated/localAndNonLocal.kt | 1 - .../localDelegated/variableOfGenericType.kt | 1 - 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt index 86b8f9c05fd..2a0fbdbd39b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/PropertyReferenceLowering.kt @@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin +import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.declarations.* import org.jetbrains.kotlin.ir.declarations.* @@ -45,9 +46,14 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class private val IrMemberAccessExpression.field: IrFieldSymbol? get() = (this as? IrPropertyReference)?.field + // Reflection metadata for local properties is serialized under the signature "" attached to the containing class. + // This maps properties to values of N. + private val localPropertyIndices = mutableMapOf() + private val IrMemberAccessExpression.signature: String - // Plain Java fields do not have a getter, but can be referenced nonetheless. - get() = getter?.owner?.let { context.state.typeMapper.mapSignatureSkipGeneric(it.descriptor).toString() } + get() = localPropertyIndices[getter]?.let { "" } + ?: getter?.owner?.let { context.state.typeMapper.mapSignatureSkipGeneric(it.descriptor).toString() } + // Plain Java fields do not have a getter, but can be referenced nonetheless. ?: TODO("plain Java field signature") private val IrMemberAccessExpression.symbol: IrSymbol @@ -74,18 +80,29 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class private val kPropertiesFieldType = context.ir.symbols.array.createType(false, listOf(makeTypeProjection(kPropertyType, Variance.OUT_VARIANCE))) + // Return some declaration the parent of which is the containing class/package for the referenced property. This is + // a bit of a hack, as the reason for not returning the container itself is the `mapImplementationOwner` call below. + // TODO: move after LocalDeclarationsLowering and always use the getter/field? (not possible right now: + // need Java field support to move below PropertiesToFieldsLowering) + private val IrMemberAccessExpression.propertyContainerChild: IrDeclaration? + get() { + var current: IrDeclaration? = getter?.owner ?: field?.owner + while (current?.parent is IrFunction) + current = current.parent as IrFunction + return current + } + // TODO: remove code duplication with CallableReferenceLowering private val IrMemberAccessExpression.parentJavaClassReference get() = IrClassReferenceImpl( startOffset, endOffset, plainJavaClass.defaultType, plainJavaClass.symbol, - CrIrType(context.state.typeMapper.mapImplementationOwner(descriptor)) + CrIrType(context.state.typeMapper.mapImplementationOwner(propertyContainerChild!!.descriptor)) ) private fun IrBuilderWithScope.buildReflectedContainerReference(expression: IrMemberAccessExpression): IrExpression { - val parent = expression.getter?.owner?.parent ?: expression.field?.owner?.parent - return when (parent) { + return when (expression.propertyContainerChild?.parent) { is IrPackageFragment -> irCall(getOrCreateKotlinPackage).apply { putValueArgument(0, expression.parentJavaClassReference) putValueArgument(1, irString(this@PropertyReferenceLowering.context.state.moduleName)) @@ -93,7 +110,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class is IrClass -> irCall(getOrCreateKotlinClass).apply { putValueArgument(0, expression.parentJavaClassReference) } - else -> irNull() + else -> throw AssertionError("referenced property not inside a class/package fragment") } } @@ -136,11 +153,17 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class isFinal = true isStatic = true } + var localPropertiesInClass = 0 irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() { override fun visitPropertyReference(expression: IrPropertyReference): IrExpression = cachedKProperty(expression) + override fun visitLocalDelegatedProperty(declaration: IrLocalDelegatedProperty): IrStatement { + localPropertyIndices[declaration.getter.symbol] = localPropertiesInClass++ + return super.visitLocalDelegatedProperty(declaration) + } + override fun visitLocalDelegatedPropertyReference(expression: IrLocalDelegatedPropertyReference): IrExpression = cachedKProperty(expression) diff --git a/compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt b/compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt index 0ade34bf712..421e7402f1b 100644 --- a/compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt +++ b/compiler/testData/codegen/box/reflection/properties/localDelegated/defaultImpls.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/properties/localDelegated/localAndNonLocal.kt b/compiler/testData/codegen/box/reflection/properties/localDelegated/localAndNonLocal.kt index 9db25f969f5..f3558748e1f 100644 --- a/compiler/testData/codegen/box/reflection/properties/localDelegated/localAndNonLocal.kt +++ b/compiler/testData/codegen/box/reflection/properties/localDelegated/localAndNonLocal.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt b/compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt index 27d70df68ce..71e0440f6eb 100644 --- a/compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt +++ b/compiler/testData/codegen/box/reflection/properties/localDelegated/variableOfGenericType.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT