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:
Kirill Rakhman
2023-01-16 09:54:31 +01:00
committed by Space Team
parent e9b8d6db80
commit ace47c06a5
128 changed files with 950 additions and 935 deletions
@@ -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) {
@@ -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(
@@ -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
@@ -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
@@ -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 =