Provide optimized code generation for for-in-withIndex for arrays

#KT-5177 In Progress
This commit is contained in:
Dmitry Petrov
2018-01-19 15:25:32 +03:00
parent e07e9c0ea5
commit 08622b0953
23 changed files with 664 additions and 9 deletions
@@ -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)
@@ -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<out CallableDescriptor>) :
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<out CallableDescriptor>
): ForLoopGenerator
override fun createInExpressionGenerator(codegen: ExpressionCodegen, operatorReference: KtSimpleNameExpression): InExpressionGenerator =
CallBasedInExpressionGenerator(codegen, operatorReference)
}
@@ -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<out CallableDescriptor>) : AbstractDestructuredPairRangeValue(rangeCall) {
override fun createDestructuredPairForLoopGenerator(
codegen: ExpressionCodegen,
forExpression: KtForExpression,
loopParameter: KtDestructuringDeclaration,
rangeCall: ResolvedCall<out CallableDescriptor>
): ForLoopGenerator =
ArrayWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall)
}
@@ -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) ->
@@ -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
@@ -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<out CallableDescriptor>
) : 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)
}
@@ -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<out CallableDescriptor>
) : 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)
}
}
@@ -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'"
}
@@ -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'"
}
@@ -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'"
}
@@ -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"
}
@@ -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'"
}
@@ -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'"
}
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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)
@@ -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)
@@ -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)
@@ -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)
@@ -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)