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) {
|
if (firOperation in FirOperation.ASSIGNMENTS) {
|
||||||
return leftArgNode.generateAssignment(
|
return leftArgNode.generateAssignment(
|
||||||
binaryExpression.toFirSourceElement(),
|
binaryExpression.toFirSourceElement(),
|
||||||
|
leftArgNode?.toFirSourceElement(),
|
||||||
rightArg,
|
rightArg,
|
||||||
rightArgAsFir,
|
rightArgAsFir,
|
||||||
firOperation,
|
firOperation,
|
||||||
|
|||||||
@@ -2176,6 +2176,7 @@ open class RawFirBuilder(
|
|||||||
if (firOperation in FirOperation.ASSIGNMENTS) {
|
if (firOperation in FirOperation.ASSIGNMENTS) {
|
||||||
return expression.left.generateAssignment(
|
return expression.left.generateAssignment(
|
||||||
source,
|
source,
|
||||||
|
expression.left?.toFirSourceElement(),
|
||||||
expression.right,
|
expression.right,
|
||||||
rightArgument,
|
rightArgument,
|
||||||
firOperation,
|
firOperation,
|
||||||
|
|||||||
+13
-5
@@ -537,6 +537,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
val assignment = unwrappedArgument.generateAssignment(
|
val assignment = unwrappedArgument.generateAssignment(
|
||||||
desugaredSource,
|
desugaredSource,
|
||||||
null,
|
null,
|
||||||
|
null,
|
||||||
if (prefix && unwrappedArgument.elementType != REFERENCE_EXPRESSION)
|
if (prefix && unwrappedArgument.elementType != REFERENCE_EXPRESSION)
|
||||||
generateResolvedAccessExpression(source, resultVar)
|
generateResolvedAccessExpression(source, resultVar)
|
||||||
else
|
else
|
||||||
@@ -889,6 +890,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
|
|
||||||
fun T?.generateAssignment(
|
fun T?.generateAssignment(
|
||||||
baseSource: KtSourceElement?,
|
baseSource: KtSourceElement?,
|
||||||
|
arrayAccessSource: KtSourceElement?,
|
||||||
rhs: T?,
|
rhs: T?,
|
||||||
value: FirExpression, // value is FIR for rhs
|
value: FirExpression, // value is FIR for rhs
|
||||||
operation: FirOperation,
|
operation: FirOperation,
|
||||||
@@ -909,7 +911,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
(result.annotations as MutableList<FirAnnotation>) += annotations
|
(result.annotations as MutableList<FirAnnotation>) += annotations
|
||||||
result
|
result
|
||||||
} else {
|
} 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(
|
private fun generateAugmentedArraySetCall(
|
||||||
unwrappedReceiver: T,
|
unwrappedReceiver: T,
|
||||||
baseSource: KtSourceElement?,
|
baseSource: KtSourceElement?,
|
||||||
|
arrayAccessSource: KtSourceElement?,
|
||||||
operation: FirOperation,
|
operation: FirOperation,
|
||||||
rhs: T?,
|
rhs: T?,
|
||||||
annotations: List<FirAnnotation>,
|
annotations: List<FirAnnotation>,
|
||||||
@@ -981,14 +984,16 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
return buildAugmentedArraySetCall {
|
return buildAugmentedArraySetCall {
|
||||||
source = baseSource
|
source = baseSource
|
||||||
this.operation = operation
|
this.operation = operation
|
||||||
assignCall = generateAugmentedCallForAugmentedArraySetCall(unwrappedReceiver, operation, rhs, convert)
|
assignCall = generateAugmentedCallForAugmentedArraySetCall(unwrappedReceiver, baseSource, operation, rhs, convert)
|
||||||
setGetBlock = generateSetGetBlockForAugmentedArraySetCall(unwrappedReceiver, baseSource, operation, rhs, convert)
|
setGetBlock =
|
||||||
|
generateSetGetBlockForAugmentedArraySetCall(unwrappedReceiver, baseSource, arrayAccessSource, operation, rhs, convert)
|
||||||
this.annotations += annotations
|
this.annotations += annotations
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateAugmentedCallForAugmentedArraySetCall(
|
private fun generateAugmentedCallForAugmentedArraySetCall(
|
||||||
unwrappedReceiver: T,
|
unwrappedReceiver: T,
|
||||||
|
baseSource: KtSourceElement?,
|
||||||
operation: FirOperation,
|
operation: FirOperation,
|
||||||
rhs: T?,
|
rhs: T?,
|
||||||
convert: T.() -> FirExpression
|
convert: T.() -> FirExpression
|
||||||
@@ -998,6 +1003,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
* a.get(x, y).plusAssign(z)
|
* a.get(x, y).plusAssign(z)
|
||||||
*/
|
*/
|
||||||
return buildFunctionCall {
|
return buildFunctionCall {
|
||||||
|
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||||
calleeReference = buildSimpleNamedReference {
|
calleeReference = buildSimpleNamedReference {
|
||||||
name = FirOperationNameConventions.ASSIGNMENTS.getValue(operation)
|
name = FirOperationNameConventions.ASSIGNMENTS.getValue(operation)
|
||||||
}
|
}
|
||||||
@@ -1016,6 +1022,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
private fun generateSetGetBlockForAugmentedArraySetCall(
|
private fun generateSetGetBlockForAugmentedArraySetCall(
|
||||||
unwrappedReceiver: T,
|
unwrappedReceiver: T,
|
||||||
baseSource: KtSourceElement?,
|
baseSource: KtSourceElement?,
|
||||||
|
arrayAccessSource: KtSourceElement?,
|
||||||
operation: FirOperation,
|
operation: FirOperation,
|
||||||
rhs: T?,
|
rhs: T?,
|
||||||
convert: T.() -> FirExpression
|
convert: T.() -> FirExpression
|
||||||
@@ -1037,7 +1044,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
source = null,
|
source = null,
|
||||||
specialName = "<array>",
|
specialName = "<array>",
|
||||||
initializer = baseCall.explicitReceiver ?: buildErrorExpression {
|
initializer = baseCall.explicitReceiver ?: buildErrorExpression {
|
||||||
source = baseSource
|
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||||
diagnostic = ConeSimpleDiagnostic("No receiver for array access", DiagnosticKind.Syntax)
|
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 += indexVariables
|
||||||
statements += buildFunctionCall {
|
statements += buildFunctionCall {
|
||||||
source = baseSource
|
source = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||||
explicitReceiver = arrayVariable.toQualifiedAccess()
|
explicitReceiver = arrayVariable.toQualifiedAccess()
|
||||||
calleeReference = buildSimpleNamedReference {
|
calleeReference = buildSimpleNamedReference {
|
||||||
name = OperatorNameConventions.SET
|
name = OperatorNameConventions.SET
|
||||||
@@ -1059,6 +1066,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
|
|||||||
}
|
}
|
||||||
|
|
||||||
val getCall = buildFunctionCall {
|
val getCall = buildFunctionCall {
|
||||||
|
source = arrayAccessSource?.fakeElement(KtFakeSourceElementKind.DesugaredCompoundAssignment)
|
||||||
explicitReceiver = arrayVariable.toQualifiedAccess()
|
explicitReceiver = arrayVariable.toQualifiedAccess()
|
||||||
calleeReference = buildSimpleNamedReference {
|
calleeReference = buildSimpleNamedReference {
|
||||||
name = OperatorNameConventions.GET
|
name = OperatorNameConventions.GET
|
||||||
|
|||||||
Reference in New Issue
Block a user