FIR checker: set source for assign call for augmented array set call
The source is set on the alternative block but not the XXXAssign call. BTW, the real source is incorrect shared among the FirAugmentedArraySetCall, FirBlock, so this change uses a fake source for the FirBlock and the FirFunctionCall. Using fake source does not seem to be necessary for compilable code because in that case FirAugmentedArraySetCall is transformed to either a FirBlock or a FirFunctionCall. But it's needed for ambiguous code where such transformation fails. In this case, all three FirElements are present and they should not share the same real source. In addition, this change also sets a fake source for the `get` call of the array access to the left hand side of the operator. For example, `m[a] += 1` where `m` is some custom map implementation that does not return `null` from `get`. The (fake) source of the synthetic `get` call in FIR is now `m[a]`. This is handy because the analysis API will resolve `m[a]` to the `get` call.
This commit is contained in:
committed by
Ilya Kirillov
parent
bc95733818
commit
b2e1dfa6db
+1
@@ -291,6 +291,7 @@ class ExpressionsConverter(
|
||||
if (firOperation in FirOperation.ASSIGNMENTS) {
|
||||
return leftArgNode.generateAssignment(
|
||||
binaryExpression.toFirSourceElement(),
|
||||
leftArgNode?.toFirSourceElement(),
|
||||
rightArg,
|
||||
rightArgAsFir,
|
||||
firOperation,
|
||||
|
||||
@@ -2176,6 +2176,7 @@ open class RawFirBuilder(
|
||||
if (firOperation in FirOperation.ASSIGNMENTS) {
|
||||
return expression.left.generateAssignment(
|
||||
source,
|
||||
expression.left?.toFirSourceElement(),
|
||||
expression.right,
|
||||
rightArgument,
|
||||
firOperation,
|
||||
|
||||
+13
-5
@@ -537,6 +537,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
val assignment = unwrappedArgument.generateAssignment(
|
||||
desugaredSource,
|
||||
null,
|
||||
null,
|
||||
if (prefix && unwrappedArgument.elementType != REFERENCE_EXPRESSION)
|
||||
generateResolvedAccessExpression(source, resultVar)
|
||||
else
|
||||
@@ -889,6 +890,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
|
||||
fun T?.generateAssignment(
|
||||
baseSource: KtSourceElement?,
|
||||
arrayAccessSource: KtSourceElement?,
|
||||
rhs: T?,
|
||||
value: FirExpression, // value is FIR for rhs
|
||||
operation: FirOperation,
|
||||
@@ -909,7 +911,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
(result.annotations as MutableList<FirAnnotation>) += annotations
|
||||
result
|
||||
} else {
|
||||
generateAugmentedArraySetCall(unwrappedLhs, baseSource, operation, rhs, annotations, convert)
|
||||
generateAugmentedArraySetCall(unwrappedLhs, baseSource, arrayAccessSource, operation, rhs, annotations, convert)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -973,6 +975,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
private fun generateAugmentedArraySetCall(
|
||||
unwrappedReceiver: T,
|
||||
baseSource: KtSourceElement?,
|
||||
arrayAccessSource: KtSourceElement?,
|
||||
operation: FirOperation,
|
||||
rhs: T?,
|
||||
annotations: List<FirAnnotation>,
|
||||
@@ -981,14 +984,16 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
return buildAugmentedArraySetCall {
|
||||
source = baseSource
|
||||
this.operation = operation
|
||||
assignCall = generateAugmentedCallForAugmentedArraySetCall(unwrappedReceiver, operation, rhs, convert)
|
||||
setGetBlock = generateSetGetBlockForAugmentedArraySetCall(unwrappedReceiver, baseSource, operation, rhs, convert)
|
||||
assignCall = generateAugmentedCallForAugmentedArraySetCall(unwrappedReceiver, baseSource, operation, rhs, convert)
|
||||
setGetBlock =
|
||||
generateSetGetBlockForAugmentedArraySetCall(unwrappedReceiver, baseSource, arrayAccessSource, operation, rhs, convert)
|
||||
this.annotations += annotations
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAugmentedCallForAugmentedArraySetCall(
|
||||
unwrappedReceiver: T,
|
||||
baseSource: KtSourceElement?,
|
||||
operation: FirOperation,
|
||||
rhs: T?,
|
||||
convert: T.() -> FirExpression
|
||||
@@ -998,6 +1003,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
* a.get(x, y).plusAssign(z)
|
||||
*/
|
||||
return buildFunctionCall {
|
||||
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
name = FirOperationNameConventions.ASSIGNMENTS.getValue(operation)
|
||||
}
|
||||
@@ -1016,6 +1022,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
private fun generateSetGetBlockForAugmentedArraySetCall(
|
||||
unwrappedReceiver: T,
|
||||
baseSource: KtSourceElement?,
|
||||
arrayAccessSource: KtSourceElement?,
|
||||
operation: FirOperation,
|
||||
rhs: T?,
|
||||
convert: T.() -> FirExpression
|
||||
@@ -1037,7 +1044,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
source = null,
|
||||
specialName = "<array>",
|
||||
initializer = baseCall.explicitReceiver ?: buildErrorExpression {
|
||||
source = baseSource
|
||||
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||
diagnostic = ConeSimpleDiagnostic("No receiver for array access", DiagnosticKind.Syntax)
|
||||
}
|
||||
)
|
||||
@@ -1047,7 +1054,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
}
|
||||
statements += indexVariables
|
||||
statements += buildFunctionCall {
|
||||
source = baseSource
|
||||
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||
explicitReceiver = arrayVariable.toQualifiedAccess()
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
name = OperatorNameConventions.SET
|
||||
@@ -1059,6 +1066,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
||||
}
|
||||
|
||||
val getCall = buildFunctionCall {
|
||||
source = arrayAccessSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||
explicitReceiver = arrayVariable.toQualifiedAccess()
|
||||
calleeReference = buildSimpleNamedReference {
|
||||
name = OperatorNameConventions.GET
|
||||
|
||||
Reference in New Issue
Block a user