[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.
This commit is contained in:
@@ -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<FirAnonymousInitializer, IrAnonymousInitializer>()
|
||||
|
||||
private val propertyCache = mutableMapOf<FirProperty, IrProperty>()
|
||||
|
||||
// For pure fields (from Java) only
|
||||
private val fieldToPropertyCache = mutableMapOf<FirField, IrProperty>()
|
||||
|
||||
private val delegatedReverseCache = mutableMapOf<IrDeclaration, FirDeclaration>()
|
||||
|
||||
private val fieldCache = mutableMapOf<FirField, IrField>()
|
||||
@@ -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?,
|
||||
|
||||
+1
-19
@@ -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
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// TARGET_BACKEND: JVM
|
||||
|
||||
// WITH_REFLECT
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// WITH_REFLECT
|
||||
// FILE: test/J.java
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
FILE fqName:<root> fileName:/SameJavaFieldReferences.kt
|
||||
FUN name:foo visibility:public modality:FINAL <> () returnType:kotlin.Unit
|
||||
BLOCK_BODY
|
||||
VAR name:ref1 type:kotlin.reflect.KProperty0<kotlin.String?> [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<kotlin.String?> origin=null
|
||||
<1>: <none>
|
||||
VAR name:ref2 type:kotlin.reflect.KProperty0<kotlin.String?> [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<kotlin.String?> origin=null
|
||||
<1>: <none>
|
||||
Reference in New Issue
Block a user