Intrinsics for 'reversed': generate in-const-bound ranges as countable
#KT-21323 In Progress
This commit is contained in:
+36
-4
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.resolve.constants.ByteValue
|
||||
import org.jetbrains.kotlin.resolve.constants.IntValue
|
||||
import org.jetbrains.kotlin.resolve.constants.IntegerValueConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.ShortValue
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
class PrimitiveNumberRangeLiteralRangeValue(
|
||||
@@ -40,21 +41,24 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
||||
SimpleBoundedValue(codegen, rangeCall)
|
||||
|
||||
override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
getConstRangeForInRangeLiteralGenerator(codegen, forExpression) ?:
|
||||
createConstBoundedForInRangeLiteralGenerator(codegen, forExpression) ?:
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStep1(codegen, forExpression, getBoundedValue(codegen))
|
||||
|
||||
override fun createForInReversedLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator =
|
||||
// TODO const-bounded version
|
||||
createConstBoundedRangeForInReversedRangeLiteralGenerator(codegen, forExpression) ?:
|
||||
ForInSimpleProgressionLoopGenerator.fromBoundedValueWithStepMinus1(codegen, forExpression, getBoundedValue(codegen))
|
||||
|
||||
private fun getConstRangeForInRangeLiteralGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator? {
|
||||
private fun createConstBoundedForInRangeLiteralGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression
|
||||
): ForLoopGenerator? {
|
||||
val rhsExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
||||
val constValue = codegen.getCompileTimeConstant(rhsExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||
val untilValue = when (constValue) {
|
||||
is ByteValue -> constValue.value + 1
|
||||
is ShortValue -> constValue.value + 1
|
||||
is IntValue -> constValue.value + 1
|
||||
else -> return null
|
||||
else -> Int.MIN_VALUE
|
||||
}
|
||||
|
||||
// Watch out for integer overflow
|
||||
@@ -70,4 +74,32 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
||||
step = 1
|
||||
)
|
||||
}
|
||||
|
||||
private fun createConstBoundedRangeForInReversedRangeLiteralGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression
|
||||
): ForLoopGenerator? {
|
||||
val lhsExpression = rangeCall.extensionReceiver.safeAs<ExpressionReceiver>()?.expression ?: return null
|
||||
val constValue = codegen.getCompileTimeConstant(lhsExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||
val untilValue = when (constValue) {
|
||||
is ByteValue -> constValue.value - 1
|
||||
is ShortValue -> constValue.value - 1
|
||||
is IntValue -> constValue.value - 1
|
||||
else -> Int.MAX_VALUE
|
||||
}
|
||||
|
||||
// Watch out for integer overflow
|
||||
return if (untilValue == Int.MAX_VALUE)
|
||||
null
|
||||
else
|
||||
ForInSimpleProgressionLoopGenerator(
|
||||
codegen, forExpression,
|
||||
startValue = codegen.generateCallSingleArgument(rangeCall),
|
||||
isStartInclusive = true,
|
||||
endValue = StackValue.integerConstant(untilValue, asmElementType),
|
||||
isEndInclusive = false,
|
||||
step = -1
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user