FIR: Make LHS of FirVariableAssignment a FirExpression
This way references can even be resolved for erroneous assignments (e.g. function call, if expression, ... on LHS) ^KT-54648 Fixed
This commit is contained in:
committed by
Space Team
parent
e9b8d6db80
commit
ace47c06a5
@@ -78,7 +78,14 @@ internal fun <T : IrElement> KtSourceElement?.convertWithOffsets(
|
||||
return f(startOffset, endOffset)
|
||||
}
|
||||
|
||||
internal fun <T : IrElement> FirQualifiedAccess.convertWithOffsets(
|
||||
internal fun <T : IrElement> FirQualifiedAccessExpression.convertWithOffsets(
|
||||
f: (startOffset: Int, endOffset: Int) -> T
|
||||
): T {
|
||||
return convertWithOffsets(this.calleeReference, f)
|
||||
}
|
||||
|
||||
internal fun <T : IrElement> FirStatement.convertWithOffsets(
|
||||
calleeReference: FirReference,
|
||||
f: (startOffset: Int, endOffset: Int) -> T
|
||||
): T {
|
||||
val psi = calleeReference.psi
|
||||
@@ -718,7 +725,7 @@ fun FirDeclaration?.computeIrOrigin(predefinedOrigin: IrDeclarationOrigin? = nul
|
||||
}
|
||||
|
||||
fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
||||
val calleeReferenceSymbol = calleeReference.toResolvedCallableSymbol() ?: return IrStatementOrigin.EQ
|
||||
val calleeReferenceSymbol = calleeReference?.toResolvedCallableSymbol() ?: return IrStatementOrigin.EQ
|
||||
val rValue = rValue
|
||||
if (rValue is FirFunctionCall && calleeReferenceSymbol.callableId.isLocal) {
|
||||
val callableId = rValue.calleeReference.toResolvedCallableSymbol()?.callableId
|
||||
@@ -736,9 +743,8 @@ fun FirVariableAssignment.getIrAssignmentOrigin(): IrStatementOrigin {
|
||||
IrStatementOrigin.POSTFIX_DECR
|
||||
}
|
||||
|
||||
if (calleeReference.source?.kind is KtFakeSourceElementKind &&
|
||||
calleeReferenceSymbol == rValue.explicitReceiver?.toResolvedCallableSymbol()
|
||||
) {
|
||||
val kind = rValue.source?.kind
|
||||
if (kind == KtFakeSourceElementKind.DesugaredIncrementOrDecrement || kind == KtFakeSourceElementKind.DesugaredCompoundAssignment) {
|
||||
if (callableName == OperatorNameConventions.PLUS) {
|
||||
return IrStatementOrigin.PLUSEQ
|
||||
} else if (callableName == OperatorNameConventions.MINUS) {
|
||||
|
||||
+1
-1
@@ -913,7 +913,7 @@ class Fir2IrDeclarationStorage(
|
||||
val setter = property.setter
|
||||
if (delegate != null || property.hasBackingField) {
|
||||
backingField = if (delegate != null) {
|
||||
((delegate as? FirQualifiedAccess)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let {
|
||||
((delegate as? FirQualifiedAccessExpression)?.calleeReference?.toResolvedBaseSymbol()?.fir as? FirTypeParameterRefsOwner)?.let {
|
||||
classifierStorage.preCacheTypeParameters(it, symbol)
|
||||
}
|
||||
createBackingField(
|
||||
|
||||
+2
-2
@@ -274,10 +274,10 @@ class Fir2IrImplicitCastInserter(
|
||||
internal fun implicitCastFromDispatchReceiver(
|
||||
original: IrExpression,
|
||||
originalTypeRef: FirTypeRef,
|
||||
calleeReference: FirReference,
|
||||
calleeReference: FirReference?,
|
||||
conversionTypeContext: ConversionTypeContext,
|
||||
): IrExpression {
|
||||
val referencedDeclaration = calleeReference.toResolvedCallableSymbol()?.unwrapCallRepresentative()?.fir
|
||||
val referencedDeclaration = calleeReference?.toResolvedCallableSymbol()?.unwrapCallRepresentative()?.fir
|
||||
|
||||
val dispatchReceiverType =
|
||||
referencedDeclaration?.dispatchReceiverType as? ConeClassLikeType
|
||||
|
||||
@@ -704,7 +704,7 @@ class Fir2IrVisitor(
|
||||
|
||||
internal fun convertToIrReceiverExpression(
|
||||
expression: FirExpression?,
|
||||
calleeReference: FirReference,
|
||||
calleeReference: FirReference?,
|
||||
callableReferenceAccess: FirCallableReferenceAccess? = null
|
||||
): IrExpression? {
|
||||
return when (expression) {
|
||||
@@ -779,7 +779,7 @@ class Fir2IrVisitor(
|
||||
val incrementStatement = this[index + 1]
|
||||
if (incrementStatement !is FirVariableAssignment) return null
|
||||
|
||||
if (incrementStatement.lValue.toResolvedCallableSymbol() != variable) return null
|
||||
if (incrementStatement.calleeReference?.toResolvedCallableSymbol() != variable) return null
|
||||
|
||||
val origin = incrementStatement.getIrAssignmentOrigin()
|
||||
return if (origin == IrStatementOrigin.EQ) null else origin
|
||||
|
||||
+4
-1
@@ -180,7 +180,10 @@ internal class AdapterGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirQualifiedAccess.findBoundReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
||||
private fun FirCallableReferenceAccess.findBoundReceiver(
|
||||
explicitReceiverExpression: IrExpression?,
|
||||
isDispatch: Boolean
|
||||
): IrExpression? {
|
||||
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
||||
if (firReceiver is FirNoReceiverExpression) {
|
||||
return null
|
||||
|
||||
+20
-17
@@ -213,7 +213,7 @@ class CallAndReferenceGenerator(
|
||||
return newType.toTypeProjection(typeProjection.kind)
|
||||
}
|
||||
|
||||
private fun FirQualifiedAccess.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? {
|
||||
private fun FirQualifiedAccessExpression.tryConvertToSamConstructorCall(type: IrType): IrTypeOperatorCall? {
|
||||
val calleeReference = calleeReference as? FirResolvedNamedReference ?: return null
|
||||
val fir = calleeReference.resolvedSymbol.fir
|
||||
if (this is FirFunctionCall && fir is FirSimpleFunction && fir.origin == FirDeclarationOrigin.SamConstructor) {
|
||||
@@ -227,7 +227,7 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
|
||||
private fun FirExpression.superQualifierSymbol(): IrClassSymbol? {
|
||||
if (this !is FirQualifiedAccess) {
|
||||
if (this !is FirQualifiedAccessExpression) {
|
||||
return null
|
||||
}
|
||||
val dispatchReceiverReference = calleeReference
|
||||
@@ -264,7 +264,7 @@ class CallAndReferenceGenerator(
|
||||
else -> null
|
||||
}
|
||||
|
||||
private val FirQualifiedAccess.dynamicOperator
|
||||
private val FirQualifiedAccessExpression.dynamicOperator
|
||||
get() = when (calleeReference.source?.kind) {
|
||||
is KtFakeSourceElementKind.ArrayAccessNameReference -> when (calleeReference.resolved?.name) {
|
||||
OperatorNameConventions.SET -> IrDynamicOperator.EQ
|
||||
@@ -288,7 +288,7 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
|
||||
private fun convertToIrCallForDynamic(
|
||||
qualifiedAccess: FirQualifiedAccess,
|
||||
qualifiedAccess: FirQualifiedAccessExpression,
|
||||
explicitReceiverExpression: IrExpression,
|
||||
type: IrType,
|
||||
calleeReference: FirReference,
|
||||
@@ -333,7 +333,7 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
|
||||
fun convertToIrCall(
|
||||
qualifiedAccess: FirQualifiedAccess,
|
||||
qualifiedAccess: FirQualifiedAccessExpression,
|
||||
typeRef: FirTypeRef,
|
||||
explicitReceiverExpression: IrExpression?,
|
||||
annotationMode: Boolean = false,
|
||||
@@ -501,13 +501,15 @@ class CallAndReferenceGenerator(
|
||||
|
||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||
}
|
||||
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, convertedExplicitReceiver)
|
||||
}.apply {
|
||||
variableAssignment.unwrapLValue()?.let { applyReceivers(it, convertedExplicitReceiver) }
|
||||
}
|
||||
}
|
||||
|
||||
fun convertToIrSetCall(variableAssignment: FirVariableAssignment, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||
try {
|
||||
val type = irBuiltIns.unitType
|
||||
val calleeReference = variableAssignment.calleeReference
|
||||
val calleeReference = variableAssignment.calleeReference ?: error("Reference not resolvable")
|
||||
val assignedValue = visitor.convertToIrExpression(variableAssignment.rValue)
|
||||
|
||||
val firSymbol = calleeReference.toResolvedBaseSymbol()
|
||||
@@ -532,7 +534,8 @@ class CallAndReferenceGenerator(
|
||||
)
|
||||
val origin = variableAssignment.getIrAssignmentOrigin()
|
||||
|
||||
return variableAssignment.convertWithOffsets { startOffset, endOffset ->
|
||||
val lValue = variableAssignment.unwrapLValue() ?: error("Assignment lValue unwrapped to null")
|
||||
return variableAssignment.convertWithOffsets(calleeReference) { startOffset, endOffset ->
|
||||
when (symbol) {
|
||||
is IrFieldSymbol -> IrSetFieldImpl(startOffset, endOffset, symbol, type, origin).apply {
|
||||
value = assignedValue
|
||||
@@ -548,7 +551,7 @@ class CallAndReferenceGenerator(
|
||||
origin = origin,
|
||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||
).apply {
|
||||
putContextReceiverArguments(variableAssignment)
|
||||
putContextReceiverArguments(lValue)
|
||||
putValueArgument(0, assignedValue)
|
||||
}
|
||||
|
||||
@@ -568,7 +571,7 @@ class CallAndReferenceGenerator(
|
||||
origin = origin,
|
||||
superQualifierSymbol = variableAssignment.dispatchReceiver.superQualifierSymbol()
|
||||
).apply {
|
||||
putValueArgument(putContextReceiverArguments(variableAssignment), assignedValue)
|
||||
putValueArgument(putContextReceiverArguments(lValue), assignedValue)
|
||||
}
|
||||
|
||||
backingField != null -> IrSetFieldImpl(
|
||||
@@ -600,7 +603,7 @@ class CallAndReferenceGenerator(
|
||||
|
||||
else -> generateErrorCallExpression(startOffset, endOffset, calleeReference)
|
||||
}
|
||||
}.applyTypeArguments(variableAssignment).applyReceivers(variableAssignment, explicitReceiverExpression)
|
||||
}.applyTypeArguments(lValue).applyReceivers(lValue, explicitReceiverExpression)
|
||||
} catch (e: Throwable) {
|
||||
throw IllegalStateException(
|
||||
"Error while translating ${variableAssignment.render()} " +
|
||||
@@ -957,7 +960,7 @@ class CallAndReferenceGenerator(
|
||||
return this
|
||||
}
|
||||
|
||||
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccess): IrExpression {
|
||||
internal fun IrExpression.applyTypeArguments(access: FirQualifiedAccessExpression): IrExpression {
|
||||
if (this !is IrMemberAccessExpression<*>) return this
|
||||
val argumentsCount = access.typeArguments.size
|
||||
if (argumentsCount <= typeArgumentsCount) {
|
||||
@@ -986,16 +989,16 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun FirQualifiedAccess.findTypeParameter(index: Int): FirTypeParameter? =
|
||||
private fun FirQualifiedAccessExpression.findTypeParameter(index: Int): FirTypeParameter? =
|
||||
((calleeReference as? FirResolvedNamedReference)?.resolvedSymbol?.fir as? FirTypeParametersOwner)?.typeParameters?.get(index)
|
||||
|
||||
private fun FirQualifiedAccess.findIrDispatchReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||
private fun FirQualifiedAccessExpression.findIrDispatchReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||
findIrReceiver(explicitReceiverExpression, isDispatch = true)
|
||||
|
||||
private fun FirQualifiedAccess.findIrExtensionReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||
private fun FirQualifiedAccessExpression.findIrExtensionReceiver(explicitReceiverExpression: IrExpression?): IrExpression? =
|
||||
findIrReceiver(explicitReceiverExpression, isDispatch = false)
|
||||
|
||||
internal fun FirQualifiedAccess.findIrReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
||||
internal fun FirQualifiedAccessExpression.findIrReceiver(explicitReceiverExpression: IrExpression?, isDispatch: Boolean): IrExpression? {
|
||||
val firReceiver = if (isDispatch) dispatchReceiver else extensionReceiver
|
||||
if (firReceiver == explicitReceiver) {
|
||||
return explicitReceiverExpression
|
||||
@@ -1011,7 +1014,7 @@ class CallAndReferenceGenerator(
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrExpression.applyReceivers(qualifiedAccess: FirQualifiedAccess, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||
private fun IrExpression.applyReceivers(qualifiedAccess: FirQualifiedAccessExpression, explicitReceiverExpression: IrExpression?): IrExpression {
|
||||
when (this) {
|
||||
is IrMemberAccessExpression<*> -> {
|
||||
val ownerFunction =
|
||||
|
||||
Reference in New Issue
Block a user