FIR: Clarify contract for BaseFirBuilder.generateAssignment

^KT-50861 Relates
This commit is contained in:
Denis.Zharkov
2022-01-19 15:41:17 +03:00
parent 6f89f1ebf4
commit 111b606580
3 changed files with 19 additions and 15 deletions
@@ -292,10 +292,10 @@ class ExpressionsConverter(
return leftArgNode.generateAssignment( return leftArgNode.generateAssignment(
binaryExpression.toFirSourceElement(), binaryExpression.toFirSourceElement(),
leftArgNode?.toFirSourceElement(), leftArgNode?.toFirSourceElement(),
rightArg,
rightArgAsFir, rightArgAsFir,
firOperation, firOperation,
leftArgAsFir.annotations leftArgAsFir.annotations,
rightArg,
) { getAsFirExpression(this) } ) { getAsFirExpression(this) }
} else { } else {
buildEqualityOperatorCall { buildEqualityOperatorCall {
@@ -2178,10 +2178,10 @@ open class RawFirBuilder(
return expression.left.generateAssignment( return expression.left.generateAssignment(
source, source,
expression.left?.toFirSourceElement(), expression.left?.toFirSourceElement(),
expression.right,
rightArgument, rightArgument,
firOperation, firOperation,
leftArgument.annotations leftArgument.annotations,
expression.right,
) { ) {
(this as KtExpression).toFirExpression("Incorrect expression in assignment: ${expression.text}") (this as KtExpression).toFirExpression("Incorrect expression in assignment: ${expression.text}")
} }
@@ -549,13 +549,13 @@ 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
resultInitializer, resultInitializer,
FirOperation.ASSIGN, FirOperation.ASSIGN,
resultInitializer.annotations, resultInitializer.annotations,
null,
convert convert
) )
@@ -900,13 +900,17 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
} }
} }
// T is a PSI or a light-tree node
fun T?.generateAssignment( fun T?.generateAssignment(
baseSource: KtSourceElement?, baseSource: KtSourceElement?,
arrayAccessSource: KtSourceElement?, arrayAccessSource: KtSourceElement?,
rhs: T?, rhsExpression: FirExpression,
value: FirExpression, // value is FIR for rhs
operation: FirOperation, operation: FirOperation,
annotations: List<FirAnnotation>, annotations: List<FirAnnotation>,
// Effectively `value = rhs?.convert()`, but at generateAugmentedArraySetCall we need to recreate FIR for rhs
// since there should be different nodes for desugaring as `.set(.., get().plus($rhs1))` and `.get(...).plusAssign($rhs2)`
// Once KT-50861 is fixed, those two parameters shall be eliminated
rhsAST: T?,
convert: T.() -> FirExpression convert: T.() -> FirExpression
): FirStatement { ): FirStatement {
val unwrappedLhs = this.unwrap() ?: return buildErrorExpression { val unwrappedLhs = this.unwrap() ?: return buildErrorExpression {
@@ -916,14 +920,14 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
val tokenType = unwrappedLhs.elementType val tokenType = unwrappedLhs.elementType
if (tokenType == ARRAY_ACCESS_EXPRESSION) { if (tokenType == ARRAY_ACCESS_EXPRESSION) {
if (operation == FirOperation.ASSIGN) { if (operation == FirOperation.ASSIGN) {
context.arraySetArgument[unwrappedLhs] = value context.arraySetArgument[unwrappedLhs] = rhsExpression
} }
return if (operation == FirOperation.ASSIGN) { return if (operation == FirOperation.ASSIGN) {
val result = unwrappedLhs.convert() val result = unwrappedLhs.convert()
(result.annotations as MutableList<FirAnnotation>) += annotations (result.annotations as MutableList<FirAnnotation>) += annotations
result result
} else { } else {
generateAugmentedArraySetCall(unwrappedLhs, baseSource, arrayAccessSource, operation, rhs, annotations, convert) generateAugmentedArraySetCall(unwrappedLhs, baseSource, arrayAccessSource, operation, annotations, rhsAST, convert)
} }
} }
@@ -938,7 +942,7 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
"Unsupported left value of assignment: ${baseSource?.psi?.text}", DiagnosticKind.ExpressionExpected "Unsupported left value of assignment: ${baseSource?.psi?.text}", DiagnosticKind.ExpressionExpected
) )
} }
rightArgument = value rightArgument = rhsExpression
this.annotations += annotations this.annotations += annotations
} }
} }
@@ -947,13 +951,13 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
if (this?.elementType == SAFE_ACCESS_EXPRESSION && this != null) { if (this?.elementType == SAFE_ACCESS_EXPRESSION && this != null) {
val safeCallNonAssignment = convert() as? FirSafeCallExpression val safeCallNonAssignment = convert() as? FirSafeCallExpression
if (safeCallNonAssignment != null) { if (safeCallNonAssignment != null) {
return putAssignmentToSafeCall(safeCallNonAssignment, baseSource, value, annotations) return putAssignmentToSafeCall(safeCallNonAssignment, baseSource, rhsExpression, annotations)
} }
} }
return buildVariableAssignment { return buildVariableAssignment {
source = baseSource source = baseSource
rValue = value rValue = rhsExpression
calleeReference = initializeLValue(unwrappedLhs) { convert() as? FirQualifiedAccess } calleeReference = initializeLValue(unwrappedLhs) { convert() as? FirQualifiedAccess }
this.annotations += annotations this.annotations += annotations
} }
@@ -963,14 +967,14 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
private fun putAssignmentToSafeCall( private fun putAssignmentToSafeCall(
safeCallNonAssignment: FirSafeCallExpression, safeCallNonAssignment: FirSafeCallExpression,
baseSource: KtSourceElement?, baseSource: KtSourceElement?,
value: FirExpression, rhsExpression: FirExpression,
annotations: List<FirAnnotation> annotations: List<FirAnnotation>
): FirSafeCallExpression { ): FirSafeCallExpression {
val nestedAccess = safeCallNonAssignment.selector as FirQualifiedAccess val nestedAccess = safeCallNonAssignment.selector as FirQualifiedAccess
val assignment = buildVariableAssignment { val assignment = buildVariableAssignment {
source = baseSource source = baseSource
rValue = value rValue = rhsExpression
calleeReference = nestedAccess.calleeReference calleeReference = nestedAccess.calleeReference
explicitReceiver = safeCallNonAssignment.checkedSubjectRef.value explicitReceiver = safeCallNonAssignment.checkedSubjectRef.value
this.annotations += annotations this.annotations += annotations
@@ -988,8 +992,8 @@ abstract class BaseFirBuilder<T>(val baseSession: FirSession, val context: Conte
baseSource: KtSourceElement?, baseSource: KtSourceElement?,
arrayAccessSource: KtSourceElement?, arrayAccessSource: KtSourceElement?,
operation: FirOperation, operation: FirOperation,
rhs: T?,
annotations: List<FirAnnotation>, annotations: List<FirAnnotation>,
rhs: T?,
convert: T.() -> FirExpression convert: T.() -> FirExpression
): FirStatement { ): FirStatement {
return buildAugmentedArraySetCall { return buildAugmentedArraySetCall {