diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 6704697be40..d73431b1af5 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -102,6 +102,7 @@ class JvmBackendContext( internal val multifileFacadesToAdd = mutableMapOf>() internal val multifileFacadeForPart = mutableMapOf() + internal val multifileFacadeClassForPart = mutableMapOf() internal val multifileFacadeMemberToPartMember = mutableMapOf() internal val hiddenConstructors = mutableMapOf() diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt index 62917f277b6..3dda167522b 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt @@ -1,10 +1,11 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ package org.jetbrains.kotlin.backend.jvm.lower +import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.createImplicitParameterDeclarationWithWrappedDescriptor import org.jetbrains.kotlin.backend.common.ir.passTypeArgumentsFrom @@ -28,12 +29,14 @@ import org.jetbrains.kotlin.ir.builders.declarations.addConstructor import org.jetbrains.kotlin.ir.builders.declarations.buildClass import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl -import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom +import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl import org.jetbrains.kotlin.ir.types.typeWith import org.jetbrains.kotlin.ir.util.* 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.JavaVisibilities import org.jetbrains.kotlin.resolve.jvm.JvmClassName @@ -58,6 +61,7 @@ internal val generateMultifileFacadesPhase = namedIrModulePhase( ) UpdateFunctionCallSites(functionDelegates).lower(input) + UpdateConstantFacadePropertyReferences(context).lower(input) context.multifileFacadesToAdd.clear() @@ -139,6 +143,7 @@ private fun generateMultifileFacades( for (partClass in partClasses) { context.multifileFacadeForPart[partClass.attributeOwnerId as IrClass] = jvmClassName + context.multifileFacadeClassForPart[partClass.attributeOwnerId as IrClass] = facadeClass moveFieldsOfConstProperties(partClass, facadeClass) @@ -260,3 +265,26 @@ private class UpdateFunctionCallSites( } } } + +private class UpdateConstantFacadePropertyReferences(private val context: JvmBackendContext) : ClassLoweringPass { + override fun lower(irClass: IrClass) { + // Find property reference classes for properties whose fields were moved to the facade class. + if (irClass.origin != JvmLoweredDeclarationOrigin.GENERATED_PROPERTY_REFERENCE) + return + val property = (irClass.attributeOwnerId as? IrPropertyReference)?.getter?.owner?.correspondingPropertySymbol?.owner + ?: return + val facadeClass = context.multifileFacadeClassForPart[property.parentAsClass.attributeOwnerId] + ?: return + if (property.backingField?.shouldMoveToFacade() != true) + return + + // Replace the class reference in the body of the property reference class (in getOwner) to refer to the facade class instead. + irClass.transformChildrenVoid(object : IrElementTransformerVoid() { + override fun visitClass(declaration: IrClass): IrStatement = declaration + + override fun visitClassReference(expression: IrClassReference): IrExpression = IrClassReferenceImpl( + expression.startOffset, expression.endOffset, facadeClass.defaultType, facadeClass.symbol, facadeClass.defaultType + ) + }) + } +} 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 fad89fcc1cc..671bf8666d9 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 @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -21,7 +21,10 @@ import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.builders.declarations.* +import org.jetbrains.kotlin.ir.builders.declarations.addField +import org.jetbrains.kotlin.ir.builders.declarations.addFunction +import org.jetbrains.kotlin.ir.builders.declarations.buildClass +import org.jetbrains.kotlin.ir.builders.declarations.buildField import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl @@ -97,9 +100,9 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class private fun IrBuilderWithScope.computeSignatureString(expression: IrCallableReference): IrExpression { return expression.getter?.let { getter -> localPropertyIndices[getter]?.let { irString("") } - ?: if (getter.owner.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) { - // Default property accessor. Compute the signature now, so that we will not get into trouble - // if the getter is transformed to a static method by inline classes lowering. + ?: if (getter.owner.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR && getter.owner.parentAsClass.isInline) { + // Default property accessor in an inline class. Compute the signature now, so that we will not + // get into trouble if the getter is transformed to a static method by inline classes lowering. irString(getter.owner.signature) } else { // Delay the computation of the signature until after inline classes lowering to make sure diff --git a/compiler/testData/codegen/box/reflection/multifileClasses/callPropertiesInMultifileClass.kt b/compiler/testData/codegen/box/reflection/multifileClasses/callPropertiesInMultifileClass.kt index 43d89cd2ba5..ec9a39c7072 100644 --- a/compiler/testData/codegen/box/reflection/multifileClasses/callPropertiesInMultifileClass.kt +++ b/compiler/testData/codegen/box/reflection/multifileClasses/callPropertiesInMultifileClass.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // KT-11447 Multifile declaration causes IAE: Method can not access a member of class diff --git a/compiler/testData/codegen/box/reflection/multifileClasses/javaFieldForVarAndConstVal.kt b/compiler/testData/codegen/box/reflection/multifileClasses/javaFieldForVarAndConstVal.kt index e6d92336f09..d141dbcd8d7 100644 --- a/compiler/testData/codegen/box/reflection/multifileClasses/javaFieldForVarAndConstVal.kt +++ b/compiler/testData/codegen/box/reflection/multifileClasses/javaFieldForVarAndConstVal.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT