From 0dd5042e626470900bea81dcf680cc809a495acb Mon Sep 17 00:00:00 2001 From: "Denis.Zharkov" Date: Wed, 19 Jan 2022 19:14:30 +0300 Subject: [PATCH] FIR: Extract putIncrementOrDecrementStatements --- .../kotlin/fir/builder/BaseFirBuilder.kt | 249 ++++++++---------- 1 file changed, 108 insertions(+), 141 deletions(-) diff --git a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt index 9df1f74b8a3..eca28ff6e4f 100644 --- a/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt +++ b/compiler/fir/raw-fir/raw-fir.common/src/org/jetbrains/kotlin/fir/builder/BaseFirBuilder.kt @@ -516,38 +516,16 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte val desugaredSource = baseSource?.fakeElement(KtFakeSourceElementKind.DesugaredIncrementOrDecrement) source = desugaredSource - // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). - val initialValueVar = generateTemporaryVariable( - baseModuleData, + val convertedReceiver = unwrappedReceiver.convert() + + putIncrementOrDecrementStatements( + convertedReceiver, + operationReference, + callName, + prefix, + unwrappedReceiver.takeIf { it.elementType == REFERENCE_EXPRESSION }?.getReferencedNameAsName(), desugaredSource, - SpecialNames.UNARY, - unwrappedReceiver.convert() - ) - - // resultInitializer is the expression for `argument.inc()` - val resultInitializer = buildFunctionCall { - source = desugaredSource - calleeReference = buildSimpleNamedReference { - source = operationReference?.toFirSourceElement() - name = callName - } - explicitReceiver = if (prefix) { - unwrappedReceiver.convert() - } else { - generateResolvedAccessExpression(desugaredSource, initialValueVar) - } - origin = FirFunctionCallOrigin.Operator - } - - // resultVar is only used for prefix increment/decrement. - val resultVar = generateTemporaryVariable( - baseModuleData, - desugaredSource, - Name.special(""), - resultInitializer - ) - - fun appendAssignment() { + ) { resultInitializer: FirExpression, resultVar: FirVariable -> val assignment = unwrappedReceiver.generateAssignment( desugaredSource, null, @@ -567,21 +545,87 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte statements += assignment } } + } + } - if (prefix) { - if (unwrappedReceiver.elementType != REFERENCE_EXPRESSION) { - statements += resultVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, resultVar) - } else { - appendAssignment() - statements += generateAccessExpression(desugaredSource, desugaredSource, unwrappedReceiver.getReferencedNameAsName()) - } - } else { - statements += initialValueVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) + + /** + * given: + * receiver++ + * + * result: + * { + * val = receiver + * val resultVar = .inc() + * appendAssignment(resultVar) + * ^ + * } + * + * given: + * ++receiver + * + * result: + * { + * val = receiver.inc() + * val resultVar = + * appendAssignment(resultVar) + * ^ + * } + * + */ + private fun FirBlockBuilder.putIncrementOrDecrementStatements( + receiver: FirExpression, + operationReference: T?, + callName: Name, // 'inc' or 'dec' + prefix: Boolean, + nameIfSimpleReference: Name?, // 'b' if whole expression is simple `b++` or `a.b++`, but not `a[1]++` + desugaredSource: KtSourceElement?, + appendAssignment: FirBlockBuilder.(resultInitializer: FirExpression, resultVar: FirVariable) -> Unit + ) { + // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). + val initialValueVar = generateTemporaryVariable( + baseModuleData, + desugaredSource, + SpecialNames.UNARY, + receiver + ) + + // resultInitializer is the expression for `argument.inc()` + val resultInitializer = buildFunctionCall { + source = desugaredSource + calleeReference = buildSimpleNamedReference { + source = operationReference?.toFirSourceElement() + name = callName } + explicitReceiver = if (prefix) { + receiver + } else { + generateResolvedAccessExpression(desugaredSource, initialValueVar) + } + origin = FirFunctionCallOrigin.Operator + } + + // resultVar is only used for prefix increment/decrement. + val resultVar = generateTemporaryVariable( + baseModuleData, + desugaredSource, + Name.special(""), + resultInitializer + ) + + if (prefix) { + if (nameIfSimpleReference != null) { + appendAssignment(resultInitializer, resultVar) + statements += generateAccessExpression(desugaredSource, desugaredSource, nameIfSimpleReference) + } else { + statements += resultVar + appendAssignment(resultInitializer, resultVar) + statements += generateResolvedAccessExpression(desugaredSource, resultVar) + } + } else { + statements += initialValueVar + appendAssignment(resultInitializer, resultVar) + statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) } } @@ -657,64 +701,25 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte firArgumentSelector.also { if (it is FirQualifiedAccessExpression) it.replaceExplicitReceiver(receiver) } } - // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). - val initialValueVar = generateTemporaryVariable( - baseModuleData, - desugaredSource, - SpecialNames.UNARY, - firArgument - ) - - // resultInitializer is the expression for `argument.inc()` - val resultInitializer = buildFunctionCall { - source = desugaredSource - calleeReference = buildSimpleNamedReference { - source = operationReference?.toFirSourceElement() - name = callName - } - explicitReceiver = if (prefix) { - firArgument - } else { - generateResolvedAccessExpression(desugaredSource, initialValueVar) - } - origin = FirFunctionCallOrigin.Operator - } - - // resultVar is only used for prefix increment/decrement. - val resultVar = generateTemporaryVariable( - baseModuleData, - desugaredSource, - Name.special(""), - resultInitializer - ) - - fun appendAssignment() { - if (firArgument is FirQualifiedAccessExpression) { - statements += buildVariableAssignment { - source = desugaredSource - rValue = if (prefix) { - generateResolvedAccessExpression(source, resultVar) - } else { - resultInitializer - } - explicitReceiver = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable) - calleeReference = buildSimpleNamedReference { - source = firArgument.calleeReference.source - name = (firArgument.calleeReference as FirSimpleNamedReference).name - } + putIncrementOrDecrementStatements( + firArgument, operationReference, callName, prefix, + nameIfSimpleReference = null, desugaredSource + ) { resultInitializer: FirExpression, resultVar: FirVariable -> + if (firArgument !is FirQualifiedAccessExpression) return@putIncrementOrDecrementStatements + statements += buildVariableAssignment { + source = desugaredSource + rValue = if (prefix) { + generateResolvedAccessExpression(source, resultVar) + } else { + resultInitializer + } + explicitReceiver = generateResolvedAccessExpression(argumentReceiverVariable.source, argumentReceiverVariable) + calleeReference = buildSimpleNamedReference { + source = firArgument.calleeReference.source + name = (firArgument.calleeReference as FirSimpleNamedReference).name } } } - - if (prefix) { - statements += resultVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, resultVar) - } else { - statements += initialValueVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) - } } } @@ -797,38 +802,10 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte origin = FirFunctionCallOrigin.Operator } - // initialValueVar is only used for postfix increment/decrement (stores the argument value before increment/decrement). - val initialValueVar = generateTemporaryVariable( - baseModuleData, - desugaredSource, - SpecialNames.UNARY, - firArgument - ) - - // resultInitializer is the expression for `argument.inc()` - val resultInitializer = buildFunctionCall { - source = desugaredSource - calleeReference = buildSimpleNamedReference { - source = operationReference?.toFirSourceElement() - name = callName - } - explicitReceiver = if (prefix) { - firArgument - } else { - generateResolvedAccessExpression(desugaredSource, initialValueVar) - } - origin = FirFunctionCallOrigin.Operator - } - - // resultVar is only used for prefix increment/decrement. - val resultVar = generateTemporaryVariable( - baseModuleData, - desugaredSource, - Name.special(""), - resultInitializer - ) - - fun appendAssignment() { + putIncrementOrDecrementStatements( + firArgument, operationReference, callName, prefix, + nameIfSimpleReference = null, desugaredSource + ) { resultInitializer: FirExpression, resultVar: FirVariable -> statements += buildFunctionCall { source = desugaredSource calleeReference = buildSimpleNamedReference { @@ -849,16 +826,6 @@ abstract class BaseFirBuilder(val baseSession: FirSession, val context: Conte origin = FirFunctionCallOrigin.Operator } } - - if (prefix) { - statements += resultVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, resultVar) - } else { - statements += initialValueVar - appendAssignment() - statements += generateResolvedAccessExpression(desugaredSource, initialValueVar) - } } }