From 23e7468e577ce5b9c9a0c4d1c1b6e7b9855a9d46 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Mon, 19 Oct 2020 18:21:24 +0300 Subject: [PATCH] [FIR2IR] Cache Java field-based properties more correctly #KT-42805 Fixed Before this commit, we cached such IR properties by FIR property which was created by Java field each time when we referenced it. This led to signature clashes. Now we cache such IR properties directly by associated FIR field. --- .../fir/backend/Fir2IrDeclarationStorage.kt | 32 +++++++++++++++++++ .../generators/CallAndReferenceGenerator.kt | 20 +----------- .../noConflictOnKotlinGetterAndJavaField.kt | 1 - .../properties/equalsHashCodeToString.kt | 1 - .../SameJavaFieldReferences.fir.txt | 9 ++++++ 5 files changed, 42 insertions(+), 21 deletions(-) create mode 100644 compiler/testData/ir/irText/firProblems/SameJavaFieldReferences.fir.txt diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index ad9723267a2..a07f39fc0d9 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -12,6 +12,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.backend.generators.AnnotationGenerator import org.jetbrains.kotlin.fir.backend.generators.DelegatedMemberGenerator import org.jetbrains.kotlin.fir.declarations.* +import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertyGetter import org.jetbrains.kotlin.fir.declarations.impl.FirDefaultPropertySetter import org.jetbrains.kotlin.fir.descriptors.FirBuiltInsPackageFragment @@ -77,6 +78,10 @@ class Fir2IrDeclarationStorage( private val initializerCache = mutableMapOf() private val propertyCache = mutableMapOf() + + // For pure fields (from Java) only + private val fieldToPropertyCache = mutableMapOf() + private val delegatedReverseCache = mutableMapOf() private val fieldCache = mutableMapOf() @@ -669,6 +674,33 @@ class Fir2IrDeclarationStorage( return createIrProperty(property, irParent, isLocal = isLocal) } + fun getOrCreateIrPropertyByPureField( + field: FirField, + irParent: IrDeclarationParent + ): IrProperty { + fieldToPropertyCache[field]?.let { return it } + return createIrProperty(field.toStubProperty(), irParent).apply { + fieldToPropertyCache[field] = this + } + } + + private fun FirField.toStubProperty(): FirProperty { + val field = this + return buildProperty { + source = field.source + session = field.session + origin = field.origin + returnTypeRef = field.returnTypeRef + name = field.name + isVar = field.isVar + getter = field.getter + setter = field.setter + symbol = FirPropertySymbol(field.symbol.callableId) + isLocal = false + status = field.status + } + } + fun createIrProperty( property: FirProperty, irParent: IrDeclarationParent?, diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt index 679da0f4dc7..6517319d7c4 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/CallAndReferenceGenerator.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.fir.backend.generators import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.declarations.* -import org.jetbrains.kotlin.fir.declarations.builder.buildProperty import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression import org.jetbrains.kotlin.fir.psi @@ -94,9 +93,7 @@ class CallAndReferenceGenerator( // Since it's used as a field reference, we need a bogus property as a placeholder. val firSymbol = (callableReferenceAccess.calleeReference as FirResolvedNamedReference).resolvedSymbol as FirFieldSymbol - declarationStorage.getOrCreateIrProperty( - firSymbol.fir.toProperty(), referencedField.parent - ).symbol + declarationStorage.getOrCreateIrPropertyByPureField(firSymbol.fir, referencedField.parent).symbol } IrPropertyReferenceImpl( startOffset, endOffset, type, @@ -147,21 +144,6 @@ class CallAndReferenceGenerator( }.applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression) } - private fun FirField.toProperty(): FirProperty = - buildProperty { - source = this@toProperty.source - session = this@toProperty.session - origin = this@toProperty.origin - returnTypeRef = this@toProperty.returnTypeRef - name = this@toProperty.name - isVar = this@toProperty.isVar - getter = this@toProperty.getter - setter = this@toProperty.setter - symbol = FirPropertySymbol(this@toProperty.symbol.callableId) - isLocal = false - status = this@toProperty.status - } - private fun FirQualifiedAccess.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? { val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null val fir = calleeReference.resolvedSymbol.fir diff --git a/compiler/testData/codegen/box/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt b/compiler/testData/codegen/box/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt index 32e65cd7846..e0a994e63c4 100644 --- a/compiler/testData/codegen/box/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt +++ b/compiler/testData/codegen/box/reflection/properties/noConflictOnKotlinGetterAndJavaField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/boxAgainstJava/reflection/properties/equalsHashCodeToString.kt b/compiler/testData/codegen/boxAgainstJava/reflection/properties/equalsHashCodeToString.kt index f6628586223..d3edbc773f3 100644 --- a/compiler/testData/codegen/boxAgainstJava/reflection/properties/equalsHashCodeToString.kt +++ b/compiler/testData/codegen/boxAgainstJava/reflection/properties/equalsHashCodeToString.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_REFLECT // FILE: test/J.java diff --git a/compiler/testData/ir/irText/firProblems/SameJavaFieldReferences.fir.txt b/compiler/testData/ir/irText/firProblems/SameJavaFieldReferences.fir.txt new file mode 100644 index 00000000000..dc93b505822 --- /dev/null +++ b/compiler/testData/ir/irText/firProblems/SameJavaFieldReferences.fir.txt @@ -0,0 +1,9 @@ +FILE fqName: fileName:/SameJavaFieldReferences.kt + FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit + BLOCK_BODY + VAR name:ref1 type:kotlin.reflect.KProperty0 [val] + PROPERTY_REFERENCE 'public final someJavaField: kotlin.String? [val]' field='FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:someJavaField type:kotlin.String? visibility:public [final,static]' getter=null setter=null type=kotlin.reflect.KProperty0 origin=null + <1>: + VAR name:ref2 type:kotlin.reflect.KProperty0 [val] + PROPERTY_REFERENCE 'public final someJavaField: kotlin.String? [val]' field='FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:someJavaField type:kotlin.String? visibility:public [final,static]' getter=null setter=null type=kotlin.reflect.KProperty0 origin=null + <1>: