[PSI2IR] Handle resolved calls generated by AssignResolutionAltererExtension

This commit is contained in:
Dmitriy Novozhilov
2022-08-24 12:02:49 +03:00
committed by teamcity
parent 6aff3c6d07
commit 89e55139c6
2 changed files with 25 additions and 12 deletions
@@ -43,11 +43,15 @@ import org.jetbrains.kotlin.types.KotlinType
class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) {
fun generateAssignment(ktExpression: KtBinaryExpression): IrExpression {
val ktLeft = ktExpression.left!!
val irRhs = ktExpression.right!!.genExpr()
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ)
return irAssignmentReceiver.assign(irRhs)
fun generateAssignment(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
return if (getResolvedCall(ktExpression) != null) {
generateAugmentedAssignment(ktExpression, origin)
} else {
val ktLeft = ktExpression.left!!
val irRhs = ktExpression.right!!.genExpr()
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, IrStatementOrigin.EQ)
irAssignmentReceiver.assign(irRhs)
}
}
fun generateAugmentedAssignment(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression {
@@ -55,7 +59,7 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
val isSimpleAssignment = get(BindingContext.VARIABLE_REASSIGNMENT, ktExpression) ?: false
val ktLeft = ktExpression.left!!
val ktRight = ktExpression.right!!
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin)
val irAssignmentReceiver = generateAssignmentReceiver(ktLeft, origin, isAugmentedAssignment = true)
val isDynamicCall = opResolvedCall.resultingDescriptor.isDynamic()
return irAssignmentReceiver.assign { irLValue ->
@@ -167,7 +171,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
private fun generateAssignmentReceiver(
ktLeft: KtExpression,
origin: IrStatementOrigin,
isAssignmentStatement: Boolean = true
isAssignmentStatement: Boolean = true,
isAugmentedAssignment: Boolean = false
): AssignmentReceiver {
val ktExpr = KtPsiUtil.safeDeparenthesize(ktLeft)
if (ktExpr is KtArrayAccessExpression) {
@@ -203,7 +208,14 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
else
createVariableValue(ktExpr, descriptor, origin)
is PropertyDescriptor ->
generateAssignmentReceiverForProperty(descriptor, origin, ktExpr, resolvedCall, isAssignmentStatement)
generateAssignmentReceiverForProperty(
descriptor,
origin,
ktExpr,
resolvedCall,
isAssignmentStatement,
isAugmentedAssignment
)
is FakeCallableDescriptorForObject ->
OnceExpressionValue(ktExpr.genExpr())
is ValueDescriptor ->
@@ -263,7 +275,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
origin: IrStatementOrigin,
ktLeft: KtExpression,
resolvedCall: ResolvedCall<*>,
isAssignmentStatement: Boolean
isAssignmentStatement: Boolean,
isAugmentedAssignment: Boolean
): AssignmentReceiver =
when {
descriptor.isDynamic() ->
@@ -280,8 +293,8 @@ class AssignmentGenerator(statementGenerator: StatementGenerator) : StatementGen
isAssignmentReceiver = isAssignmentStatement
)
)
origin == IrStatementOrigin.EQ && !descriptor.isVar -> {
// An assignment to a val property can only be its initialization in the constructor.
origin == IrStatementOrigin.EQ && !descriptor.isVar && !isAugmentedAssignment -> {
// An assignment to a val property can only be its initialization in the constructor or an augmented assignment.
val receiver = resolvedCall.dispatchReceiver ?: descriptor.dispatchReceiverParameter?.value
createBackingFieldLValue(ktLeft, descriptor, statementGenerator.generateReceiverOrNull(ktLeft, receiver), null)
}
@@ -132,7 +132,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat
return when (val irOperator = getInfixOperator(ktOperator)) {
null -> throw AssertionError("Unexpected infix operator: $ktOperator")
IrStatementOrigin.EQ -> AssignmentGenerator(statementGenerator).generateAssignment(expression)
IrStatementOrigin.EQ -> AssignmentGenerator(statementGenerator).generateAssignment(expression, irOperator)
in AUGMENTED_ASSIGNMENTS -> AssignmentGenerator(statementGenerator).generateAugmentedAssignment(expression, irOperator)
IrStatementOrigin.ELVIS -> generateElvis(expression)
in OPERATORS_DESUGARED_TO_CALLS -> generateBinaryOperatorAsCall(expression, irOperator)