backend: Set 'origin' property for generated variables in 'for' loops
This commit is contained in:
+17
-9
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
|||||||
import org.jetbrains.kotlin.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
@@ -201,8 +202,7 @@ private class ForLoopsTransformer(val context: Context) : IrElementTransformerVo
|
|||||||
|
|
||||||
//region Util classes ==============================================================================================
|
//region Util classes ==============================================================================================
|
||||||
// TODO: Replace with a cast when such support is added in the boxing lowering.
|
// TODO: Replace with a cast when such support is added in the boxing lowering.
|
||||||
private data class ProgressionType(val elementType: KotlinType,
|
private data class ProgressionType(val elementType: KotlinType, val numberCastFunctionName: Name) {
|
||||||
val numberCastFunctionName: Name) {
|
|
||||||
fun isIntProgression() = KotlinBuiltIns.isInt(elementType)
|
fun isIntProgression() = KotlinBuiltIns.isInt(elementType)
|
||||||
fun isLongProgression() = KotlinBuiltIns.isLong(elementType)
|
fun isLongProgression() = KotlinBuiltIns.isLong(elementType)
|
||||||
fun isCharProgression() = KotlinBuiltIns.isChar(elementType)
|
fun isCharProgression() = KotlinBuiltIns.isChar(elementType)
|
||||||
@@ -291,6 +291,7 @@ private class ForLoopsTransformer(val context: Context) : IrElementTransformerVo
|
|||||||
//region Lowering ==================================================================================================
|
//region Lowering ==================================================================================================
|
||||||
// Lower a loop header.
|
// Lower a loop header.
|
||||||
private fun processHeader(variable: IrVariable, initializer: IrCall): IrStatement? {
|
private fun processHeader(variable: IrVariable, initializer: IrCall): IrStatement? {
|
||||||
|
assert(variable.origin == IrDeclarationOrigin.FOR_LOOP_ITERATOR)
|
||||||
val symbol = variable.symbol
|
val symbol = variable.symbol
|
||||||
if (!variable.descriptor.type.isSubtypeOf(iteratorType)) {
|
if (!variable.descriptor.type.isSubtypeOf(iteratorType)) {
|
||||||
return null
|
return null
|
||||||
@@ -309,20 +310,25 @@ private class ForLoopsTransformer(val context: Context) : IrElementTransformerVo
|
|||||||
* For this loop:
|
* For this loop:
|
||||||
* `for (i in a() .. b() step c() step d())`
|
* `for (i in a() .. b() step c() step d())`
|
||||||
* We need to call functions in the following order: a, b, c, d.
|
* We need to call functions in the following order: a, b, c, d.
|
||||||
* So we call b() before step calculations and then call last element calculation function (if necessary).
|
* So we call b() before step calculations and then call last element calculation function (if required).
|
||||||
*/
|
*/
|
||||||
val inductionVariable = scope.createTemporaryVariable(first.castIfNecessary(progressionType),
|
val inductionVariable = scope.createTemporaryVariable(first.castIfNecessary(progressionType),
|
||||||
"inductionVariable",
|
nameHint = "inductionVariable",
|
||||||
true).also {
|
isMutable = true,
|
||||||
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE).also {
|
||||||
statements.add(it)
|
statements.add(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
val boundValue = scope.createTemporaryVariable(bound.castIfNecessary(progressionType),"bound")
|
val boundValue = scope.createTemporaryVariable(bound.castIfNecessary(progressionType),
|
||||||
|
nameHint = "bound",
|
||||||
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE)
|
||||||
.also { statements.add(it) }
|
.also { statements.add(it) }
|
||||||
|
|
||||||
|
|
||||||
val stepExpression = (if (increasing) step else step?.unaryMinus()) ?: defaultStep(startOffset, endOffset)
|
val stepExpression = (if (increasing) step else step?.unaryMinus()) ?: defaultStep(startOffset, endOffset)
|
||||||
val stepValue = scope.createTemporaryVariable(stepExpression, "step").also {
|
val stepValue = scope.createTemporaryVariable(stepExpression,
|
||||||
|
nameHint = "step",
|
||||||
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE).also {
|
||||||
statements.add(it)
|
statements.add(it)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,7 +352,9 @@ private class ForLoopsTransformer(val context: Context) : IrElementTransformerVo
|
|||||||
stepValue.symbol)
|
stepValue.symbol)
|
||||||
}
|
}
|
||||||
val lastValue = if (lastExpression != null) {
|
val lastValue = if (lastExpression != null) {
|
||||||
scope.createTemporaryVariable(lastExpression, "last").also {
|
scope.createTemporaryVariable(lastExpression,
|
||||||
|
nameHint = "last",
|
||||||
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE).also {
|
||||||
statements.add(it)
|
statements.add(it)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -364,9 +372,9 @@ private class ForLoopsTransformer(val context: Context) : IrElementTransformerVo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Lower getting a next induction variable value.
|
// Lower getting a next induction variable value.
|
||||||
private fun processNext(variable: IrVariable, initializer: IrCall): IrExpression? {
|
private fun processNext(variable: IrVariable, initializer: IrCall): IrExpression? {
|
||||||
|
assert(variable.origin == IrDeclarationOrigin.FOR_LOOP_VARIABLE)
|
||||||
val irIteratorAccess = initializer.dispatchReceiver as? IrGetValue ?: throw AssertionError()
|
val irIteratorAccess = initializer.dispatchReceiver as? IrGetValue ?: throw AssertionError()
|
||||||
val forLoopInfo = iteratorToLoopInfo[irIteratorAccess.symbol] ?: return null // If we didn't lower a corresponding header.
|
val forLoopInfo = iteratorToLoopInfo[irIteratorAccess.symbol] ?: return null // If we didn't lower a corresponding header.
|
||||||
val builder = context.createIrBuilder(scopeOwnerSymbol, initializer.startOffset, initializer.endOffset)
|
val builder = context.createIrBuilder(scopeOwnerSymbol, initializer.startOffset, initializer.endOffset)
|
||||||
|
|||||||
Reference in New Issue
Block a user