Minor: pull up helper methods for const-bounded for-in-range generation
This commit is contained in:
+102
@@ -18,13 +18,19 @@ package org.jetbrains.kotlin.codegen.range
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.*
|
import org.jetbrains.kotlin.codegen.*
|
||||||
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall
|
import org.jetbrains.kotlin.codegen.range.comparison.getComparisonGeneratorForRangeContainsCall
|
||||||
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
||||||
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InFloatingPointRangeLiteralExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.InFloatingPointRangeLiteralExpressionGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.inExpression.InIntegralContinuousRangeExpressionGenerator
|
import org.jetbrains.kotlin.codegen.range.inExpression.InIntegralContinuousRangeExpressionGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.psi.KtExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
import org.jetbrains.kotlin.psi.KtSimpleNameExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
|
import org.jetbrains.kotlin.resolve.constants.*
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
||||||
@@ -64,4 +70,100 @@ abstract class PrimitiveNumberRangeIntrinsicRangeValue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract fun getBoundedValue(codegen: ExpressionCodegen): BoundedValue
|
protected abstract fun getBoundedValue(codegen: ExpressionCodegen): BoundedValue
|
||||||
|
|
||||||
|
protected fun createConstBoundedForLoopGeneratorOrNull(
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression,
|
||||||
|
startValue: StackValue,
|
||||||
|
endExpression: KtExpression,
|
||||||
|
step: Int
|
||||||
|
): ForLoopGenerator? {
|
||||||
|
val endConstValue = codegen.getCompileTimeConstant(endExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
||||||
|
|
||||||
|
return when (endConstValue) {
|
||||||
|
is ByteValue -> {
|
||||||
|
val endIntValue = endConstValue.value.toInt()
|
||||||
|
if (isProhibitedIntConstEndValue(step, endIntValue))
|
||||||
|
null
|
||||||
|
else
|
||||||
|
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ShortValue -> {
|
||||||
|
val endIntValue = endConstValue.value.toInt()
|
||||||
|
if (isProhibitedIntConstEndValue(step, endIntValue))
|
||||||
|
null
|
||||||
|
else
|
||||||
|
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
is IntValue -> {
|
||||||
|
val endIntValue = endConstValue.value
|
||||||
|
if (isProhibitedIntConstEndValue(step, endIntValue))
|
||||||
|
null
|
||||||
|
else
|
||||||
|
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
is CharValue -> {
|
||||||
|
val endCharValue = endConstValue.value
|
||||||
|
if (isProhibitedCharConstEndValue(step, endCharValue))
|
||||||
|
null
|
||||||
|
else
|
||||||
|
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endCharValue.toInt(), step)
|
||||||
|
}
|
||||||
|
|
||||||
|
is LongValue -> {
|
||||||
|
val endLongValue = endConstValue.value
|
||||||
|
if (isProhibitedLongConstEndValue(step, endLongValue))
|
||||||
|
null
|
||||||
|
else
|
||||||
|
createConstBoundedLongForLoopGenerator(codegen, forExpression, startValue, endLongValue, step)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createConstBoundedIntForLoopGenerator(
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression,
|
||||||
|
startValue: StackValue,
|
||||||
|
endIntValue: Int,
|
||||||
|
step: Int
|
||||||
|
): ForLoopGenerator? =
|
||||||
|
ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
||||||
|
codegen, forExpression,
|
||||||
|
startValue = startValue,
|
||||||
|
isStartInclusive = true,
|
||||||
|
endValue = StackValue.integerConstant(endIntValue, asmElementType),
|
||||||
|
isEndInclusive = true,
|
||||||
|
step = step
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun createConstBoundedLongForLoopGenerator(
|
||||||
|
codegen: ExpressionCodegen,
|
||||||
|
forExpression: KtForExpression,
|
||||||
|
startValue: StackValue,
|
||||||
|
endLongValue: Long,
|
||||||
|
step: Int
|
||||||
|
): ForLoopGenerator? =
|
||||||
|
ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
||||||
|
codegen, forExpression,
|
||||||
|
startValue = startValue,
|
||||||
|
isStartInclusive = true,
|
||||||
|
endValue = StackValue.constant(endLongValue, asmElementType),
|
||||||
|
isEndInclusive = true,
|
||||||
|
step = step
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun isProhibitedCharConstEndValue(step: Int, endValue: Char) =
|
||||||
|
endValue == if (step == 1) java.lang.Character.MAX_VALUE else java.lang.Character.MIN_VALUE
|
||||||
|
|
||||||
|
private fun isProhibitedIntConstEndValue(step: Int, endValue: Int) =
|
||||||
|
endValue == if (step == 1) Int.MAX_VALUE else Int.MIN_VALUE
|
||||||
|
|
||||||
|
private fun isProhibitedLongConstEndValue(step: Int, endValue: Long) =
|
||||||
|
endValue == if (step == 1) Long.MAX_VALUE else Long.MIN_VALUE
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-102
@@ -17,17 +17,13 @@
|
|||||||
package org.jetbrains.kotlin.codegen.range
|
package org.jetbrains.kotlin.codegen.range
|
||||||
|
|
||||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||||
import org.jetbrains.kotlin.codegen.StackValue
|
|
||||||
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
import org.jetbrains.kotlin.codegen.generateCallReceiver
|
||||||
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
import org.jetbrains.kotlin.codegen.generateCallSingleArgument
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInDefinitelySafeSimpleProgressionLoopGenerator
|
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForInSimpleProgressionLoopGenerator
|
||||||
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtExpression
|
|
||||||
import org.jetbrains.kotlin.psi.KtForExpression
|
import org.jetbrains.kotlin.psi.KtForExpression
|
||||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||||
import org.jetbrains.kotlin.resolve.constants.*
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
@@ -52,7 +48,7 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
|||||||
forExpression: KtForExpression
|
forExpression: KtForExpression
|
||||||
): ForLoopGenerator? {
|
): ForLoopGenerator? {
|
||||||
val endExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
val endExpression = rangeCall.valueArgumentsByIndex?.run { get(0).arguments[0].getArgumentExpression() } ?: return null
|
||||||
return createConstBoundedForLoopGenerator(
|
return createConstBoundedForLoopGeneratorOrNull(
|
||||||
codegen, forExpression,
|
codegen, forExpression,
|
||||||
codegen.generateCallReceiver(rangeCall),
|
codegen.generateCallReceiver(rangeCall),
|
||||||
endExpression,
|
endExpression,
|
||||||
@@ -65,107 +61,11 @@ class PrimitiveNumberRangeLiteralRangeValue(
|
|||||||
forExpression: KtForExpression
|
forExpression: KtForExpression
|
||||||
): ForLoopGenerator? {
|
): ForLoopGenerator? {
|
||||||
val endExpression = rangeCall.extensionReceiver.safeAs<ExpressionReceiver>()?.expression ?: return null
|
val endExpression = rangeCall.extensionReceiver.safeAs<ExpressionReceiver>()?.expression ?: return null
|
||||||
return createConstBoundedForLoopGenerator(
|
return createConstBoundedForLoopGeneratorOrNull(
|
||||||
codegen, forExpression,
|
codegen, forExpression,
|
||||||
codegen.generateCallSingleArgument(rangeCall),
|
codegen.generateCallSingleArgument(rangeCall),
|
||||||
endExpression,
|
endExpression,
|
||||||
-1
|
-1
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createConstBoundedForLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
startValue: StackValue,
|
|
||||||
endExpression: KtExpression,
|
|
||||||
step: Int
|
|
||||||
): ForLoopGenerator? {
|
|
||||||
val endConstValue = codegen.getCompileTimeConstant(endExpression).safeAs<IntegerValueConstant<*>>() ?: return null
|
|
||||||
|
|
||||||
return when (endConstValue) {
|
|
||||||
is ByteValue -> {
|
|
||||||
val endIntValue = endConstValue.value.toInt()
|
|
||||||
if (isProhibitedIntConstEndValue(step, endIntValue))
|
|
||||||
null
|
|
||||||
else
|
|
||||||
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
is ShortValue -> {
|
|
||||||
val endIntValue = endConstValue.value.toInt()
|
|
||||||
if (isProhibitedIntConstEndValue(step, endIntValue))
|
|
||||||
null
|
|
||||||
else
|
|
||||||
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
is IntValue -> {
|
|
||||||
val endIntValue = endConstValue.value
|
|
||||||
if (isProhibitedIntConstEndValue(step, endIntValue))
|
|
||||||
null
|
|
||||||
else
|
|
||||||
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endIntValue, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
is CharValue -> {
|
|
||||||
val endCharValue = endConstValue.value
|
|
||||||
if (isProhibitedCharConstEndValue(step, endCharValue))
|
|
||||||
null
|
|
||||||
else
|
|
||||||
createConstBoundedIntForLoopGenerator(codegen, forExpression, startValue, endCharValue.toInt(), step)
|
|
||||||
}
|
|
||||||
|
|
||||||
is LongValue -> {
|
|
||||||
val endLongValue = endConstValue.value
|
|
||||||
if (isProhibitedLongConstEndValue(step, endLongValue))
|
|
||||||
null
|
|
||||||
else
|
|
||||||
createConstBoundedLongForLoopGenerator(codegen, forExpression, startValue, endLongValue, step)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createConstBoundedIntForLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
startValue: StackValue,
|
|
||||||
endIntValue: Int,
|
|
||||||
step: Int
|
|
||||||
): ForLoopGenerator? =
|
|
||||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
|
||||||
codegen, forExpression,
|
|
||||||
startValue = startValue,
|
|
||||||
isStartInclusive = true,
|
|
||||||
endValue = StackValue.integerConstant(endIntValue, asmElementType),
|
|
||||||
isEndInclusive = true,
|
|
||||||
step = step
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun createConstBoundedLongForLoopGenerator(
|
|
||||||
codegen: ExpressionCodegen,
|
|
||||||
forExpression: KtForExpression,
|
|
||||||
startValue: StackValue,
|
|
||||||
endLongValue: Long,
|
|
||||||
step: Int
|
|
||||||
): ForLoopGenerator? =
|
|
||||||
ForInDefinitelySafeSimpleProgressionLoopGenerator(
|
|
||||||
codegen, forExpression,
|
|
||||||
startValue = startValue,
|
|
||||||
isStartInclusive = true,
|
|
||||||
endValue = StackValue.constant(endLongValue, asmElementType),
|
|
||||||
isEndInclusive = true,
|
|
||||||
step = step
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun isProhibitedCharConstEndValue(step: Int, endValue: Char) =
|
|
||||||
endValue == if (step == 1) java.lang.Character.MAX_VALUE else java.lang.Character.MIN_VALUE
|
|
||||||
|
|
||||||
private fun isProhibitedIntConstEndValue(step: Int, endValue: Int) =
|
|
||||||
endValue == if (step == 1) Int.MAX_VALUE else Int.MIN_VALUE
|
|
||||||
|
|
||||||
private fun isProhibitedLongConstEndValue(step: Int, endValue: Long) =
|
|
||||||
endValue == if (step == 1) Long.MAX_VALUE else Long.MIN_VALUE
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user