From 2399a39414b02d32c784ad343136fc5f504de12d Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Fri, 19 Jan 2018 17:29:43 +0300 Subject: [PATCH] Provide optimized code generation for for-in-withIndex for CharSequences #KT-5177 In Progress --- .../kotlin/codegen/RangeCodegenUtil.kt | 16 ++-- .../range/CharSequenceWithIndexRangeValue.kt | 35 ++++++++ .../kotlin/codegen/range/RangeValues.kt | 2 + .../CharSequenceWithIndexForLoopGenerator.kt | 80 +++++++++++++++++++ .../forInCharSeqWithIndexStops.kt | 16 ++++ .../forInCharSequenceWithIndex.kt | 14 ++++ .../forInEmptyStringWithIndex.kt | 8 ++ .../forInStringWithIndex.kt | 12 +++ .../forInStringWithIndexNoElementVar.kt | 14 ++++ .../forInStringWithIndexNoIndexVar.kt | 14 ++++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 17 ++++ .../forInCharSequenceWithIndex.kt | 23 ++++++ .../forInEmptyStringWithIndex.kt | 17 ++++ .../forInStringWithIndex.kt | 21 +++++ .../forInStringWithIndexNoElementVar.kt | 23 ++++++ .../forInStringWithIndexNoIndexVar.kt | 23 ++++++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 26 ++++++ .../ir/IrBlackBoxCodegenTestGenerated.java | 51 ++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 51 ++++++++++++ .../codegen/BytecodeTextTestGenerated.java | 45 +++++++++++ .../LightAnalysisModeTestGenerated.java | 51 ++++++++++++ .../semantics/JsCodegenBoxTestGenerated.java | 57 +++++++++++++ 22 files changed, 610 insertions(+), 6 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceWithIndexRangeValue.kt create mode 100644 compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/CharSequenceWithIndexForLoopGenerator.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt create mode 100644 compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt create mode 100644 compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt index d54f4fb2b44..72183896520 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/RangeCodegenUtil.kt @@ -143,22 +143,26 @@ fun isArrayOrPrimitiveArrayWithIndex(descriptor: CallableDescriptor) = KotlinBuiltIns.isArray(it) || KotlinBuiltIns.isPrimitiveArray(it) } -fun isIterableWithIndex(descriptor: CallableDescriptor) = - descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.collections") { - val typeDescriptor = it.constructor.declarationDescriptor ?: return false - isTopLevelInPackage(typeDescriptor, "Iterable", "kotlin.collections") - } - fun isCollectionIndices(descriptor: CallableDescriptor) = descriptor.isTopLevelExtensionOnType("indices", "kotlin.collections") { KotlinBuiltIns.isCollectionOrNullableCollection(it) } +fun isIterableWithIndex(descriptor: CallableDescriptor) = + descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.collections") { + KotlinBuiltIns.isIterableOrNullableIterable(it) + } + fun isCharSequenceIndices(descriptor: CallableDescriptor) = descriptor.isTopLevelExtensionOnType("indices", "kotlin.text") { KotlinBuiltIns.isCharSequenceOrNullableCharSequence(it) } +fun isCharSequenceWithIndex(descriptor: CallableDescriptor) = + descriptor.isTopLevelExtensionOnType("withIndex", "kotlin.text") { + KotlinBuiltIns.isCharSequenceOrNullableCharSequence(it) + } + fun isComparableRangeTo(descriptor: CallableDescriptor) = descriptor.isTopLevelExtensionOnType("rangeTo", "kotlin.ranges") { val extensionReceiverTypeDescriptor = it.constructor.declarationDescriptor as? TypeParameterDescriptor ?: return false diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceWithIndexRangeValue.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceWithIndexRangeValue.kt new file mode 100644 index 00000000000..1ee22f04ef7 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/CharSequenceWithIndexRangeValue.kt @@ -0,0 +1,35 @@ +/* + * 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.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.codegen.ExpressionCodegen +import org.jetbrains.kotlin.codegen.range.forLoop.CharSequenceWithIndexForLoopGenerator +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 CharSequenceWithIndexRangeValue(rangeCall: ResolvedCall) : AbstractDestructuredPairRangeValue(rangeCall) { + + override fun createDestructuredPairForLoopGenerator( + codegen: ExpressionCodegen, + forExpression: KtForExpression, + loopParameter: KtDestructuringDeclaration, + rangeCall: ResolvedCall + ): ForLoopGenerator = + CharSequenceWithIndexForLoopGenerator( + codegen, forExpression, loopParameter, rangeCall, + canCacheLength = canCacheLength(rangeCall) + ) + + private fun canCacheLength(rangeCall: ResolvedCall): Boolean { + val receiverType = rangeCall.extensionReceiver?.type ?: return false + return KotlinBuiltIns.isString(receiverType) + } + +} \ No newline at end of file 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 1aaedc9395e..6f1ccc60482 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/RangeValues.kt @@ -130,6 +130,8 @@ private fun ExpressionCodegen.createIntrinsifiedRangeValueOrNull(rangeCall: Reso ArrayWithIndexRangeValue(rangeCall) isIterableWithIndex(rangeCallee) -> IterableWithIndexRangeValue(rangeCall) + isCharSequenceWithIndex(rangeCallee) -> + CharSequenceWithIndexRangeValue(rangeCall) isComparableRangeTo(rangeCallee) -> ComparableRangeLiteralRangeValue(this, rangeCall) isPrimitiveProgressionReverse(rangeCallee) -> diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/CharSequenceWithIndexForLoopGenerator.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/CharSequenceWithIndexForLoopGenerator.kt new file mode 100644 index 00000000000..7f2152d4030 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/range/forLoop/CharSequenceWithIndexForLoopGenerator.kt @@ -0,0 +1,80 @@ +/* + * 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.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.org.objectweb.asm.Label +import org.jetbrains.org.objectweb.asm.Type + +class CharSequenceWithIndexForLoopGenerator( + codegen: ExpressionCodegen, + forExpression: KtForExpression, + loopParameter: KtDestructuringDeclaration, + rangeCall: ResolvedCall, + private val canCacheLength: Boolean +) : AbstractWithIndexForLoopGenerator(codegen, forExpression, loopParameter, rangeCall) { + + private val charSeqType = codegen.asmType(ExpressionCodegen.getExpectedReceiverType(rangeCall)) + private var charSeqVar = -1 + private var lengthVar = -1 + + private var indexVar = -1 + private var indexType = Type.INT_TYPE + + override fun beforeLoop() { + charSeqVar = createLoopTempVariable(charSeqType) + val charSeqValue = StackValue.local(charSeqVar, charSeqType) + charSeqValue.store(codegen.generateCallReceiver(rangeCall), v) + + if (canCacheLength) { + lengthVar = createLoopTempVariable(Type.INT_TYPE) + evalCharSeqLengthOnStack() + v.store(lengthVar, Type.INT_TYPE) + } + + indexVar = indexLoopComponent?.parameterVar ?: createLoopTempVariable(Type.INT_TYPE) + indexType = indexLoopComponent?.parameterType ?: Type.INT_TYPE + + StackValue.local(indexVar, indexType) + .store(StackValue.constant(0, Type.INT_TYPE), v) + } + + private fun evalCharSeqLengthOnStack() { + v.load(charSeqVar, charSeqType) + v.invokeinterface("java/lang/CharSequence", "length", "()I") + } + + override fun checkPreCondition(loopExit: Label) { + v.load(indexVar, Type.INT_TYPE) + if (canCacheLength) { + v.load(lengthVar, Type.INT_TYPE) + } else { + evalCharSeqLengthOnStack() + } + v.ificmpge(loopExit) + } + + override fun assignLoopParametersNextValues() { + if (elementLoopComponent != null) { + v.load(charSeqVar, charSeqType) + v.load(indexVar, Type.INT_TYPE) + v.invokeinterface("java/lang/CharSequence", "charAt", "(I)C") + StackValue.local(elementLoopComponent.parameterVar, elementLoopComponent.parameterType) + .store(StackValue.onStack(Type.CHAR_TYPE), v) + } + } + + override fun incrementAndCheckPostCondition(loopExit: Label) { + v.iinc(indexVar, 1) + } + +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt new file mode 100644 index 00000000000..05d8ba2b42a --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt @@ -0,0 +1,16 @@ +// IGNORE_BACKEND: JS, NATIVE +// WITH_RUNTIME + +fun box(): String { + val s = StringBuilder() + + val xs = StringBuilder("abcd") + + for ((index, x) in xs.withIndex()) { + s.append("$index:$x;") + xs.setLength(0) + } + + val ss = s.toString() + return if (ss == "0:a;") "OK" else "fail: '$ss'" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt new file mode 100644 index 00000000000..1435bb37248 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val cs: CharSequence = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in cs.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/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt new file mode 100644 index 00000000000..490e0e6b01f --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt @@ -0,0 +1,8 @@ +// WITH_RUNTIME + +fun box(): String { + for ((index, x) in "".withIndex()) { + return "Loop over empty String should not be executed" + } + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt new file mode 100644 index 00000000000..bcc212852ff --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt @@ -0,0 +1,12 @@ +// WITH_RUNTIME + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in "abcd".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/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt new file mode 100644 index 00000000000..00fcb0608a0 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((i, _) in xs.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/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt new file mode 100644 index 00000000000..3c6acafa997 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt @@ -0,0 +1,14 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((_, x) in xs.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/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt new file mode 100644 index 00000000000..fd72df19e45 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun useAny(x: Any) {} + +fun box(): String { + val s = StringBuilder() + + for ((index: Any, x) in xs.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/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt new file mode 100644 index 00000000000..25fa8cb750d --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +val cs: CharSequence = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in cs.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 length +// 1 charAt \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt new file mode 100644 index 00000000000..49bdbeff981 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt @@ -0,0 +1,17 @@ +// WITH_RUNTIME + +fun box(): String { + for ((index, x) in "".withIndex()) { + return "Loop over empty String should not be executed" + } + return "OK" +} + +// 0 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 length +// 1 charAt \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt new file mode 100644 index 00000000000..f79bc693b43 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt @@ -0,0 +1,21 @@ +// WITH_RUNTIME + +fun box(): String { + val s = StringBuilder() + + for ((index, x) in "abcd".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 length +// 1 charAt \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt new file mode 100644 index 00000000000..d5b801995fe --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((i, _) in xs.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 length +// 0 charAt \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt new file mode 100644 index 00000000000..1aa599dc8f0 --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt @@ -0,0 +1,23 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun box(): String { + val s = StringBuilder() + + for ((_, x) in xs.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 length +// 1 charAt \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt new file mode 100644 index 00000000000..e23dd13b02b --- /dev/null +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt @@ -0,0 +1,26 @@ +// WITH_RUNTIME + +val xs = "abcd" + +fun useAny(x: Any) {} + +fun box(): String { + val s = StringBuilder() + + for ((index: Any, x) in xs.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 withIndex +// 0 iterator +// 0 hasNext +// 0 next +// 0 component1 +// 0 component2 +// 1 length +// 1 charAt \ 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 75c9bfec71a..19351001ac5 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 @@ -5223,6 +5223,57 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInCharSequenceWithIndex extends AbstractIrBlackBoxCodegenTest { + public void testAllFilesPresentInForInCharSequenceWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInCharSeqWithIndexStops.kt") + public void testForInCharSeqWithIndexStops() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt"); + doTest(fileName); + } + + @TestMetadata("forInCharSequenceWithIndex.kt") + public void testForInCharSequenceWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyStringWithIndex.kt") + public void testForInEmptyStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndex.kt") + public void testForInStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoElementVar.kt") + public void testForInStringWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoIndexVar.kt") + public void testForInStringWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInStringWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex") @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 26c55f7978e..ee4df40ffb0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -5223,6 +5223,57 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInCharSequenceWithIndex extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInForInCharSequenceWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInCharSeqWithIndexStops.kt") + public void testForInCharSeqWithIndexStops() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt"); + doTest(fileName); + } + + @TestMetadata("forInCharSequenceWithIndex.kt") + public void testForInCharSequenceWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyStringWithIndex.kt") + public void testForInEmptyStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndex.kt") + public void testForInStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoElementVar.kt") + public void testForInStringWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoIndexVar.kt") + public void testForInStringWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInStringWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex") @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 39353f2f830..4d17da1ce53 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BytecodeTextTestGenerated.java @@ -1407,6 +1407,51 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest { } } + @TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInCharSequenceWithIndex extends AbstractBytecodeTextTest { + public void testAllFilesPresentInForInCharSequenceWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.ANY, true); + } + + @TestMetadata("forInCharSequenceWithIndex.kt") + public void testForInCharSequenceWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyStringWithIndex.kt") + public void testForInEmptyStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndex.kt") + public void testForInStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoElementVar.kt") + public void testForInStringWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoIndexVar.kt") + public void testForInStringWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInStringWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.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 92965ca2760..6958327430f 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -5223,6 +5223,57 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInCharSequenceWithIndex extends AbstractLightAnalysisModeTest { + public void testAllFilesPresentInForInCharSequenceWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JVM, true); + } + + @TestMetadata("forInCharSeqWithIndexStops.kt") + public void testForInCharSeqWithIndexStops() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt"); + doTest(fileName); + } + + @TestMetadata("forInCharSequenceWithIndex.kt") + public void testForInCharSequenceWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyStringWithIndex.kt") + public void testForInEmptyStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndex.kt") + public void testForInStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoElementVar.kt") + public void testForInStringWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoIndexVar.kt") + public void testForInStringWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInStringWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex") @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 8ad284caf2e..977fe88a5a2 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 @@ -5805,6 +5805,63 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest { } } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class ForInCharSequenceWithIndex extends AbstractJsCodegenBoxTest { + public void testAllFilesPresentInForInCharSequenceWithIndex() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex"), Pattern.compile("^(.+)\\.kt$"), TargetBackend.JS, true); + } + + @TestMetadata("forInCharSeqWithIndexStops.kt") + public void testForInCharSeqWithIndexStops() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSeqWithIndexStops.kt"); + try { + doTest(fileName); + } + catch (Throwable ignore) { + return; + } + throw new AssertionError("Looks like this test can be unmuted. Remove IGNORE_BACKEND directive for that."); + } + + @TestMetadata("forInCharSequenceWithIndex.kt") + public void testForInCharSequenceWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInEmptyStringWithIndex.kt") + public void testForInEmptyStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndex.kt") + public void testForInStringWithIndex() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndex.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoElementVar.kt") + public void testForInStringWithIndexNoElementVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexNoIndexVar.kt") + public void testForInStringWithIndexNoIndexVar() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt"); + doTest(fileName); + } + + @TestMetadata("forInStringWithIndexWithExplicitlyTypedIndexVariable.kt") + public void testForInStringWithIndexWithExplicitlyTypedIndexVariable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/controlStructures/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt"); + doTest(fileName); + } + } + @TestMetadata("compiler/testData/codegen/box/controlStructures/forInIterableWithIndex") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)