JVM_IR reuse loop variable as index variable should happen after LDL

We can't apply "reuse loop variable as index variable" transformation
before local declarations lowering, otherwise it will affect captured
loop variable behavior, resulting in KT-48626.

Since it's JVM-specific, move it to JvmOptimizationLowering.
This commit is contained in:
Dmitry Petrov
2021-09-06 16:42:02 +03:00
committed by TeamCityServer
parent f62ffeaa0a
commit d9e4dec810
19 changed files with 445 additions and 133 deletions
@@ -8763,12 +8763,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@Test
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@Test
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
@@ -30144,6 +30156,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@Test
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
@@ -31221,6 +31239,24 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@Test
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@Test
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@Test
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@Test
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
@@ -56,9 +56,6 @@ interface CommonBackendContext : BackendContext, LoggingContext {
val preferJavaLikeCounterLoop: Boolean
get() = false
val reuseLoopVariableAsInductionVariable: Boolean
get() = false
val doWhileCounterLoopOrigin: IrStatementOrigin?
get() = null
@@ -8,18 +8,16 @@ package org.jetbrains.kotlin.backend.common.lower.loops
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.lower.AbstractVariableRemapper
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.classifierOrNull
import org.jetbrains.kotlin.ir.types.isNullable
import org.jetbrains.kotlin.ir.util.dump
import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.ir.visitors.*
@@ -190,102 +188,9 @@ private class RangeLoopTransformer(
statements[0] = loweredHeader
statements[1] = loopReplacementExpression
if (context.reuseLoopVariableAsInductionVariable && loopHeader.canReuseLoopVariableAsInductionVariable) {
reuseLoopVariableAsInductionVariable(expression)
}
return super.visitBlock(expression)
}
private fun reuseLoopVariableAsInductionVariable(irBlock: IrBlock) {
// Given a loop in the form:
// {
// var inductionVariable = <start>
// }
// do {
// if (!(<whileLoopCondition>)) break
// val loopVariable = inductionVariable
// <originalLoopBody>
// } while ( { inductionVariable += <step>; true } )
// replace it with:
// {
// var loopVariable' = <start>
// }
// do {
// if (!(<whileLoopCondition'>)) break
// <originalLoopBody'>
// } while ( { loopVariable' += <step>; true } )
// where whenLoopCondition' and originalLoopBody' are corresponding statements
// with inductionVariable and loopVariable remapped to loopVariable'.
//
// NB we can do so only with a do-while counter loop as described above,
// otherwise it changes semantics of 'continue' inside the loop.
val header = irBlock.statements[0] as? IrStatementContainer ?: return
val inductionVariableIndex = header.statements.indexOfFirst { it.isInductionVariable(context) }
if (inductionVariableIndex < 0) return
val inductionVariable = header.statements[inductionVariableIndex] as IrVariable
val innerLoop = findInnerDoWhileLoop(irBlock.statements[1]) ?: return
if (innerLoop.origin != context.doWhileCounterLoopOrigin) return
val loopVariableContainerAndIndex = findLoopVariable(innerLoop) ?: return
val (loopVariableContainer, loopVariableIndex) = loopVariableContainerAndIndex
val loopVariable = loopVariableContainer.statements[loopVariableIndex] as IrVariable
val inductionVariableType = inductionVariable.type
val loopVariableType = loopVariable.type
if (loopVariableType.isNullable()) return
if (loopVariableType.classifierOrNull != inductionVariableType.classifierOrNull) return
val newLoopVariable = IrVariableImpl(
loopVariable.startOffset, loopVariable.endOffset, loopVariable.origin,
IrVariableSymbolImpl(),
loopVariable.name, loopVariableType,
isVar = true, // NB original loop variable is 'val'
isConst = false, isLateinit = false
)
newLoopVariable.initializer = inductionVariable.initializer
header.statements[inductionVariableIndex] = newLoopVariable
loopVariableContainer.statements.removeAt(loopVariableIndex)
val remapper = object : AbstractVariableRemapper() {
override fun remapVariable(value: IrValueDeclaration): IrValueDeclaration? =
if (value == inductionVariable || value == loopVariable) newLoopVariable else null
}
irBlock.statements[1].transformChildren(remapper, null)
}
private fun findInnerDoWhileLoop(statement: IrStatement): IrDoWhileLoop? {
if (statement is IrDoWhileLoop) {
return statement
}
if (statement is IrWhen) {
val branch0Result = statement.branches[0].result
if (branch0Result is IrDoWhileLoop)
return branch0Result
}
return null
}
private fun findLoopVariable(doWhileLoop: IrDoWhileLoop): Pair<IrContainerExpression, Int>? {
val loopBody = doWhileLoop.body as? IrContainerExpression ?: return null
for ((index, statement) in loopBody.statements.withIndex()) {
if (statement.isLoopVariable())
return Pair(loopBody, index)
else if (statement is IrContainerExpression && statement.origin == IrStatementOrigin.FOR_LOOP_NEXT) {
val loopVarIndex = statement.statements.indexOfFirst { it.isLoopVariable() }
if (loopVarIndex < 0) return null
return Pair(statement, loopVarIndex)
}
}
return null
}
private fun IrStatement.isLoopVariable() =
this is IrVariable && origin == IrDeclarationOrigin.FOR_LOOP_VARIABLE
/**
* Lowers the "header" statement that stores the iterator into the loop variable
* (e.g., `val it = someIterable.iterator()`) and gather information for building the for-loop
@@ -44,10 +44,6 @@ interface ForLoopHeader {
*/
val consumesLoopVariableComponents: Boolean
/** `true` if it's possible to use loop variable as induction variable in this kind of loop */
val canReuseLoopVariableAsInductionVariable: Boolean
get() = false
/** Statements used to initialize an iteration of the loop (e.g., assign loop variable). */
fun initializeIteration(
loopVariable: IrVariable?,
@@ -62,7 +58,7 @@ interface ForLoopHeader {
internal const val inductionVariableName = "inductionVariable"
internal fun IrStatement.isInductionVariable(context: CommonBackendContext) =
fun IrStatement.isInductionVariable(context: CommonBackendContext) =
this is IrVariable &&
origin == context.inductionVariableOrigin &&
name.asString() == inductionVariableName
@@ -75,8 +71,6 @@ abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
override val consumesLoopVariableComponents = false
override val canReuseLoopVariableAsInductionVariable get() = true
val inductionVariable: IrVariable
protected val stepVariable: IrVariable?
@@ -445,51 +439,56 @@ class ProgressionLoopHeader(
): LoopReplacement {
// Transform loop:
// while (<newLoopCondition>) {
// {
// <loopVarAssignments>
// inductionVariable += step
// { // FOR_LOOP_NEXT
// <initializeLoopIteration>
// <inductionVariableUpdate>
// }
// <originalLoopBody>
// }
// to:
// do {
// if (!(<newLoopCondition>)) break
// val forLoopVariable = inductionVariable
// { // FOR_LOOP_NEXT
// if (!(<newLoopCondition>)) break
// <initializeLoopIteration>
// }
// <originalLoopBody>
// } while ( { inductionVariable += step; true } )
// } while (
// {
// <inductionVariableUpdate>
// true
// }
// )
val bodyBlock = newBody as? IrContainerExpression
?: throw AssertionError("newBody: ${newBody?.dump()}")
val forLoopNextBlock = bodyBlock.statements[0] as? IrContainerExpression
?: throw AssertionError("bodyBlock[0]: ${bodyBlock.statements[0].dump()}")
if (forLoopNextBlock.origin != IrStatementOrigin.FOR_LOOP_NEXT)
throw AssertionError("FOR_LOOP_NEXT expected: ${forLoopNextBlock.dump()}")
val loopStep = forLoopNextBlock.statements.last() as? IrSetValue
val inductionVariableUpdate = forLoopNextBlock.statements.last() as? IrSetValue
?: throw AssertionError("forLoopNextBlock.last: ${forLoopNextBlock.statements.last().dump()}")
val doWhileLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, context.doWhileCounterLoopOrigin)
doWhileLoop.label = oldLoop.label
val negatedConditionCheck = createNegatedConditionCheck(newLoopCondition, doWhileLoop)
bodyBlock.statements[0] = IrCompositeImpl(
forLoopNextBlock.startOffset, forLoopNextBlock.endOffset,
forLoopNextBlock.type,
forLoopNextBlock.origin,
).apply {
statements.add(createNegatedConditionCheck(newLoopCondition, doWhileLoop))
if (forLoopNextBlock.statements.size >= 2)
statements.addAll(forLoopNextBlock.statements.subList(0, forLoopNextBlock.statements.lastIndex))
}
bodyBlock.statements[0] = negatedConditionCheck
val loopVarAssignments =
if (forLoopNextBlock.statements.size == 2)
forLoopNextBlock.statements[0]
else
IrCompositeImpl(
forLoopNextBlock.startOffset, forLoopNextBlock.endOffset, forLoopNextBlock.type, null,
forLoopNextBlock.statements.subList(0, forLoopNextBlock.statements.lastIndex)
)
bodyBlock.statements.add(1, loopVarAssignments)
doWhileLoop.body = bodyBlock
val stepStartOffset = loopStep.startOffset
val stepEndOffset = loopStep.endOffset
val stepStartOffset = inductionVariableUpdate.startOffset
val stepEndOffset = inductionVariableUpdate.endOffset
val doWhileCondition =
IrCompositeImpl(
stepStartOffset, stepEndOffset, context.irBuiltIns.booleanType, null,
listOf(
loopStep,
inductionVariableUpdate,
IrConstImpl.boolean(stepStartOffset, stepEndOffset, context.irBuiltIns.booleanType, true)
)
)
@@ -218,9 +218,6 @@ class JvmBackendContext(
override val preferJavaLikeCounterLoop: Boolean
get() = true
override val reuseLoopVariableAsInductionVariable: Boolean
get() = true
override val doWhileCounterLoopOrigin: IrStatementOrigin
get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP
@@ -6,22 +6,27 @@
package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.AbstractVariableRemapper
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlock
import org.jetbrains.kotlin.backend.common.lower.loops.isInductionVariable
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.codegen.AsmUtil
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
@@ -410,11 +415,77 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
expression.rewritePostfixIncrDecr()?.let { return it }
}
if (expression.origin == IrStatementOrigin.FOR_LOOP) {
reuseLoopVariableAsInductionVariableIfPossible(expression)
}
expression.transformChildren(this, data)
removeUnnecessaryTemporaryVariables(expression.statements)
return expression
}
private fun reuseLoopVariableAsInductionVariableIfPossible(irForLoopBlock: IrContainerExpression) {
if (irForLoopBlock.statements.size != 2) return
val loopInitialization = irForLoopBlock.statements[0] as? IrComposite ?: return
val inductionVariableIndex = loopInitialization.statements.indexOfFirst { it.isInductionVariable(context) }
if (inductionVariableIndex < 0) return
val inductionVariable = loopInitialization.statements[inductionVariableIndex] as? IrVariable ?: return
val loopVariablePosition = findLoopVariablePosition(irForLoopBlock.statements[1]) ?: return
val (loopVariableContainer, loopVariableIndex) = loopVariablePosition
val loopVariable = loopVariableContainer.statements[loopVariableIndex] as? IrVariable ?: return
val inductionVariableType = inductionVariable.type
val loopVariableType = loopVariable.type
if (loopVariableType.isNullable()) return
if (loopVariableType.classifierOrNull != inductionVariableType.classifierOrNull) return
val newLoopVariable = IrVariableImpl(
loopVariable.startOffset, loopVariable.endOffset, loopVariable.origin,
IrVariableSymbolImpl(),
loopVariable.name, loopVariableType,
isVar = true, // NB original loop variable is 'val'
isConst = false, isLateinit = false
)
newLoopVariable.initializer = inductionVariable.initializer
loopInitialization.statements[inductionVariableIndex] = newLoopVariable
loopVariableContainer.statements.removeAt(loopVariableIndex)
val remapper = object : AbstractVariableRemapper() {
override fun remapVariable(value: IrValueDeclaration): IrValueDeclaration? =
if (value == inductionVariable || value == loopVariable) newLoopVariable else null
}
irForLoopBlock.statements[1].transformChildren(remapper, null)
}
private fun findLoopVariablePosition(statement: IrStatement): Pair<IrContainerExpression, Int>? {
when (statement) {
is IrDoWhileLoop -> {
// Expecting counter loop
val doWhileLoop = statement as? IrDoWhileLoop ?: return null
if (doWhileLoop.origin != JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP) return null
val doWhileLoopBody = doWhileLoop.body as? IrComposite ?: return null
if (doWhileLoopBody.origin != IrStatementOrigin.FOR_LOOP_INNER_WHILE) return null
val iterationInitialization = doWhileLoopBody.statements[0] as? IrComposite ?: return null
val loopVariableIndex = iterationInitialization.statements.indexOfFirst { it.isLoopVariable() }
if (loopVariableIndex < 0) return null
return iterationInitialization to loopVariableIndex
}
is IrWhen -> {
// Expecting if-guarded counter loop
val doWhileLoop = statement.branches[0].result as? IrDoWhileLoop ?: return null
return findLoopVariablePosition(doWhileLoop)
}
else -> {
return null
}
}
}
private fun IrStatement.isLoopVariable() =
this is IrVariable && origin == IrDeclarationOrigin.FOR_LOOP_VARIABLE
private fun IrContainerExpression.rewritePostfixIncrDecr(): IrCall? {
return when (origin) {
IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR -> {
@@ -0,0 +1,19 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: STDLIB_GENERATED
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun test(xs: List<String>): String {
var r = ""
for ((i, x) in xs.withIndex()) {
if (i > 1) break
r += "$i:$x;"
}
return r
}
fun box(): String {
val t = test(listOf("a", "b", "c", "d", "e"))
if (t != "0:a;1:b;") return "Failed: $t"
return "OK"
}
@@ -0,0 +1,19 @@
// DONT_TARGET_EXACT_BACKEND: WASM
// WASM_MUTE_REASON: STDLIB_GENERATED
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun test(xs: List<String>): String {
var r = ""
for ((i, x) in xs.withIndex()) {
if (i % 2 == 0) continue
r += "$i:$x;"
}
return r
}
fun box(): String {
val t = test(listOf("a", "b", "c", "d", "e"))
if (t != "1:b;3:d;") return "Failed: $t"
return "OK"
}
+16
View File
@@ -0,0 +1,16 @@
// IGNORE_BACKEND: WASM
// WITH_RUNTIME
fun build(): List<() -> Int> {
val r = ArrayList<() -> Int>()
for (i in 0 until 3) {
r.add({ i })
}
return r
}
fun box(): String {
val t = build().map { it() }
if (t != listOf(0, 1, 2)) return "Failed: $t"
return "OK"
}
@@ -0,0 +1,13 @@
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun test(xs: List<String>): String {
var r = ""
for (i in xs.indices) {
r += xs[i]
}
return r
}
fun box(): String =
test(listOf("OK"))
@@ -0,0 +1,14 @@
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun test(xs: List<String>): String {
var r = ""
for (i in xs.indices) {
if (i > 1) break
r += xs[i]
}
return r
}
fun box(): String =
test(listOf("O", "K", "2", "3", "4"))
@@ -0,0 +1,14 @@
// KJS_WITH_FULL_RUNTIME
// WITH_RUNTIME
fun test(xs: List<String>): String {
var r = ""
for (i in xs.indices) {
if (i % 2 == 0) continue
r += xs[i]
}
return r
}
fun box(): String =
test(listOf("0", "O", "2", "K", "4"))
@@ -8691,12 +8691,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@Test
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@Test
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
@@ -30018,6 +30030,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
}
@Test
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@Test
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
@@ -31095,6 +31113,24 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@Test
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@Test
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@Test
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@Test
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
@@ -8763,12 +8763,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@Test
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@Test
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@Test
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
@@ -30144,6 +30156,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@Test
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
@@ -31221,6 +31239,24 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@Test
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@Test
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@Test
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@Test
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
@@ -6732,11 +6732,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexNoElementVar.kt");
@@ -25546,6 +25556,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true, "stepped");
}
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forByteProgressionWithIntIncrement.kt");
@@ -26485,6 +26500,21 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInNonOptimizedIndices.kt");
@@ -5976,11 +5976,21 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexNoElementVar.kt");
@@ -20210,6 +20220,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR_ES6, true);
}
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forByteProgressionWithIntIncrement.kt");
@@ -21144,6 +21159,21 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInNonOptimizedIndices.kt");
@@ -5382,11 +5382,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexNoElementVar.kt");
@@ -19616,6 +19626,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
}
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forByteProgressionWithIntIncrement.kt");
@@ -20550,6 +20565,21 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInNonOptimizedIndices.kt");
@@ -5362,11 +5362,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndex.kt");
}
@TestMetadata("forInListWithIndexBreak.kt")
public void testForInListWithIndexBreak() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreak.kt");
}
@TestMetadata("forInListWithIndexBreakAndContinue.kt")
public void testForInListWithIndexBreakAndContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexBreakAndContinue.kt");
}
@TestMetadata("forInListWithIndexContinue.kt")
public void testForInListWithIndexContinue() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexContinue.kt");
}
@TestMetadata("forInListWithIndexNoElementVar.kt")
public void testForInListWithIndexNoElementVar() throws Exception {
runTest("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex/forInListWithIndexNoElementVar.kt");
@@ -19646,6 +19656,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forByteProgressionWithIntIncrement.kt");
@@ -20580,6 +20595,21 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInNonOptimizedIndices.kt");
@@ -12647,6 +12647,11 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/ranges"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true, "stepped/unsigned");
}
@TestMetadata("capturedLoopVar.kt")
public void testCapturedLoopVar() throws Exception {
runTest("compiler/testData/codegen/box/ranges/capturedLoopVar.kt");
}
@TestMetadata("forByteProgressionWithIntIncrement.kt")
public void testForByteProgressionWithIntIncrement() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forByteProgressionWithIntIncrement.kt");
@@ -13071,6 +13076,21 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInCollectionTypeParameterIndices.kt");
}
@TestMetadata("forInListIndices.kt")
public void testForInListIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndices.kt");
}
@TestMetadata("forInListIndicesBreak.kt")
public void testForInListIndicesBreak() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesBreak.kt");
}
@TestMetadata("forInListIndicesContinue.kt")
public void testForInListIndicesContinue() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInListIndicesContinue.kt");
}
@TestMetadata("forInNonOptimizedIndices.kt")
public void testForInNonOptimizedIndices() throws Exception {
runTest("compiler/testData/codegen/box/ranges/forInIndices/forInNonOptimizedIndices.kt");