Cast step expression to the correct Number type, if necessary.
This commit is contained in:
committed by
max-kammerer
parent
f6e74079bb
commit
6b83c04472
+4
-4
@@ -26,10 +26,10 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
|||||||
// TODO: Handle UIntProgression, ULongProgression
|
// TODO: Handle UIntProgression, ULongProgression
|
||||||
|
|
||||||
/** Represents a progression type in the Kotlin stdlib. */
|
/** Represents a progression type in the Kotlin stdlib. */
|
||||||
enum class ProgressionType(val numberCastFunctionName: Name) {
|
enum class ProgressionType(val elementCastFunctionName: Name, val stepCastFunctionName: Name) {
|
||||||
INT_PROGRESSION(Name.identifier("toInt")),
|
INT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt")),
|
||||||
LONG_PROGRESSION(Name.identifier("toLong")),
|
LONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong")),
|
||||||
CHAR_PROGRESSION(Name.identifier("toChar"));
|
CHAR_PROGRESSION(Name.identifier("toChar"), Name.identifier("toInt"));
|
||||||
|
|
||||||
/** Returns the [IrType] of the `first`/`last` properties and elements in the progression. */
|
/** Returns the [IrType] of the `first`/`last` properties and elements in the progression. */
|
||||||
fun elementType(builtIns: IrBuiltIns): IrType = when (this) {
|
fun elementType(builtIns: IrBuiltIns): IrType = when (this) {
|
||||||
|
|||||||
+20
-6
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.functions
|
import org.jetbrains.kotlin.ir.util.functions
|
||||||
import org.jetbrains.kotlin.ir.util.isNullable
|
import org.jetbrains.kotlin.ir.util.isNullable
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
/** Contains information about variables used in the loop. */
|
/** Contains information about variables used in the loop. */
|
||||||
internal sealed class ForLoopHeader(
|
internal sealed class ForLoopHeader(
|
||||||
@@ -224,7 +225,10 @@ internal class HeaderProcessor(
|
|||||||
// In the above example, if first() is a Long and last() is an Int, this creates a
|
// In the above example, if first() is a Long and last() is an Int, this creates a
|
||||||
// LongProgression so last(), should be cast to a Long.
|
// LongProgression so last(), should be cast to a Long.
|
||||||
val inductionVariable = scope.createTemporaryVariable(
|
val inductionVariable = scope.createTemporaryVariable(
|
||||||
first.castIfNecessary(progressionType),
|
first.castIfNecessary(
|
||||||
|
progressionType.elementType(context.irBuiltIns),
|
||||||
|
progressionType.elementCastFunctionName
|
||||||
|
),
|
||||||
nameHint = "inductionVariable",
|
nameHint = "inductionVariable",
|
||||||
isMutable = true,
|
isMutable = true,
|
||||||
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
||||||
@@ -235,13 +239,23 @@ internal class HeaderProcessor(
|
|||||||
// them to non-nullable.
|
// them to non-nullable.
|
||||||
// TODO: Confirm if casting to non-nullable is still necessary
|
// TODO: Confirm if casting to non-nullable is still necessary
|
||||||
val lastValue = scope.createTemporaryVariable(
|
val lastValue = scope.createTemporaryVariable(
|
||||||
ensureNotNullable(last.castIfNecessary(progressionType)),
|
ensureNotNullable(
|
||||||
|
last.castIfNecessary(
|
||||||
|
progressionType.elementType(context.irBuiltIns),
|
||||||
|
progressionType.elementCastFunctionName
|
||||||
|
)
|
||||||
|
),
|
||||||
nameHint = "last",
|
nameHint = "last",
|
||||||
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
||||||
)
|
)
|
||||||
|
|
||||||
val stepValue = scope.createTemporaryVariable(
|
val stepValue = scope.createTemporaryVariable(
|
||||||
ensureNotNullable(step),
|
ensureNotNullable(
|
||||||
|
step.castIfNecessary(
|
||||||
|
progressionType.stepType(context.irBuiltIns),
|
||||||
|
progressionType.stepCastFunctionName
|
||||||
|
)
|
||||||
|
),
|
||||||
nameHint = "step",
|
nameHint = "step",
|
||||||
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
|
||||||
)
|
)
|
||||||
@@ -265,11 +279,11 @@ internal class HeaderProcessor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun IrExpression.castIfNecessary(progressionType: ProgressionType): IrExpression {
|
private fun IrExpression.castIfNecessary(targetType: IrType, numberCastFunctionName: Name): IrExpression {
|
||||||
return if (type.toKotlinType() == progressionType.elementType(context.irBuiltIns).toKotlinType()) {
|
return if (type.toKotlinType() == targetType.toKotlinType()) {
|
||||||
this
|
this
|
||||||
} else {
|
} else {
|
||||||
val function = type.getClass()!!.functions.first { it.name == progressionType.numberCastFunctionName }
|
val function = type.getClass()!!.functions.first { it.name == numberCastFunctionName }
|
||||||
IrCallImpl(startOffset, endOffset, function.returnType, function.symbol)
|
IrCallImpl(startOffset, endOffset, function.returnType, function.symbol)
|
||||||
.apply { dispatchReceiver = this@castIfNecessary }
|
.apply { dispatchReceiver = this@castIfNecessary }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user