Provide optimized code generation for for-in-withIndex for arrays
#KT-5177 In Progress
This commit is contained in:
@@ -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)
|
||||
|
||||
+41
@@ -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) ->
|
||||
|
||||
+2
-9
@@ -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
|
||||
|
||||
+97
@@ -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)
|
||||
|
||||
}
|
||||
+73
@@ -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)
|
||||
}
|
||||
}
|
||||
+14
@@ -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'"
|
||||
}
|
||||
+14
@@ -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'"
|
||||
}
|
||||
+17
@@ -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'"
|
||||
}
|
||||
Vendored
+11
@@ -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"
|
||||
}
|
||||
Vendored
+12
@@ -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'"
|
||||
}
|
||||
Vendored
+14
@@ -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'"
|
||||
}
|
||||
+22
@@ -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
|
||||
compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrrayWithIndexNoIndexVar.kt
Vendored
+22
@@ -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
|
||||
Vendored
+19
@@ -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
|
||||
Vendored
+20
@@ -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
|
||||
Vendored
+22
@@ -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
|
||||
Generated
+45
@@ -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)
|
||||
|
||||
+45
@@ -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)
|
||||
|
||||
+45
@@ -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)
|
||||
|
||||
+45
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user