diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index f0fa3b94d29..3516eb22a4d 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -207,7 +207,7 @@ class Fir2IrConverter( ) } is FirProperty -> { - declarationStorage.getOrCreateProperty( + declarationStorage.getOrCreateIrProperty( declaration, parent, isLocal = isLocal ) } 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 654f91295f0..78ca2aa5801 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 @@ -636,7 +636,7 @@ class Fir2IrDeclarationStorage( } } - internal val FirProperty.fieldVisibility: Visibility + private val FirProperty.fieldVisibility: Visibility get() = when { isLateInit -> setter?.visibility ?: status.visibility isConst -> status.visibility @@ -660,7 +660,7 @@ class Fir2IrDeclarationStorage( return symbolTable.declareProperty(signature, { Fir2IrPropertySymbol(signature, containerSource) }, factory) } - fun getOrCreateProperty( + fun getOrCreateIrProperty( property: FirProperty, irParent: IrDeclarationParent?, isLocal: Boolean = false, 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 ce8c1cb8758..0aff3e65e62 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,6 +8,7 @@ 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 @@ -53,6 +54,11 @@ class CallAndReferenceGenerator( ): IrExpression { val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope) val type = callableReferenceAccess.typeRef.toIrType() + fun propertyOrigin(): IrStatementOrigin? = + when (callableReferenceAccess.source?.psi?.parent) { + is KtPropertyDelegate -> IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE + else -> null + } return callableReferenceAccess.convertWithOffsets { startOffset, endOffset -> when (symbol) { is IrPropertySymbol -> { @@ -62,17 +68,13 @@ class CallAndReferenceGenerator( referencedPropertyGetter != null -> null else -> referencedProperty.backingField?.symbol } - val origin = when (callableReferenceAccess.source?.psi?.parent) { - is KtPropertyDelegate -> IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE - else -> null - } IrPropertyReferenceImpl( startOffset, endOffset, type, symbol, typeArgumentsCount = referencedPropertyGetter?.typeParameters?.size ?: 0, backingFieldSymbol, referencedPropertyGetter?.symbol, referencedProperty.setter?.symbol, - origin + propertyOrigin() ) } is IrLocalDelegatedPropertySymbol -> { @@ -84,6 +86,28 @@ class CallAndReferenceGenerator( IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE ) } + is IrFieldSymbol -> { + val referencedField = symbol.owner + val propertySymbol = referencedField.correspondingPropertySymbol + ?: run { + // In case of [IrField] without the corresponding property, we've created it directly from [FirField]. + // 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 + } + IrPropertyReferenceImpl( + startOffset, endOffset, type, + propertySymbol, + typeArgumentsCount = (type as? IrSimpleType)?.arguments?.size ?: 0, + symbol, + getter = if (referencedField.isStatic) null else propertySymbol.owner.getter?.symbol, + setter = if (referencedField.isStatic) null else propertySymbol.owner.setter?.symbol, + propertyOrigin() + ) + } is IrConstructorSymbol -> { val constructor = symbol.owner val klass = constructor.parent as? IrClass @@ -123,6 +147,21 @@ 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/callableReference/bound/javaField.kt b/compiler/testData/codegen/box/callableReference/bound/javaField.kt index 14234652033..349f5ad8f20 100644 --- a/compiler/testData/codegen/box/callableReference/bound/javaField.kt +++ b/compiler/testData/codegen/box/callableReference/bound/javaField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // FILE: JClass.java public class JClass { diff --git a/compiler/testData/codegen/box/callableReference/javaField.kt b/compiler/testData/codegen/box/callableReference/javaField.kt index 5ed17cf635e..d519f86be55 100644 --- a/compiler/testData/codegen/box/callableReference/javaField.kt +++ b/compiler/testData/codegen/box/callableReference/javaField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME diff --git a/compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt b/compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt index aaba16900ad..11bdb520da2 100644 --- a/compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt +++ b/compiler/testData/codegen/box/reflection/annotations/annotationsOnJavaMembers.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/call/bound/javaInstanceField.kt b/compiler/testData/codegen/box/reflection/call/bound/javaInstanceField.kt index 1e7a749a509..654391f6875 100644 --- a/compiler/testData/codegen/box/reflection/call/bound/javaInstanceField.kt +++ b/compiler/testData/codegen/box/reflection/call/bound/javaInstanceField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/properties/javaPropertyInheritedInKotlin.kt b/compiler/testData/codegen/box/reflection/properties/javaPropertyInheritedInKotlin.kt index 59cd04c4dcb..64a7a3acf06 100644 --- a/compiler/testData/codegen/box/reflection/properties/javaPropertyInheritedInKotlin.kt +++ b/compiler/testData/codegen/box/reflection/properties/javaPropertyInheritedInKotlin.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/box/reflection/properties/javaStaticField.kt b/compiler/testData/codegen/box/reflection/properties/javaStaticField.kt index d0beb3bf74d..22de15590f5 100644 --- a/compiler/testData/codegen/box/reflection/properties/javaStaticField.kt +++ b/compiler/testData/codegen/box/reflection/properties/javaStaticField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // WITH_REFLECT diff --git a/compiler/testData/codegen/box/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt b/compiler/testData/codegen/box/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt index 2fe8bbfd7c8..691c0e8cc69 100644 --- a/compiler/testData/codegen/box/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt +++ b/compiler/testData/codegen/box/reflection/properties/referenceToJavaFieldOfKotlinSubclass.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // TARGET_BACKEND: JVM // FILE: J.java diff --git a/compiler/testData/codegen/boxAgainstJava/callableReference/publicFinalField.kt b/compiler/testData/codegen/boxAgainstJava/callableReference/publicFinalField.kt index 98d123a7ce8..e6eb43158b5 100644 --- a/compiler/testData/codegen/boxAgainstJava/callableReference/publicFinalField.kt +++ b/compiler/testData/codegen/boxAgainstJava/callableReference/publicFinalField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: A.java public class A { diff --git a/compiler/testData/codegen/boxAgainstJava/callableReference/publicMutableField.kt b/compiler/testData/codegen/boxAgainstJava/callableReference/publicMutableField.kt index 2c0b1d7763b..84cbe7f31ec 100644 --- a/compiler/testData/codegen/boxAgainstJava/callableReference/publicMutableField.kt +++ b/compiler/testData/codegen/boxAgainstJava/callableReference/publicMutableField.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: A.java public class A { diff --git a/compiler/testData/codegen/boxAgainstJava/reflection/mapping/javaFields.kt b/compiler/testData/codegen/boxAgainstJava/reflection/mapping/javaFields.kt index 7bb0365fa05..2d85dc1ec3e 100644 --- a/compiler/testData/codegen/boxAgainstJava/reflection/mapping/javaFields.kt +++ b/compiler/testData/codegen/boxAgainstJava/reflection/mapping/javaFields.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_REFLECT // FULL_JDK // FILE: J.java diff --git a/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt index ee0942d426b..108e782182f 100644 --- a/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt +++ b/compiler/testData/codegen/bytecodeText/callableReference/boundFieldReferenceInInline.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: JClass.java public class JClass { diff --git a/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt b/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt index f9a7c52576b..30e77d5baa7 100644 --- a/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt +++ b/compiler/testData/codegen/bytecodeText/callableReference/unboundFieldReferenceInInline.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // FILE: JClass.java public class JClass { diff --git a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt index 4f7acc2c13f..ab06764a079 100644 --- a/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt +++ b/compiler/testData/ir/irText/expressions/propertyReferences.fir.txt @@ -260,7 +260,8 @@ FILE fqName: fileName:/propertyReferences.kt PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty0 visibility:private [final,static] EXPRESSION_BODY - ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.CONST|' type=kotlin.reflect.KProperty0 + PROPERTY_REFERENCE 'public final CONST: kotlin.Int [val]' field='FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:CONST type:kotlin.Int visibility:public [final,static]' getter=null setter=null type=kotlin.reflect.KProperty0 origin=null + <1>: FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty0 correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val] BLOCK_BODY @@ -269,7 +270,8 @@ FILE fqName: fileName:/propertyReferences.kt PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty0 visibility:private [final,static] EXPRESSION_BODY - ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.nonConst|' type=kotlin.reflect.KMutableProperty0 + PROPERTY_REFERENCE 'public open nonConst: kotlin.Int [var]' field='FIELD IR_EXTERNAL_JAVA_DECLARATION_STUB name:nonConst type:kotlin.Int visibility:public [static]' getter=null setter=null type=kotlin.reflect.KMutableProperty0 origin=null + <1>: FUN DEFAULT_PROPERTY_ACCESSOR name: visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty0 correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val] BLOCK_BODY