FIR2IR: add support for callable reference to Java field
#KT-42656 Fixed
This commit is contained in:
committed by
Mikhail Glukhikh
parent
65545a10c4
commit
5f64d6ec76
@@ -207,7 +207,7 @@ class Fir2IrConverter(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
is FirProperty -> {
|
is FirProperty -> {
|
||||||
declarationStorage.getOrCreateProperty(
|
declarationStorage.getOrCreateIrProperty(
|
||||||
declaration, parent, isLocal = isLocal
|
declaration, parent, isLocal = isLocal
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -636,7 +636,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val FirProperty.fieldVisibility: Visibility
|
private val FirProperty.fieldVisibility: Visibility
|
||||||
get() = when {
|
get() = when {
|
||||||
isLateInit -> setter?.visibility ?: status.visibility
|
isLateInit -> setter?.visibility ?: status.visibility
|
||||||
isConst -> status.visibility
|
isConst -> status.visibility
|
||||||
@@ -660,7 +660,7 @@ class Fir2IrDeclarationStorage(
|
|||||||
return symbolTable.declareProperty(signature, { Fir2IrPropertySymbol(signature, containerSource) }, factory)
|
return symbolTable.declareProperty(signature, { Fir2IrPropertySymbol(signature, containerSource) }, factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getOrCreateProperty(
|
fun getOrCreateIrProperty(
|
||||||
property: FirProperty,
|
property: FirProperty,
|
||||||
irParent: IrDeclarationParent?,
|
irParent: IrDeclarationParent?,
|
||||||
isLocal: Boolean = false,
|
isLocal: Boolean = false,
|
||||||
|
|||||||
+44
-5
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.fir.backend.generators
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
import org.jetbrains.kotlin.fir.backend.*
|
import org.jetbrains.kotlin.fir.backend.*
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
import org.jetbrains.kotlin.fir.expressions.impl.FirNoReceiverExpression
|
||||||
import org.jetbrains.kotlin.fir.psi
|
import org.jetbrains.kotlin.fir.psi
|
||||||
@@ -53,6 +54,11 @@ class CallAndReferenceGenerator(
|
|||||||
): IrExpression {
|
): IrExpression {
|
||||||
val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope)
|
val symbol = callableReferenceAccess.calleeReference.toSymbol(session, classifierStorage, declarationStorage, conversionScope)
|
||||||
val type = callableReferenceAccess.typeRef.toIrType()
|
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 ->
|
return callableReferenceAccess.convertWithOffsets { startOffset, endOffset ->
|
||||||
when (symbol) {
|
when (symbol) {
|
||||||
is IrPropertySymbol -> {
|
is IrPropertySymbol -> {
|
||||||
@@ -62,17 +68,13 @@ class CallAndReferenceGenerator(
|
|||||||
referencedPropertyGetter != null -> null
|
referencedPropertyGetter != null -> null
|
||||||
else -> referencedProperty.backingField?.symbol
|
else -> referencedProperty.backingField?.symbol
|
||||||
}
|
}
|
||||||
val origin = when (callableReferenceAccess.source?.psi?.parent) {
|
|
||||||
is KtPropertyDelegate -> IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
IrPropertyReferenceImpl(
|
IrPropertyReferenceImpl(
|
||||||
startOffset, endOffset, type, symbol,
|
startOffset, endOffset, type, symbol,
|
||||||
typeArgumentsCount = referencedPropertyGetter?.typeParameters?.size ?: 0,
|
typeArgumentsCount = referencedPropertyGetter?.typeParameters?.size ?: 0,
|
||||||
backingFieldSymbol,
|
backingFieldSymbol,
|
||||||
referencedPropertyGetter?.symbol,
|
referencedPropertyGetter?.symbol,
|
||||||
referencedProperty.setter?.symbol,
|
referencedProperty.setter?.symbol,
|
||||||
origin
|
propertyOrigin()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
is IrLocalDelegatedPropertySymbol -> {
|
is IrLocalDelegatedPropertySymbol -> {
|
||||||
@@ -84,6 +86,28 @@ class CallAndReferenceGenerator(
|
|||||||
IrStatementOrigin.PROPERTY_REFERENCE_FOR_DELEGATE
|
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 -> {
|
is IrConstructorSymbol -> {
|
||||||
val constructor = symbol.owner
|
val constructor = symbol.owner
|
||||||
val klass = constructor.parent as? IrClass
|
val klass = constructor.parent as? IrClass
|
||||||
@@ -123,6 +147,21 @@ class CallAndReferenceGenerator(
|
|||||||
}.applyTypeArguments(callableReferenceAccess).applyReceivers(callableReferenceAccess, explicitReceiverExpression)
|
}.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? {
|
private fun FirQualifiedAccess.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? {
|
||||||
val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null
|
val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||||
val fir = calleeReference.resolvedSymbol.fir
|
val fir = calleeReference.resolvedSymbol.fir
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// FILE: JClass.java
|
// FILE: JClass.java
|
||||||
public class JClass {
|
public class JClass {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
// WITH_RUNTIME
|
// WITH_RUNTIME
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// TARGET_BACKEND: JVM
|
// TARGET_BACKEND: JVM
|
||||||
|
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
public class A {
|
public class A {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FILE: A.java
|
// FILE: A.java
|
||||||
|
|
||||||
public class A {
|
public class A {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// WITH_REFLECT
|
// WITH_REFLECT
|
||||||
// FULL_JDK
|
// FULL_JDK
|
||||||
// FILE: J.java
|
// FILE: J.java
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FILE: JClass.java
|
// FILE: JClass.java
|
||||||
|
|
||||||
public class JClass {
|
public class JClass {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND_FIR: JVM_IR
|
|
||||||
// FILE: JClass.java
|
// FILE: JClass.java
|
||||||
|
|
||||||
public class JClass {
|
public class JClass {
|
||||||
|
|||||||
@@ -260,7 +260,8 @@ FILE fqName:<root> fileName:/propertyReferences.kt
|
|||||||
PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
|
PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
|
||||||
FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty0<kotlin.Int> visibility:private [final,static]
|
FIELD PROPERTY_BACKING_FIELD name:test_J_CONST type:kotlin.reflect.KProperty0<kotlin.Int> visibility:private [final,static]
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.CONST|' type=kotlin.reflect.KProperty0<kotlin.Int>
|
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<kotlin.Int> origin=null
|
||||||
|
<1>: <none>
|
||||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_CONST> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty0<kotlin.Int>
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_CONST> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KProperty0<kotlin.Int>
|
||||||
correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
|
correspondingProperty: PROPERTY name:test_J_CONST visibility:public modality:FINAL [val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
@@ -269,7 +270,8 @@ FILE fqName:<root> fileName:/propertyReferences.kt
|
|||||||
PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
|
PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
|
||||||
FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty0<kotlin.Int> visibility:private [final,static]
|
FIELD PROPERTY_BACKING_FIELD name:test_J_nonConst type:kotlin.reflect.KMutableProperty0<kotlin.Int> visibility:private [final,static]
|
||||||
EXPRESSION_BODY
|
EXPRESSION_BODY
|
||||||
ERROR_CALL 'Unsupported callable reference: Q|J|::R|/J.nonConst|' type=kotlin.reflect.KMutableProperty0<kotlin.Int>
|
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<kotlin.Int> origin=null
|
||||||
|
<1>: <none>
|
||||||
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_nonConst> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty0<kotlin.Int>
|
FUN DEFAULT_PROPERTY_ACCESSOR name:<get-test_J_nonConst> visibility:public modality:FINAL <> () returnType:kotlin.reflect.KMutableProperty0<kotlin.Int>
|
||||||
correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
|
correspondingProperty: PROPERTY name:test_J_nonConst visibility:public modality:FINAL [val]
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
|
|||||||
Reference in New Issue
Block a user