From 08622b0953207fdb978d90753fb0b88ac2da36ff Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 19 Jan 2018 15:25:32 +0300 Subject: [PATCH] Provide optimized code generation for for-in-withIndex for arrays #KT-5177 In Progress --- .../kotlin/codegen/RangeCodegenUtil.kt | 15 +++ .../AbstractDestructuredPairRangeValue.kt | 41 ++++++++ .../codegen/range/ArrayWithIndexRangeValue.kt | 28 ++++++ .../kotlin/codegen/range/RangeValues.kt | 2 + .../range/forLoop/AbstractForLoopGenerator.kt | 11 +-- .../AbstractWithIndexForLoopGenerator.kt | 97 +++++++++++++++++++ .../forLoop/ArrayWithIndexForLoopGenerator.kt | 73 ++++++++++++++ .../forInArrrayWithIndexNoElementVar.kt | 14 +++ .../forInArrrayWithIndexNoIndexVar.kt | 14 +++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 17 ++++ .../forInEmptyArrrayWithIndex.kt | 11 +++ .../forInIntArrrayWithIndex.kt | 12 +++ .../forInObjectArrrayWithIndex.kt | 14 +++ .../forInArrrayWithIndexNoElementVar.kt | 22 +++++ .../forInArrrayWithIndexNoIndexVar.kt | 22 +++++ .../forInEmptyArrrayWithIndex.kt | 19 ++++ .../forInIntArrrayWithIndex.kt | 20 ++++ .../forInObjectArrrayWithIndex.kt | 22 +++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 45 +++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 45 +++++++++ .../codegen/BytecodeTextTestGenerated.java | 39 ++++++++ .../LightAnalysisModeTestGenerated.java | 45 +++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 45 +++++++++ 23 files changed, 664 insertions(+), 9 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractDestructuredPairRangeValue.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayWithIndexRangeValue.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractWithIndexForLoopGenerator.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/ArrayWithIndexForLoopGenerator.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrrayWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrrayWithIndex.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt index c15ca1038b0..d04004f3d62 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt @@ -21,8 +21,11 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns.RANGES_PACKAGE_FQ_NAME import org.jetbrains.kotlin.builtins.PrimitiveType import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitiveNumberClassDescriptor import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.jvm.AsmTypes @@ -88,6 +91,13 @@ fun getRangeOrProgressionElementType(rangeType: KotlinType): KotlinType? { } } +fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType { + val loopRange = forExpression.loopRange!! + val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange) + ?: throw AssertionError("No next() function " + DiagnosticUtils.atLocation(loopRange)) + return nextCall.resultingDescriptor.returnType!! +} + fun getPrimitiveRangeOrProgressionElementType(rangeOrProgressionName: FqName): PrimitiveType? = RANGE_TO_ELEMENT_TYPE[rangeOrProgressionName] ?: PROGRESSION_TO_ELEMENT_TYPE[rangeOrProgressionName] @@ -128,6 +138,11 @@ fun isArrayOrPrimitiveArrayIndices(descriptor: CallableDescriptor) = KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it) } +fun isArrayOrPrimitiveArrayWithIndex(descriptor: CallableDescriptor) = + descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.collections") { + KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it) + } + fun isCollectionIndices(descriptor: CallableDescriptor) = descriptor.isTopLevelExtensionOnType("indices", "kotlin.collections") { KotlinBuiltIns.isCollectionOrNullableCollection(it) diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractDestructuredPairRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractDestructuredPairRangeValue.kt new file mode 100644 index 00000000000..27f44643ae5 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/AbstractDestructuredPairRangeValue.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator +import org.jetbrains.kotlin.codegen.range.forLoop.IteratorForLoopGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.CallBasedInExpressionGenerator +import org.jetbrains.kotlin.codegen.range.inExpression.InExpressionGenerator +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.psi.KtSimpleNameExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall + +abstract class AbstractDestructuredPairRangeValue(protected val rangeCall: ResolvedCall) : + RangeValue { + + override fun createForLoopGenerator(codegen: ExpressionCodegen, forExpression: KtForExpression): ForLoopGenerator { + val loopParameter = forExpression.destructuringDeclaration + return if (loopParameter != null) + createDestructuredPairForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) + else + IteratorForLoopGenerator(codegen, forExpression) + } + + protected abstract fun createDestructuredPairForLoopGenerator( + codegen: ExpressionCodegen, + forExpression: KtForExpression, + loopParameter: KtDestructuringDeclaration, + rangeCall: ResolvedCall + ): ForLoopGenerator + + override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator = + CallBasedInExpressionGenerator(codegen, operatorReference) +} + + diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayWithIndexRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayWithIndexRangeValue.kt new file mode 100644 index 00000000000..178b92f8d89 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/ArrayWithIndexRangeValue.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.range + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.range.forLoop.ArrayWithIndexForLoopGenerator +import org.jetbrains.kotlin.codegen.range.forLoop.ForLoopGenerator +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall + + +class ArrayWithIndexRangeValue(rangeCall: ResolvedCall) : AbstractDestructuredPairRangeValue(rangeCall) { + + override fun createDestructuredPairForLoopGenerator( + codegen: ExpressionCodegen, + forExpression: KtForExpression, + loopParameter: KtDestructuringDeclaration, + rangeCall: ResolvedCall + ): ForLoopGenerator = + ArrayWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) + +} + diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt index bdefbc23495..61a71a14fd2 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt @@ -126,6 +126,8 @@ private fun ExpressionCodegen.createIntrinsifiedRangeValueOrNull(rangeCall: Reso CollectionIndicesRangeValue(rangeCall) isCharSequenceIndices(rangeCallee) -> CharSequenceIndicesRangeValue(rangeCall) + isArrayOrPrimitiveArrayWithIndex(rangeCallee) -> + ArrayWithIndexRangeValue(rangeCall) isComparableRangeTo(rangeCallee) -> ComparableRangeLiteralRangeValue(this, rangeCall) isPrimitiveProgressionReverse(rangeCallee) -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractForLoopGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractForLoopGenerator.kt index c22cb7f8e96..bf134b60388 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractForLoopGenerator.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractForLoopGenerator.kt @@ -19,7 +19,7 @@ package org.jetbrains.kotlin.codegen.range.forLoop import org.jetbrains.kotlin.codegen.ExpressionCodegen import org.jetbrains.kotlin.codegen.StackValue import org.jetbrains.kotlin.codegen.filterOutDescriptorsWithSpecialNames -import org.jetbrains.kotlin.diagnostics.DiagnosticUtils +import org.jetbrains.kotlin.codegen.getElementType import org.jetbrains.kotlin.psi.KtDestructuringDeclaration import org.jetbrains.kotlin.psi.KtForExpression import org.jetbrains.kotlin.resolve.BindingContext @@ -30,7 +30,7 @@ import org.jetbrains.org.objectweb.asm.Type abstract class AbstractForLoopGenerator( protected val codegen: ExpressionCodegen, - override val forExpression: KtForExpression + final override val forExpression: KtForExpression ) : ForLoopGenerator { protected val bindingContext = codegen.bindingContext protected val v = codegen.v!! @@ -45,13 +45,6 @@ abstract class AbstractForLoopGenerator( protected var loopParameterVar: Int = -1 protected lateinit var loopParameterType: Type - private fun BindingContext.getElementType(forExpression: KtForExpression): KotlinType { - val loopRange = forExpression.loopRange!! - val nextCall = get(BindingContext.LOOP_RANGE_NEXT_RESOLVED_CALL, loopRange) - ?: throw AssertionError("No next() function " + DiagnosticUtils.atLocation(loopRange)) - return nextCall.resultingDescriptor.returnType!! - } - override fun beforeLoop() { val loopParameter = forExpression.loopParameter ?: return val multiParameter = loopParameter.destructuringDeclaration diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractWithIndexForLoopGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractWithIndexForLoopGenerator.kt new file mode 100644 index 00000000000..5feff036f80 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/AbstractWithIndexForLoopGenerator.kt @@ -0,0 +1,97 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.range.forLoop + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtDestructuringDeclarationEntry +import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.Type + +abstract class AbstractWithIndexForLoopGenerator( + protected val codegen: ExpressionCodegen, + final override val forExpression: KtForExpression, + protected val loopParameter: KtDestructuringDeclaration, + protected val rangeCall: ResolvedCall +) : ForLoopGenerator { + + protected val bindingContext = codegen.bindingContext + protected val v = codegen.v!! + + private val loopParameterStartLabel = Label() + private val bodyEnd = Label() + private val leaveTasks = arrayListOf<() -> Unit>() + + protected class LoopComponent(val parameterVar: Int, val parameterType: Type, val elementType: Type) + + protected val indexLoopComponent: LoopComponent? = loopParameter.entries.getOrNull(0)?.resolveLoopComponent() + protected val elementLoopComponent: LoopComponent? = loopParameter.entries.getOrNull(1)?.resolveLoopComponent() + + private fun KtDestructuringDeclarationEntry.resolveLoopComponent(): LoopComponent? { + val variableDescriptor = bindingContext[BindingContext.VARIABLE, this] + + if (variableDescriptor == null || variableDescriptor.name.isSpecial) return null + + val resolvedCall = bindingContext[BindingContext.COMPONENT_RESOLVED_CALL, this] ?: return null + + val elementType = codegen.asmType(resolvedCall.resultingDescriptor.returnType ?: return null) + + val parameterType = codegen.asmType(variableDescriptor.type) + val parameterVar = codegen.myFrameMap.enter(variableDescriptor, parameterType) + scheduleLeaveTask { + codegen.myFrameMap.leaveTemp(parameterType) + v.visitLocalVariable( + variableDescriptor.name.asString(), + parameterType.descriptor, null, + loopParameterStartLabel, bodyEnd, + parameterVar + ) + } + return LoopComponent(parameterVar, parameterType, elementType) + } + + protected fun scheduleLeaveTask(task: () -> Unit) { + leaveTasks.add(task) + } + + protected fun createLoopTempVariable(type: Type): Int { + val varIndex = codegen.myFrameMap.enterTemp(type) + scheduleLeaveTask { codegen.myFrameMap.leaveTemp(type) } + return varIndex + } + + + override fun beforeBody() { + assignLoopParametersNextValues() + v.mark(loopParameterStartLabel) + } + + override fun checkEmptyLoop(loopExit: Label) { + // do nothing + } + + override fun body() { + codegen.generateLoopBody(forExpression.body) + } + + override fun afterBody(loopExit: Label) { + codegen.markStartLineNumber(forExpression) + incrementAndCheckPostCondition(loopExit) + v.mark(bodyEnd) + } + + override fun afterLoop() { + for (task in leaveTasks.asReversed()) task() + } + + protected abstract fun assignLoopParametersNextValues() + protected abstract fun incrementAndCheckPostCondition(loopExit: Label) + +} \ No newline at end of file diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/ArrayWithIndexForLoopGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/ArrayWithIndexForLoopGenerator.kt new file mode 100644 index 00000000000..e7d0b402642 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/ArrayWithIndexForLoopGenerator.kt @@ -0,0 +1,73 @@ +/* + * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.codegen.range.forLoop + +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.StackValue +import org.jetbrains.kotlin.codegen.generateCallReceiver +import org.jetbrains.kotlin.codegen.range.forLoop.AbstractWithIndexForLoopGenerator +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.psi.KtDestructuringDeclaration +import org.jetbrains.kotlin.psi.KtForExpression +import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall +import org.jetbrains.kotlin.resolve.jvm.AsmTypes +import org.jetbrains.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.Type + +class ArrayWithIndexForLoopGenerator( + codegen: ExpressionCodegen, + forExpression: KtForExpression, + loopParameter: KtDestructuringDeclaration, + rangeCall: ResolvedCall +) : AbstractWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) { + + private val arrayType = codegen.asmType(ExpressionCodegen.getExpectedReceiverType(rangeCall)) + private var arrayVar = -1 + private var arrayLengthVar = -1 + + private var indexVar = -1 + private var indexType = Type.INT_TYPE + + override fun beforeLoop() { + arrayVar = createLoopTempVariable(arrayType) + + arrayLengthVar = createLoopTempVariable(Type.INT_TYPE) + + indexVar = indexLoopComponent?.parameterVar ?: createLoopTempVariable(Type.INT_TYPE) + indexType = indexLoopComponent?.parameterType ?: Type.INT_TYPE + + val arrayValue = StackValue.local(arrayVar, arrayType) + arrayValue.store(codegen.generateCallReceiver(rangeCall), v) + + arrayValue.put(arrayType, v) + v.arraylength() + v.store(arrayLengthVar, Type.INT_TYPE) + + StackValue.local(indexVar, indexType) + .store(StackValue.constant(0, Type.INT_TYPE), v) + } + + override fun checkPreCondition(loopExit: Label) { + StackValue.local(indexVar, indexType) + .put(Type.INT_TYPE, v) + v.load(arrayLengthVar, Type.INT_TYPE) + v.ificmpge(loopExit) + } + + override fun assignLoopParametersNextValues() { + if (elementLoopComponent != null) { + v.load(arrayVar, AsmTypes.OBJECT_TYPE) + v.load(indexVar, Type.INT_TYPE) + v.aload(elementLoopComponent.elementType) + StackValue.local(elementLoopComponent.parameterVar, elementLoopComponent .parameterType) + .store(StackValue.onStack(elementLoopComponent .elementType), v) + } + } + + override fun incrementAndCheckPostCondition(loopExit: Label) { + v.iinc(indexVar, 1) + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt new file mode 100644 index 00000000000..3e1960de238 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((i, _) in arr.withIndex()) { + s.append("$i;") + } + + val ss = s.toString() + return if (ss == "0;1;2;3;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt new file mode 100644 index 00000000000..a62b7a28345 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((_, x) in arr.withIndex()) { + s.append("$x;") + } + + val ss = s.toString() + return if (ss == "a;b;c;d;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt new file mode 100644 index 00000000000..5ba7716f540 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun useAny(x: Any) {} + +fun box(): String { + val s = StringBuilder() + + for ((index: Any, x) in arr.withIndex()) { + useAny(index) + s.append("$index:$x;") + } + + val ss = s.toString() + return if (ss == "0:a;1:b;2:c;3:d;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt new file mode 100644 index 00000000000..b95ed235fe0 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt @@ -0,0 +1,11 @@ +// WITH_RUNTIME + +val arr = intArrayOf() + +fun box(): String { + val s = StringBuilder() + for ((index, x) in arr.withIndex()) { + return "Loop over empty array should not be executed" + } + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt new file mode 100644 index 00000000000..09df87d740b --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +val arr = intArrayOf(10, 20, 30, 40) + +fun box(): String { + val s = StringBuilder() + for ((index, x) in arr.withIndex()) { + s.append("$index:$x;") + } + val ss = s.toString() + return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt new file mode 100644 index 00000000000..87b7f2c8cfe --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in arr.withIndex()) { + s.append("$index:$x;") + } + + val ss = s.toString() + return if (ss == "0:a;1:b;2:c;3:d;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt new file mode 100644 index 00000000000..65ed573b8f4 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((i, _) in arr.withIndex()) { + s.append("$i;") + } + + val ss = s.toString() + return if (ss == "0;1;2;3;") "OK" else "fail: '$ss'" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 ARRAYLENGTH \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt new file mode 100644 index 00000000000..b9281c40db9 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((_, x) in arr.withIndex()) { + s.append("$x;") + } + + val ss = s.toString() + return if (ss == "a;b;c;d;") "OK" else "fail: '$ss'" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 ARRAYLENGTH \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt new file mode 100644 index 00000000000..0110498e519 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt @@ -0,0 +1,19 @@ +// WITH_RUNTIME + +val arr = intArrayOf() + +fun box(): String { + val s = StringBuilder() + for ((index, x) in arr.withIndex()) { + return "Loop over empty array should not be executed" + } + return "OK" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 ARRAYLENGTH \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrrayWithIndex.kt new file mode 100644 index 00000000000..e4f07d19361 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrrayWithIndex.kt @@ -0,0 +1,20 @@ +// WITH_RUNTIME + +val arr = intArrayOf(10, 20, 30, 40) + +fun box(): String { + val s = StringBuilder() + for ((index, x) in arr.withIndex()) { + s.append("$index:$x;") + } + val ss = s.toString() + return if (ss == "0:10;1:20;2:30;3:40;") "OK" else "fail: '$ss'" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 ARRAYLENGTH \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrrayWithIndex.kt new file mode 100644 index 00000000000..e7df8239c33 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrrayWithIndex.kt @@ -0,0 +1,22 @@ +// WITH_RUNTIME + +val arr = arrayOf("a", "b", "c", "d") + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in arr.withIndex()) { + s.append("$index:$x;") + } + + val ss = s.toString() + return if (ss == "0:a;1:b;2:c;3:d;") "OK" else "fail: '$ss'" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 ARRAYLENGTH \ No newline at end of file diff --git a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java index a145fba6bc7..5c3509cc4d0 100644 --- a/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-ir-jvm/tests/org/jetbrains/kotlin/codegen/ir/IrBlackBoxCodegenTestGenerated.java @@ -5178,6 +5178,51 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInArrayWithIndex extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInForInArrayWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInArrrayWithIndexNoElementVar.kt") + public void testForInArrrayWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexNoIndexVar.kt") + public void testForInArrrayWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInArrrayWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyArrrayWithIndex.kt") + public void testForInEmptyArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInIntArrrayWithIndex.kt") + public void testForInIntArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInObjectArrrayWithIndex.kt") + public void testForInObjectArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/returnsNothing") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 7dec6bd70c0..9237b06e282 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5178,6 +5178,51 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInArrayWithIndex extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInForInArrayWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInArrrayWithIndexNoElementVar.kt") + public void testForInArrrayWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexNoIndexVar.kt") + public void testForInArrrayWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInArrrayWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyArrrayWithIndex.kt") + public void testForInEmptyArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInIntArrrayWithIndex.kt") + public void testForInIntArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInObjectArrrayWithIndex.kt") + public void testForInObjectArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/returnsNothing") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java index 56534bb0041..cca83afb5e5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1368,6 +1368,45 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { doTest(fileName); } + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInArrayWithIndex extends AbstractBytecodeTextTest { + public void testAllFilesPresentInForInArrayWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("forInArrrayWithIndexNoElementVar.kt") + public void testForInArrrayWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexNoIndexVar.kt") + public void testForInArrrayWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyArrrayWithIndex.kt") + public void testForInEmptyArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInIntArrrayWithIndex.kt") + public void testForInIntArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInObjectArrrayWithIndex.kt") + public void testForInObjectArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrrayWithIndex.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInIndices") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 9b5c6b12b84..9407e571f9b 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5178,6 +5178,51 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInArrayWithIndex extends AbstractLightAnalysisModeTest { + public void testAllFilesPresentInForInArrayWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInArrrayWithIndexNoElementVar.kt") + public void testForInArrrayWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexNoIndexVar.kt") + public void testForInArrrayWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInArrrayWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyArrrayWithIndex.kt") + public void testForInEmptyArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInIntArrrayWithIndex.kt") + public void testForInIntArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInObjectArrrayWithIndex.kt") + public void testForInObjectArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/returnsNothing") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) 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 7cc460cb969..9b599b46aac 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 @@ -5760,6 +5760,51 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInArrayWithIndex extends AbstractJsCodegenBoxTest { + public void testAllFilesPresentInForInArrayWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("forInArrrayWithIndexNoElementVar.kt") + public void testForInArrrayWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexNoIndexVar.kt") + public void testForInArrrayWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInArrrayWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInArrrayWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyArrrayWithIndex.kt") + public void testForInEmptyArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInEmptyArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInIntArrrayWithIndex.kt") + public void testForInIntArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInIntArrrayWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInObjectArrrayWithIndex.kt") + public void testForInObjectArrrayWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInArrayWithIndex/forInObjectArrrayWithIndex.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/returnsNothing") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)