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>: