[FIR2IR] Fix synthetic property reference in delegate expression
This commit is contained in:
@@ -170,13 +170,15 @@ private fun FirBasedSymbol<*>.toSymbolForCall(
|
||||
classifierStorage: Fir2IrClassifierStorage,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
preferGetter: Boolean,
|
||||
explicitReceiver: FirExpression? = null
|
||||
explicitReceiver: FirExpression? = null,
|
||||
isDelegate: Boolean = false
|
||||
) = when (this) {
|
||||
is FirCallableSymbol<*> -> unwrapCallRepresentative().toSymbolForCall(
|
||||
dispatchReceiver,
|
||||
declarationStorage,
|
||||
preferGetter,
|
||||
explicitReceiver
|
||||
explicitReceiver,
|
||||
isDelegate
|
||||
)
|
||||
is FirClassifierSymbol<*> -> toSymbol(session, classifierStorage)
|
||||
else -> error("Unknown symbol: $this")
|
||||
@@ -189,11 +191,12 @@ fun FirReference.toSymbolForCall(
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
conversionScope: Fir2IrConversionScope,
|
||||
preferGetter: Boolean = true,
|
||||
explicitReceiver: FirExpression? = null // Actual only for callable references
|
||||
explicitReceiver: FirExpression? = null, // Actual only for callable references
|
||||
isDelegate: Boolean = false
|
||||
): IrSymbol? {
|
||||
return when (this) {
|
||||
is FirResolvedNamedReference ->
|
||||
resolvedSymbol.toSymbolForCall(dispatchReceiver, session, classifierStorage, declarationStorage, preferGetter, explicitReceiver)
|
||||
resolvedSymbol.toSymbolForCall(dispatchReceiver, session, classifierStorage, declarationStorage, preferGetter, explicitReceiver, isDelegate)
|
||||
is FirErrorNamedReference ->
|
||||
candidateSymbol?.toSymbolForCall(
|
||||
dispatchReceiver,
|
||||
@@ -201,7 +204,8 @@ fun FirReference.toSymbolForCall(
|
||||
classifierStorage,
|
||||
declarationStorage,
|
||||
preferGetter,
|
||||
explicitReceiver
|
||||
explicitReceiver,
|
||||
isDelegate
|
||||
)
|
||||
is FirThisReference -> {
|
||||
when (val boundSymbol = boundSymbol) {
|
||||
@@ -222,7 +226,8 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
|
||||
dispatchReceiver: FirExpression,
|
||||
declarationStorage: Fir2IrDeclarationStorage,
|
||||
preferGetter: Boolean,
|
||||
explicitReceiver: FirExpression? = null
|
||||
explicitReceiver: FirExpression? = null,
|
||||
isDelegate: Boolean = false
|
||||
): IrSymbol? {
|
||||
val dispatchReceiverLookupTag = when (dispatchReceiver) {
|
||||
is FirNoReceiverExpression -> {
|
||||
@@ -242,15 +247,20 @@ private fun FirCallableSymbol<*>.toSymbolForCall(
|
||||
}
|
||||
return when (this) {
|
||||
is FirSimpleSyntheticPropertySymbol -> {
|
||||
(fir as? FirSyntheticProperty)?.let { syntheticProperty ->
|
||||
val delegateSymbol = if (preferGetter) {
|
||||
syntheticProperty.getter.delegate.symbol
|
||||
} else {
|
||||
syntheticProperty.setter?.delegate?.symbol
|
||||
?: throw AssertionError("Written synthetic property must have a setter")
|
||||
}
|
||||
delegateSymbol.unwrapCallRepresentative().toSymbolForCall(dispatchReceiver, declarationStorage, preferGetter)
|
||||
} ?: declarationStorage.getIrPropertySymbol(this)
|
||||
if (isDelegate) {
|
||||
declarationStorage.getIrPropertySymbol(this)
|
||||
} else {
|
||||
(fir as? FirSyntheticProperty)?.let { syntheticProperty ->
|
||||
val delegateSymbol = if (preferGetter) {
|
||||
syntheticProperty.getter.delegate.symbol
|
||||
} else {
|
||||
syntheticProperty.setter?.delegate?.symbol
|
||||
?: throw AssertionError("Written synthetic property must have a setter")
|
||||
}
|
||||
delegateSymbol.unwrapCallRepresentative()
|
||||
.toSymbolForCall(dispatchReceiver, declarationStorage, preferGetter, isDelegate = false)
|
||||
} ?: declarationStorage.getIrPropertySymbol(this)
|
||||
}
|
||||
}
|
||||
is FirFunctionSymbol<*> -> declarationStorage.getIrFunctionSymbol(this, dispatchReceiverLookupTag)
|
||||
is FirPropertySymbol -> declarationStorage.getIrPropertySymbol(this, dispatchReceiverLookupTag)
|
||||
|
||||
@@ -270,7 +270,7 @@ class Fir2IrVisitor(
|
||||
val delegate = variable.delegate
|
||||
if (delegate != null) {
|
||||
val irProperty = declarationStorage.createIrLocalDelegatedProperty(variable, conversionScope.parentFromStack())
|
||||
irProperty.delegate.initializer = convertToIrExpression(delegate)
|
||||
irProperty.delegate.initializer = convertToIrExpression(delegate, isDelegate = true)
|
||||
conversionScope.withFunction(irProperty.getter) {
|
||||
memberGenerator.convertFunctionContent(irProperty.getter, variable.getter, null)
|
||||
}
|
||||
@@ -456,7 +456,8 @@ class Fir2IrVisitor(
|
||||
}
|
||||
}
|
||||
} else if (boundSymbol is FirCallableSymbol) {
|
||||
val receiverSymbol = calleeReference.toSymbolForCall(FirNoReceiverExpression, session, classifierStorage, declarationStorage, conversionScope)
|
||||
val receiverSymbol =
|
||||
calleeReference.toSymbolForCall(FirNoReceiverExpression, session, classifierStorage, declarationStorage, conversionScope)
|
||||
val receiver = (receiverSymbol?.owner as? IrSimpleFunction)?.extensionReceiverParameter
|
||||
if (receiver != null) {
|
||||
return thisReceiverExpression.convertWithOffsets { startOffset, endOffset ->
|
||||
@@ -499,10 +500,18 @@ class Fir2IrVisitor(
|
||||
}
|
||||
|
||||
override fun visitCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, data: Any?): IrElement {
|
||||
return convertCallableReferenceAccess(callableReferenceAccess, false)
|
||||
}
|
||||
|
||||
private fun convertCallableReferenceAccess(callableReferenceAccess: FirCallableReferenceAccess, isDelegate: Boolean): IrElement {
|
||||
val explicitReceiverExpression = convertToIrReceiverExpression(
|
||||
callableReferenceAccess.explicitReceiver, callableReferenceAccess.calleeReference, callableReferenceAccess
|
||||
)
|
||||
return callGenerator.convertToIrCallableReference(callableReferenceAccess, explicitReceiverExpression)
|
||||
return callGenerator.convertToIrCallableReference(
|
||||
callableReferenceAccess,
|
||||
explicitReceiverExpression,
|
||||
isDelegate = isDelegate
|
||||
)
|
||||
}
|
||||
|
||||
override fun visitVariableAssignment(variableAssignment: FirVariableAssignment, data: Any?): IrElement {
|
||||
@@ -525,7 +534,11 @@ class Fir2IrVisitor(
|
||||
return accept(this@Fir2IrVisitor, null) as IrStatement
|
||||
}
|
||||
|
||||
internal fun convertToIrExpression(expression: FirExpression, annotationMode: Boolean = false): IrExpression {
|
||||
internal fun convertToIrExpression(
|
||||
expression: FirExpression,
|
||||
annotationMode: Boolean = false,
|
||||
isDelegate: Boolean = false
|
||||
): IrExpression {
|
||||
return when (expression) {
|
||||
is FirBlock -> expression.convertToIrExpressionOrBlock(
|
||||
if (expression.source?.kind == KtFakeSourceElementKind.DesugaredForLoop) IrStatementOrigin.FOR_LOOP else null
|
||||
@@ -541,10 +554,14 @@ class Fir2IrVisitor(
|
||||
when (unwrappedExpression) {
|
||||
is FirFunctionCall -> convertToIrCall(unwrappedExpression, annotationMode)
|
||||
is FirArrayOfCall -> convertToArrayOfCall(unwrappedExpression, annotationMode)
|
||||
is FirCallableReferenceAccess -> convertCallableReferenceAccess(unwrappedExpression, isDelegate)
|
||||
else -> expression.accept(this, null) as IrExpression
|
||||
}
|
||||
} else {
|
||||
expression.accept(this, null) as IrExpression
|
||||
when (unwrappedExpression) {
|
||||
is FirCallableReferenceAccess -> convertCallableReferenceAccess(unwrappedExpression, isDelegate)
|
||||
else -> expression.accept(this, null) as IrExpression
|
||||
}
|
||||
}
|
||||
}
|
||||
}.let {
|
||||
|
||||
+3
-2
@@ -61,7 +61,8 @@ class CallAndReferenceGenerator(
|
||||
|
||||
fun convertToIrCallableReference(
|
||||
callableReferenceAccess: FirCallableReferenceAccess,
|
||||
explicitReceiverExpression: IrExpression?
|
||||
explicitReceiverExpression: IrExpression?,
|
||||
isDelegate: Boolean
|
||||
): IrExpression {
|
||||
val type = approximateFunctionReferenceType(callableReferenceAccess.typeRef.coneType).toIrType()
|
||||
|
||||
@@ -79,7 +80,7 @@ class CallAndReferenceGenerator(
|
||||
|
||||
val symbol = callableReferenceAccess.calleeReference.toSymbolForCall(
|
||||
callableReferenceAccess.dispatchReceiver, session, classifierStorage, declarationStorage, conversionScope,
|
||||
explicitReceiver = callableReferenceAccess.explicitReceiver
|
||||
explicitReceiver = callableReferenceAccess.explicitReceiver, isDelegate = isDelegate
|
||||
)
|
||||
// val x by y ->
|
||||
// val `x$delegate` = y
|
||||
|
||||
+1
-1
@@ -217,7 +217,7 @@ internal class ClassMemberGenerator(
|
||||
if (initializer == null && initializerExpression != null) {
|
||||
initializer = irFactory.createExpressionBody(
|
||||
run {
|
||||
val irExpression = visitor.convertToIrExpression(initializerExpression)
|
||||
val irExpression = visitor.convertToIrExpression(initializerExpression, isDelegate = property.delegate != null)
|
||||
if (property.delegate == null) {
|
||||
with(visitor.implicitCastInserter) {
|
||||
irExpression.cast(initializerExpression, initializerExpression.typeRef, property.returnTypeRef)
|
||||
|
||||
+1
-3
@@ -1,6 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FIR status: REPEATED_ANNOTATION at val y9; fir2ir produces an IrFunctionReference of type KProperty0 instead of an IrPropertyReference
|
||||
// WITH_REFLECT
|
||||
// WITH_STDLIB
|
||||
// FILE: J.java
|
||||
@@ -34,6 +32,6 @@ fun box(): String {
|
||||
val y6 by @Anno() (((j2)::value))
|
||||
val y7 by (@Anno() ((j2)::value))
|
||||
val y8 by ((@Anno() (j2)::value))
|
||||
val y9 by @Anno() ((@Anno() (j2)::value))
|
||||
val y9 by @Anno() (j2)::value
|
||||
return x + y
|
||||
}
|
||||
|
||||
@@ -1,8 +1,4 @@
|
||||
// TARGET_BACKEND: JVM
|
||||
// IGNORE_BACKEND_FIR: JVM_IR
|
||||
// FIR status: V
|
||||
// Caused by: java.lang.AssertionError: Unexpected IR element found during code generation. Either code generation for it is not implemented, or it should have been lowered:
|
||||
// FUNCTION_REFERENCE 'public open fun getFoo (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null reflectionTarget=<same>
|
||||
// WITH_STDLIB
|
||||
|
||||
// MODULE: jjj
|
||||
|
||||
+2
-2
@@ -2,7 +2,7 @@ FILE fqName:k fileName:/box.kt
|
||||
PROPERTY name:p1 visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_DELEGATE name:p1$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
FUNCTION_REFERENCE 'public open fun getFoo (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null reflectionTarget=<same>
|
||||
PROPERTY_REFERENCE 'public open foo: @[FlexibleNullability] kotlin.String? [var]' field=null getter='public open fun <get-foo> (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun <set-foo> (<set-?>: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null
|
||||
$this: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J' type=<root>.J origin=null
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p1> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
|
||||
correspondingProperty: PROPERTY name:p1 visibility:public modality:FINAL [delegated,var]
|
||||
@@ -26,7 +26,7 @@ FILE fqName:k fileName:/box.kt
|
||||
PROPERTY name:p2 visibility:public modality:FINAL [delegated,var]
|
||||
FIELD PROPERTY_DELEGATE name:p2$delegate type:kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> visibility:private [final,static]
|
||||
EXPRESSION_BODY
|
||||
FUNCTION_REFERENCE 'public open fun getFoo (): @[FlexibleNullability] kotlin.String? declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null reflectionTarget=<same>
|
||||
PROPERTY_REFERENCE 'public open foo: @[FlexibleNullability] kotlin.String? [var]' field=null getter='public open fun <get-foo> (): @[FlexibleNullability] kotlin.String? declared in <root>.J' setter='public open fun <set-foo> (<set-?>: @[FlexibleNullability] kotlin.String?): kotlin.Unit declared in <root>.J' type=kotlin.reflect.KMutableProperty0<@[FlexibleNullability] kotlin.String?> origin=null
|
||||
$this: CONSTRUCTOR_CALL 'public constructor <init> () [primary] declared in <root>.J' type=<root>.J origin=null
|
||||
FUN DELEGATED_PROPERTY_ACCESSOR name:<get-p2> visibility:public modality:FINAL <> () returnType:@[FlexibleNullability] kotlin.String?
|
||||
correspondingProperty: PROPERTY name:p2 visibility:public modality:FINAL [delegated,var]
|
||||
|
||||
Reference in New Issue
Block a user