diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt index 43c956facff..017bda71673 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt @@ -41,48 +41,59 @@ val forLoopsPhase = makeIrFilePhase( * * For example, this loop: * ``` - * for (i in first..last) { // Do something with i } + * for (loopVar in A..B) { // Loop body } * ``` * is represented in IR in such a manner: * ``` - * val it = (first..last).iterator() + * val it = (A..B).iterator() * while (it.hasNext()) { - * val i = it.next() - * // Do something with i + * val loopVar = it.next() + * // Loop body * } * ``` * We transform it into one of the following loops: * * ``` - * // 1. If the induction variable cannot overflow, i.e., `last` is const and != MAX_VALUE (if increasing, or MIN_VALUE if decreasing), - * // OR if loop is an until loop (e.g., `for (i in first until last)`): + * // 1. If the induction variable cannot overflow, i.e., `B` is const and != MAX_VALUE (if increasing, or MIN_VALUE if decreasing). * - * var inductionVar = first - * while (inductionVar <= last) { // (inductionVar >= last if the progression is decreasing) - * val i = inductionVar - * inductionVar++ - * // Do something with i + * var inductionVar = A + * var last = B + * while (inductionVar <= last) { // (`inductionVar >= last` if the progression is decreasing) + * val loopVar = inductionVar + * inductionVar++ // (`inductionVar--` if the progression is decreasing) + * // Loop body * } * * // 2. If the induction variable CAN overflow, i.e., `last` is not const or is MAX/MIN_VALUE: * - * var inductionVar = first - * if (inductionVar <= last) { // (inductionVar >= last if the progression is decreasing) + * var inductionVar = A + * var last = B + * if (inductionVar <= last) { // (`inductionVar >= last` if the progression is decreasing) * // Loop is not empty * do { - * val i = inductionVar - * inductionVar++ - * // Do something with i - * } while (i != last) + * val loopVar = inductionVar + * inductionVar++ // (`inductionVar--` if the progression is decreasing) + * // Loop body + * } while (loopVar != last) + * } + * + * // 3. If loop is an until loop (e.g., `for (i in A until B)`), it cannot overflow and we use `<` for comparisons: + * + * var inductionVar = A + * var last = B + * while (inductionVar < last) { + * val loopVar = inductionVar + * inductionVar++ + * // Loop body * } * ``` - * In case of iteration over an array, we transform it into the following: + * In case of iteration over an array (e.g., `for (i in array)`), we transform it into the following: * ``` * var inductionVar = 0 - * val last = array.size - 1 - * while (inductionVar <= last) { - * val i = array[inductionVar++] - * // Do something with i + * val last = array.size + * while (inductionVar < last) { + * val loopVar = array[inductionVar++] + * // Loop body * } * ``` */ diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt index fd0b1418ee0..aa5e03dcf99 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt @@ -61,7 +61,8 @@ internal sealed class HeaderInfo( val progressionType: ProgressionType, val first: IrExpression, val last: IrExpression, - val step: IrExpression + val step: IrExpression, + val isLastInclusive: Boolean ) { val direction: ProgressionDirection by lazy { // If step is a constant (either Int or Long), then we can determine the direction. @@ -82,10 +83,10 @@ internal class ProgressionHeaderInfo( first: IrExpression, last: IrExpression, step: IrExpression, + isLastInclusive: Boolean = true, canOverflow: Boolean? = null, - val additionalVariables: List = listOf(), - val additionalNotEmptyCondition: IrExpression? = null -) : HeaderInfo(progressionType, first, last, step) { + val additionalVariables: List = listOf() +) : HeaderInfo(progressionType, first, last, step, isLastInclusive) { private val _canOverflow: Boolean? = canOverflow val canOverflow: Boolean by lazy { @@ -129,7 +130,8 @@ internal class ArrayHeaderInfo( ProgressionType.INT_PROGRESSION, first, last, - step + step, + isLastInclusive = false ) /** Matches a call to `iterator()` and builds a [HeaderInfo] out of the call's context. */ diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index 43d7ef15fbc..9040fa63d7d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -26,10 +26,10 @@ import org.jetbrains.kotlin.name.Name /** Contains information about variables used in the loop. */ internal sealed class ForLoopHeader( + protected open val headerInfo: HeaderInfo, val inductionVariable: IrVariable, val last: IrVariable, val step: IrVariable, - val progressionType: ProgressionType, var loopVariable: IrVariable? = null ) { /** Expression used to initialize the loop variable at the beginning of the loop. */ @@ -48,26 +48,98 @@ internal sealed class ForLoopHeader( * Returns null if no check is needed for the for-loop. */ abstract fun buildNotEmptyConditionIfNecessary(builder: DeclarationIrBuilder): IrExpression? + + protected fun buildLoopCondition(builder: DeclarationIrBuilder): IrExpression = + with(builder) { + val builtIns = context.irBuiltIns + val progressionType = headerInfo.progressionType + val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType() + val compFun = + if (headerInfo.isLastInclusive) builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!! + else builtIns.lessFunByOperandType[progressionKotlinType]!! + + // The default condition depends on the direction. + return when (headerInfo.direction) { + ProgressionDirection.DECREASING -> + // last <= inductionVar (use `<` if last is exclusive) + irCall(compFun).apply { + putValueArgument(0, irGet(last)) + putValueArgument(1, irGet(inductionVariable)) + } + ProgressionDirection.INCREASING -> + // inductionVar <= last (use `<` if last is exclusive) + irCall(compFun).apply { + putValueArgument(0, irGet(inductionVariable)) + putValueArgument(1, irGet(last)) + } + ProgressionDirection.UNKNOWN -> { + // If the direction is unknown, we check depending on the "step" value: + // // (use `<` if last is exclusive) + // (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar) + val stepKotlinType = progressionType.stepType(builtIns).toKotlinType() + val zero = if (progressionType == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0) + context.oror( + context.andand( + irCall(builtIns.greaterFunByOperandType[stepKotlinType]!!).apply { + putValueArgument(0, irGet(step)) + putValueArgument(1, zero) + }, + irCall(compFun).apply { + putValueArgument(0, irGet(inductionVariable)) + putValueArgument(1, irGet(last)) + }), + context.andand( + irCall(builtIns.lessFunByOperandType[stepKotlinType]!!).apply { + putValueArgument(0, irGet(step)) + putValueArgument(1, zero) + }, + irCall(compFun).apply { + putValueArgument(0, irGet(last)) + putValueArgument(1, irGet(inductionVariable)) + }) + ) + } + } + } } internal class ProgressionLoopHeader( - private val headerInfo: ProgressionHeaderInfo, + override val headerInfo: ProgressionHeaderInfo, inductionVariable: IrVariable, last: IrVariable, step: IrVariable -) : ForLoopHeader(inductionVariable, last, step, headerInfo.progressionType) { +) : ForLoopHeader(headerInfo, inductionVariable, last, step) { override fun initializeLoopVariable(symbols: Symbols, builder: DeclarationIrBuilder) = with(builder) { // loopVariable = inductionVariable irGet(inductionVariable) } + // For this loop: + // + // for (i in first()..last() step step()) + // + // ...the functions may have side-effects so we need to call them in the following order: first() (inductionVariable), last(), step(). + // Additional variables come first as they may be needed to the subsequent variables. override val declarations: List get() = headerInfo.additionalVariables + listOf(inductionVariable, last, step) override fun buildInnerLoop(builder: DeclarationIrBuilder, loop: IrLoop, newBody: IrExpression?): IrLoop = with(builder) { if (headerInfo.canOverflow) { - // Condition: loopVariable != last. We cannot use the induction variable because it can overflow. + // If the induction variable CAN overflow, we cannot use it in the loop condition. Loop is lowered into something like: + // + // var inductionVar = A + // var last = B + // if (inductionVar <= last) { + // // Loop is not empty + // do { + // val loopVar = inductionVar + // inductionVar++ + // // Loop body + // } while (loopVar != last) + // } + // + // The `if (inductionVar <= last)` "not empty" check is added in buildNotEmptyConditionIfNecessary(). assert(loopVariable != null) val booleanNotFun = context.irBuiltIns.booleanClass.functions.first { it.owner.name.asString() == "not" } val newCondition = irCallOp(booleanNotFun, booleanNotFun.owner.returnType, irCall(context.irBuiltIns.eqeqSymbol).apply { @@ -80,85 +152,38 @@ internal class ProgressionLoopHeader( body = newBody } } else { - // If the induction variable cannot overflow, use a while loop using the "not empty" condition. - val newCondition = buildNotEmptyCondition(this@with) + // If the induction variable can NOT overflow, use a simple while loop. Loop is lowered into something like: + // + // var inductionVar = A + // var last = B + // while (inductionVar <= last) { + // val loopVar = inductionVar + // inductionVar++ + // // Loop body + // } IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, loop.origin).apply { label = loop.label - condition = newCondition + condition = buildLoopCondition(this@with) body = newBody } } } - // If the induction variable cannot overflow, we do NOT need the enclosing "not empty" check because the for-loop is lowered into a - // while loop that uses the "not empty" condition (see buildInnerLoop()); the enclosing check would be redundant. + // If the induction variable can NOT overflow, we do NOT need the enclosing "not empty" check because the for-loop is lowered into a + // simple while loop (see buildInnerLoop()); the enclosing check would be redundant. override fun buildNotEmptyConditionIfNecessary(builder: DeclarationIrBuilder): IrExpression? = - if (headerInfo.canOverflow) buildNotEmptyCondition(builder) else null - - private fun buildNotEmptyCondition(builder: DeclarationIrBuilder): IrExpression = - with(builder) { - val builtIns = context.irBuiltIns - val progressionKotlinType = progressionType.elementType(builtIns).toKotlinType() - val lessOrEqualFun = builtIns.lessOrEqualFunByOperandType[progressionKotlinType]!! - - // The default "not empty" condition depends on the direction. - val notEmptyCondition = when (headerInfo.direction) { - ProgressionDirection.DECREASING -> - // last <= inductionVariable - irCall(lessOrEqualFun).apply { - putValueArgument(0, irGet(last)) - putValueArgument(1, irGet(inductionVariable)) - } - ProgressionDirection.INCREASING -> - // inductionVariable <= last - irCall(lessOrEqualFun).apply { - putValueArgument(0, irGet(inductionVariable)) - putValueArgument(1, irGet(last)) - } - ProgressionDirection.UNKNOWN -> { - // If the direction is unknown, we check depending on the "step" value: - // (step > 0 && inductionVariable <= last) || (step < 0 || last <= inductionVariable) - val stepKotlinType = progressionType.stepType(builtIns).toKotlinType() - val zero = if (progressionType == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0) - context.oror( - context.andand( - irCall(builtIns.greaterFunByOperandType[stepKotlinType]!!).apply { - putValueArgument(0, irGet(step)) - putValueArgument(1, zero) - }, - irCall(lessOrEqualFun).apply { - putValueArgument(0, irGet(inductionVariable)) - putValueArgument(1, irGet(last)) - }), - context.andand( - irCall(builtIns.lessFunByOperandType[stepKotlinType]!!).apply { - putValueArgument(0, irGet(step)) - putValueArgument(1, zero) - }, - irCall(lessOrEqualFun).apply { - putValueArgument(0, irGet(last)) - putValueArgument(1, irGet(inductionVariable)) - }) - ) - } - } - - if (headerInfo.additionalNotEmptyCondition != null) context.andand( - headerInfo.additionalNotEmptyCondition, - notEmptyCondition - ) else notEmptyCondition - } + if (headerInfo.canOverflow) buildLoopCondition(builder) else null } internal class ArrayLoopHeader( - private val headerInfo: ArrayHeaderInfo, + override val headerInfo: ArrayHeaderInfo, inductionVariable: IrVariable, last: IrVariable, step: IrVariable -) : ForLoopHeader(inductionVariable, last, step, ProgressionType.INT_PROGRESSION) { +) : ForLoopHeader(headerInfo, inductionVariable, last, step) { override fun initializeLoopVariable(symbols: Symbols, builder: DeclarationIrBuilder) = with(builder) { - // loopVariable = array[inductionVariable] + // inductionVar = loopVar[inductionVariable] val arrayGetFun = headerInfo.arrayVariable.type.getClass()!!.functions.first { it.name.asString() == "get" } irCall(arrayGetFun).apply { dispatchReceiver = irGet(headerInfo.arrayVariable) @@ -170,17 +195,18 @@ internal class ArrayLoopHeader( get() = listOf(headerInfo.arrayVariable, inductionVariable, last, step) override fun buildInnerLoop(builder: DeclarationIrBuilder, loop: IrLoop, newBody: IrExpression?): IrLoop = with(builder) { - // Condition: inductionVariable != last - val builtIns = context.irBuiltIns - val callee = builtIns.lessOrEqualFunByOperandType[builtIns.int]!! - val newCondition = irCall(callee).apply { - putValueArgument(0, irGet(inductionVariable)) - putValueArgument(1, irGet(last)) - } - + // Loop is lowered into something like: + // + // var inductionVar = 0 + // var last = array.size + // while (inductionVar < last) { + // val loopVar = array[inductionVar++] + // inductionVar++ + // // Loop body + // } IrWhileLoopImpl(loop.startOffset, loop.endOffset, loop.type, loop.origin).apply { label = loop.label - condition = newCondition + condition = buildLoopCondition(this@with) body = newBody } } @@ -224,18 +250,13 @@ internal class HeaderProcessor( with(headerInfo) { // For this loop: // - // ``` - // for (i in first()..last() step step()) - // ``` + // for (i in first()..last() step step()) // - // ...the functions may have side-effects so we need to call them in the following - // order: first(), last(), step(). - // - // We also need to cast them to conform to the progression type so that operations - // in the induction variable within the loop are more efficient. + // We need to cast first(), last(). and step() to conform to the progression type so + // that operations on the induction variable within the loop are more efficient. // // 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( first.castIfNecessary( progressionType.elementType(context.irBuiltIns), diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt index 8c8daf6c330..ad988bfba96 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt @@ -6,23 +6,19 @@ package org.jetbrains.kotlin.backend.common.lower.loops import org.jetbrains.kotlin.backend.common.CommonBackendContext -import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher import org.jetbrains.kotlin.backend.common.lower.matchers.singleArgumentExtension import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.ir.builders.* +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irGet +import org.jetbrains.kotlin.ir.builders.irInt import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.IrCall -import org.jetbrains.kotlin.ir.expressions.IrConst -import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.toKotlinType -import org.jetbrains.kotlin.ir.util.functions import org.jetbrains.kotlin.ir.util.properties import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name @@ -80,78 +76,15 @@ internal class UntilHandler(private val context: CommonBackendContext, private v override fun build(call: IrCall, data: ProgressionType): HeaderInfo? = with(context.createIrBuilder(call.symbol, call.startOffset, call.endOffset)) { - val boundArg = call.getValueArgument(0)!! - val bound = ensureNotNullable( - boundArg.castIfNecessary( - data.elementType(context.irBuiltIns), - data.elementCastFunctionName - ) - ) - // `bound` may be needed for an additional condition to the emptiness check (see comments below). If so, store `bound` in a - // temporary variable as it may be an expression with side-effects and we should only evaluate it once. - val boundVar = if (needsMinValueCondition(data, boundArg)) scope.createTemporaryVariable( - bound, - nameHint = "bound", - origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE - ) else null - - // `last = bound - 1` for the loop `for (i in first until bound)`. - val decFun = data.decFun(context.irBuiltIns) - val last = irCallOp(decFun.symbol, bound.type, if (boundVar != null) irGet(boundVar) else bound) - - // The default "not empty" check cannot be used for the corner case: - // - // for (i in a until MIN_VALUE) {} - // - // ...which should always be considered an empty range. When the given bound is MIN_VALUE, and because `last = bound - 1`, - // "last" will underflow to MAX_VALUE, therefore the default "not empty" check: - // - // if (inductionVar <= last) { /* loop */ } - // - // ...will always be true and won't consider the range as empty. Therefore, we need to add an additional condition to the - // "not empty" check so that it becomes: - // - // if (inductionVar <= last && bound > MIN_VALUE) { /* loop */ } ProgressionHeaderInfo( data, first = call.extensionReceiver!!, - last = last, + last = call.getValueArgument(0)!!, step = irInt(1), - canOverflow = false, - additionalVariables = listOfNotNull(boundVar), - additionalNotEmptyCondition = if (boundVar != null) buildMinValueCondition(data, irGet(boundVar)) else null + isLastInclusive = false, + canOverflow = false ) } - - /** Returns true (i.e., min value condition is needed) if `bound` is non-const OR is MIN_VALUE. */ - private fun needsMinValueCondition(progressionType: ProgressionType, bound: IrExpression): Boolean { - val boundValue = (bound as? IrConst<*>)?.value - val boundValueAsLong = when (boundValue) { - is Number -> boundValue.toLong() - is Char -> boundValue.toLong() - else -> return true // If "bound" is not a const Number or Char. - } - val minValueAsLong = when (progressionType) { - ProgressionType.INT_PROGRESSION -> Int.MIN_VALUE.toLong() - ProgressionType.CHAR_PROGRESSION -> Char.MIN_VALUE.toLong() - ProgressionType.LONG_PROGRESSION -> Long.MIN_VALUE - } - return minValueAsLong == boundValueAsLong - } - - private fun DeclarationIrBuilder.buildMinValueCondition(progressionType: ProgressionType, bound: IrExpression): IrExpression { - val irBuiltIns = context.irBuiltIns - val minConst = when (progressionType) { - ProgressionType.INT_PROGRESSION -> irInt(Int.MIN_VALUE) - ProgressionType.CHAR_PROGRESSION -> irChar(Char.MIN_VALUE) - ProgressionType.LONG_PROGRESSION -> irLong(Long.MIN_VALUE) - } - val progressionKotlinType = progressionType.elementType(irBuiltIns).toKotlinType() - return irCall(irBuiltIns.greaterFunByOperandType[progressionKotlinType]!!).apply { - putValueArgument(0, bound) - putValueArgument(1, minConst) - } - } } /** Builds a [HeaderInfo] for progressions built using the `indices` extension property. */ @@ -167,18 +100,18 @@ internal class IndicesHandler(val context: CommonBackendContext) : ProgressionHa override fun build(call: IrCall, data: ProgressionType): HeaderInfo? = with(context.createIrBuilder(call.symbol, call.startOffset, call.endOffset)) { - // `last = array.size - 1` for the loop `for (i in array.indices)`. + // `last = array.size` for the loop `for (i in array.indices)`. val arraySizeProperty = call.extensionReceiver!!.type.getClass()!!.properties.first { it.name.asString() == "size" } - val decFun = data.decFun(context.irBuiltIns) - val last = irCallOp(decFun.symbol, data.elementType(context.irBuiltIns), irCall(arraySizeProperty.getter!!).apply { + val last = irCall(arraySizeProperty.getter!!).apply { dispatchReceiver = call.extensionReceiver - }) + } ProgressionHeaderInfo( data, first = irInt(0), last = last, step = irInt(1), + isLastInclusive = false, canOverflow = false // Cannot overflow because `last` is at most MAX_VALUE - 1 ) } @@ -225,8 +158,6 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte /** Builds a [HeaderInfo] for arrays. */ internal class ArrayIterationHandler(private val context: CommonBackendContext) : HeaderInfoHandler { - private val intDecFun = ProgressionType.INT_PROGRESSION.decFun(context.irBuiltIns) - override val matcher = createIrCallMatcher { origin { it == IrStatementOrigin.FOR_LOOP_ITERATOR } // TODO: Support rare cases like `T : IntArray` @@ -255,11 +186,11 @@ internal class ArrayIterationHandler(private val context: CommonBackendContext) origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE ) - // `last = array.size - 1` for the loop `for (i in array.indices)`. + // `last = array.size` for the loop `for (i in array.indices)`. val arraySizeProperty = arrayReference.type.getClass()!!.properties.first { it.name.asString() == "size" } - val last = irCallOp(intDecFun.symbol, context.irBuiltIns.intType, irCall(arraySizeProperty.getter!!).apply { + val last = irCall(arraySizeProperty.getter!!).apply { dispatchReceiver = irGet(arrayReference) - }) + } ArrayHeaderInfo( first = irInt(0), @@ -268,14 +199,4 @@ internal class ArrayIterationHandler(private val context: CommonBackendContext) arrayVariable = arrayReference ) } -} - -private fun ProgressionType.decFun(builtIns: IrBuiltIns): IrFunction { - val symbol = - when (this) { - ProgressionType.INT_PROGRESSION -> builtIns.intClass - ProgressionType.LONG_PROGRESSION -> builtIns.longClass - ProgressionType.CHAR_PROGRESSION -> builtIns.charClass - } - return symbol.owner.functions.first { it.name.asString() == "dec" } } \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt new file mode 100644 index 00000000000..d4d195a083f --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in logged("start;", 4) downTo logged("end;", 1)) { + sum = sum * 10 + i + } + + assertEquals(4321, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt similarity index 57% rename from compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt index 1b816de9394..fae58fac6ae 100644 --- a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt @@ -5,15 +5,15 @@ import kotlin.test.* val log = StringBuilder() fun logged(message: String, value: Int) = - value.also { log.append(message) } + value.also { log.append(message) } fun box(): String { - var s = 0 - for (i in (logged("start;", 1) .. logged("end;", 2)).reversed()) { - s += i + var sum = 0 + for (i in logged("start;", 1)..logged("end;", 4)) { + sum = sum * 10 + i } - assertEquals(3, s) + assertEquals(1234, sum) assertEquals("start;end;", log.toString()) diff --git a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt similarity index 57% rename from compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt index 010af21f1d5..fad30bf9921 100644 --- a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt @@ -5,15 +5,15 @@ import kotlin.test.* val log = StringBuilder() fun logged(message: String, value: Int) = - value.also { log.append(message) } + value.also { log.append(message) } fun box(): String { - var s = 0 - for (i in (logged("start;", 2) downTo logged("end;", 1)).reversed()) { - s += i + var sum = 0 + for (i in (logged("start;", 4) downTo logged("end;", 1)).reversed()) { + sum = sum * 10 + i } - assertEquals(3, s) + assertEquals(1234, sum) assertEquals("start;end;", log.toString()) diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt new file mode 100644 index 00000000000..09b90f3f3e0 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in (logged("start;", 1)..logged("end;", 4)).reversed()) { + sum = sum * 10 + i + } + + assertEquals(4321, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt similarity index 57% rename from compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt rename to compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt index 0dac73ca202..2e1eb651377 100644 --- a/compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt @@ -5,15 +5,15 @@ import kotlin.test.* val log = StringBuilder() fun logged(message: String, value: Int) = - value.also { log.append(message) } + value.also { log.append(message) } fun box(): String { - var s = 0 - for (i in (logged("start;", 1) until logged("end;", 3)).reversed()) { - s += i + var sum = 0 + for (i in (logged("start;", 1) until logged("end;", 5)).reversed()) { + sum = sum * 10 + i } - assertEquals(3, s) + assertEquals(4321, sum) assertEquals("start;end;", log.toString()) diff --git a/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt new file mode 100644 index 00000000000..8864b09d443 --- /dev/null +++ b/compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt @@ -0,0 +1,21 @@ +// KJS_WITH_FULL_RUNTIME +// WITH_RUNTIME +import kotlin.test.* + +val log = StringBuilder() + +fun logged(message: String, value: Int) = + value.also { log.append(message) } + +fun box(): String { + var sum = 0 + for (i in logged("start;", 1) until logged("end;", 5)) { + sum = sum * 10 + i + } + + assertEquals(1234, sum) + + assertEquals("start;end;", log.toString()) + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt index bd08b8fc554..4ea36ceec8b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil.kt @@ -1,6 +1,6 @@ -fun test(): Int { +fun test(a: Int, b: Int): Int { var sum = 0 - for (i in 1 until 6) { + for (i in a until b) { sum = sum * 10 + i } return sum diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index d20f74cbe70..7c6f993bee7 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -18583,6 +18583,49 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/ranges/evaluationOrder") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EvaluationOrder extends AbstractBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInEvaluationOrder() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInDownToEvaluationOrder.kt") + public void testForInDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInRangeLiteralEvaluationOrder.kt") + public void testForInRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedDownToEvaluationOrder.kt") + public void testForInReversedDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") + public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedUntilEvaluationOrder.kt") + public void testForInReversedUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + } + + @TestMetadata("forInUntilEvaluationOrder.kt") + public void testForInUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -18958,34 +19001,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testForInReversedUntilWithNonConstBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInReversed/forInReversedUntilWithNonConstBounds.kt"); } - - @TestMetadata("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class EvaluationOrder extends AbstractBlackBoxCodegenTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); - } - - public void testAllFilesPresentInEvaluationOrder() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); - } - - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); - } - } } @TestMetadata("compiler/testData/codegen/box/ranges/forInUntil") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index a27e19e2174..ee5597cf827 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -18583,6 +18583,49 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/ranges/evaluationOrder") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EvaluationOrder extends AbstractLightAnalysisModeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); + } + + public void testAllFilesPresentInEvaluationOrder() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInDownToEvaluationOrder.kt") + public void testForInDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInRangeLiteralEvaluationOrder.kt") + public void testForInRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedDownToEvaluationOrder.kt") + public void testForInReversedDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") + public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedUntilEvaluationOrder.kt") + public void testForInReversedUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + } + + @TestMetadata("forInUntilEvaluationOrder.kt") + public void testForInUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -18958,34 +19001,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes public void testForInReversedUntilWithNonConstBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInReversed/forInReversedUntilWithNonConstBounds.kt"); } - - @TestMetadata("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class EvaluationOrder extends AbstractLightAnalysisModeTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); - } - - public void testAllFilesPresentInEvaluationOrder() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); - } - - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); - } - } } @TestMetadata("compiler/testData/codegen/box/ranges/forInUntil") diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index 4aed2a0238b..14dea039ed6 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -18588,6 +18588,49 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/ranges/evaluationOrder") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EvaluationOrder extends AbstractIrBlackBoxCodegenTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); + } + + public void testAllFilesPresentInEvaluationOrder() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); + } + + @TestMetadata("forInDownToEvaluationOrder.kt") + public void testForInDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInRangeLiteralEvaluationOrder.kt") + public void testForInRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedDownToEvaluationOrder.kt") + public void testForInReversedDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") + public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedUntilEvaluationOrder.kt") + public void testForInReversedUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + } + + @TestMetadata("forInUntilEvaluationOrder.kt") + public void testForInUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -18963,34 +19006,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes public void testForInReversedUntilWithNonConstBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInReversed/forInReversedUntilWithNonConstBounds.kt"); } - - @TestMetadata("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class EvaluationOrder extends AbstractIrBlackBoxCodegenTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM_IR, testDataFilePath); - } - - public void testAllFilesPresentInEvaluationOrder() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM_IR, true); - } - - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); - } - } } @TestMetadata("compiler/testData/codegen/box/ranges/forInUntil") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java index b2bd8439ad8..cf969dcbf1a 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/ir/semantics/IrJsCodegenBoxTestGenerated.java @@ -14643,6 +14643,49 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/ranges/evaluationOrder") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EvaluationOrder extends AbstractIrJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); + } + + public void testAllFilesPresentInEvaluationOrder() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); + } + + @TestMetadata("forInDownToEvaluationOrder.kt") + public void testForInDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInRangeLiteralEvaluationOrder.kt") + public void testForInRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedDownToEvaluationOrder.kt") + public void testForInReversedDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") + public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedUntilEvaluationOrder.kt") + public void testForInReversedUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + } + + @TestMetadata("forInUntilEvaluationOrder.kt") + public void testForInUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -15018,34 +15061,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest { public void testForInReversedUntilWithNonConstBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInReversed/forInReversedUntilWithNonConstBounds.kt"); } - - @TestMetadata("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class EvaluationOrder extends AbstractIrJsCodegenBoxTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS_IR, testDataFilePath); - } - - public void testAllFilesPresentInEvaluationOrder() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS_IR, true); - } - - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); - } - } } @TestMetadata("compiler/testData/codegen/box/ranges/forInUntil") diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java index ed7824e7348..63112efe47d 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/semantics/JsCodegenBoxTestGenerated.java @@ -15813,6 +15813,49 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/ranges/evaluationOrder") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class EvaluationOrder extends AbstractJsCodegenBoxTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); + } + + public void testAllFilesPresentInEvaluationOrder() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("forInDownToEvaluationOrder.kt") + public void testForInDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInRangeLiteralEvaluationOrder.kt") + public void testForInRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedDownToEvaluationOrder.kt") + public void testForInReversedDownToEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") + public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); + } + + @TestMetadata("forInReversedUntilEvaluationOrder.kt") + public void testForInReversedUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); + } + + @TestMetadata("forInUntilEvaluationOrder.kt") + public void testForInUntilEvaluationOrder() throws Exception { + runTest("compiler/testData/codegen/box/ranges/evaluationOrder/forInUntilEvaluationOrder.kt"); + } + } + @TestMetadata("compiler/testData/codegen/box/ranges/expression") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) @@ -16188,34 +16231,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { public void testForInReversedUntilWithNonConstBounds() throws Exception { runTest("compiler/testData/codegen/box/ranges/forInReversed/forInReversedUntilWithNonConstBounds.kt"); } - - @TestMetadata("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder") - @TestDataPath("$PROJECT_ROOT") - @RunWith(JUnit3RunnerWithInners.class) - public static class EvaluationOrder extends AbstractJsCodegenBoxTest { - private void runTest(String testDataFilePath) throws Exception { - KotlinTestUtils.runTest0(this::doTest, TargetBackend.JS, testDataFilePath); - } - - public void testAllFilesPresentInEvaluationOrder() throws Exception { - KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); - } - - @TestMetadata("forInReversedDownToEvaluationOrder.kt") - public void testForInReversedDownToEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedDownToEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedRangeLiteralEvaluationOrder.kt") - public void testForInReversedRangeLiteralEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedRangeLiteralEvaluationOrder.kt"); - } - - @TestMetadata("forInReversedUntilEvaluationOrder.kt") - public void testForInReversedUntilEvaluationOrder() throws Exception { - runTest("compiler/testData/codegen/box/ranges/forInReversed/evaluationOrder/forInReversedUntilEvaluationOrder.kt"); - } - } } @TestMetadata("compiler/testData/codegen/box/ranges/forInUntil")