From a6c213585178f66d7f5f24f8b1a92dce9bfe86cd Mon Sep 17 00:00:00 2001 From: Toshiaki Kameyama Date: Mon, 21 Aug 2017 18:44:51 +0900 Subject: [PATCH] Counter loop in Java is transformed to less effective loop in Kotlin #KT-19337 Fixed --- .../conversion/SeveralMethodsSample.expected.kt | 2 +- j2k/src/org/jetbrains/kotlin/j2k/ForConverter.kt | 9 +++++---- j2k/src/org/jetbrains/kotlin/j2k/ast/Expressions.kt | 6 ++++++ j2k/src/org/jetbrains/kotlin/j2k/ast/Util.kt | 2 +- j2k/testData/fileOrElement/for/forRangeWithLT2.kt | 2 +- .../fileOrElement/for/forThroughNonArrayIndices.kt | 2 +- .../fileOrElement/for/forThroughNonCollectionIndices.kt | 2 +- j2k/testData/fileOrElement/issues/kt-899.kt | 6 +++--- 8 files changed, 19 insertions(+), 12 deletions(-) diff --git a/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt b/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt index fc77c461841..667416f299d 100644 --- a/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt +++ b/idea/testData/copyPaste/conversion/SeveralMethodsSample.expected.kt @@ -30,7 +30,7 @@ class A { fun getSelected(): ArrayList { val result = ArrayList() - for (i in 0..myChecked.length - 1) { + for (i in 0 until myChecked.length) { if (myChecked[i]) { result.add(myOverridingMethods.get(i)) } diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ForConverter.kt b/j2k/src/org/jetbrains/kotlin/j2k/ForConverter.kt index a5527a379df..e9fd7721bc1 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ForConverter.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ForConverter.kt @@ -206,10 +206,11 @@ class ForConverter( if (indicesRange != null) return indicesRange val startConverted = codeConverter.convertExpression(start) - return if (reversed) - DownToExpression(startConverted, convertBound(bound, if (inclusiveComparison) 0 else +1)) - else - RangeExpression(startConverted, convertBound(bound, if (inclusiveComparison) 0 else -1)) + return when { + reversed -> DownToExpression(startConverted, convertBound(bound, if (inclusiveComparison) 0 else +1)) + bound !is PsiLiteralExpression && !inclusiveComparison -> UntilExpression(startConverted, convertBound(bound, 0)) + else -> RangeExpression(startConverted, convertBound(bound, if (inclusiveComparison) 0 else -1)) + } } private fun indicesIterationRange(start: PsiExpression, bound: PsiExpression, reversed: Boolean, inclusiveComparison: Boolean): Expression? { diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Expressions.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Expressions.kt index 226799a221e..6581ca3ccb7 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Expressions.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Expressions.kt @@ -265,6 +265,12 @@ class RangeExpression(val start: Expression, val end: Expression): Expression() } } +class UntilExpression(val start: Expression, val end: Expression): Expression() { + override fun generateCode(builder: CodeBuilder) { + builder.appendOperand(this, start).append(" until ").appendOperand(this, end) + } +} + class DownToExpression(val start: Expression, val end: Expression): Expression() { override fun generateCode(builder: CodeBuilder) { builder.appendOperand(this, start).append(" downTo ").appendOperand(this, end) diff --git a/j2k/src/org/jetbrains/kotlin/j2k/ast/Util.kt b/j2k/src/org/jetbrains/kotlin/j2k/ast/Util.kt index 33d46ebcc8f..6477a219f61 100644 --- a/j2k/src/org/jetbrains/kotlin/j2k/ast/Util.kt +++ b/j2k/src/org/jetbrains/kotlin/j2k/ast/Util.kt @@ -48,7 +48,7 @@ private fun Expression.precedence(): Int? { is BinaryExpression -> op.precedence - is RangeExpression, is DownToExpression -> 5 + is RangeExpression, is UntilExpression, is DownToExpression -> 5 is IsOperator -> 8 diff --git a/j2k/testData/fileOrElement/for/forRangeWithLT2.kt b/j2k/testData/fileOrElement/for/forRangeWithLT2.kt index 4353335bf69..9826825fa3e 100644 --- a/j2k/testData/fileOrElement/for/forRangeWithLT2.kt +++ b/j2k/testData/fileOrElement/for/forRangeWithLT2.kt @@ -1,3 +1,3 @@ -for (i in 0..N - 1) { +for (i in 0 until N) { println(i) } diff --git a/j2k/testData/fileOrElement/for/forThroughNonArrayIndices.kt b/j2k/testData/fileOrElement/for/forThroughNonArrayIndices.kt index ecfb074f523..390e8f8ffcb 100644 --- a/j2k/testData/fileOrElement/for/forThroughNonArrayIndices.kt +++ b/j2k/testData/fileOrElement/for/forThroughNonArrayIndices.kt @@ -4,7 +4,7 @@ internal class X { internal class C { fun foo(x: X) { - for (i in 0..x.length - 1) { + for (i in 0 until x.length) { print(i) } } diff --git a/j2k/testData/fileOrElement/for/forThroughNonCollectionIndices.kt b/j2k/testData/fileOrElement/for/forThroughNonCollectionIndices.kt index f9c5308650a..99cf0c87fcf 100644 --- a/j2k/testData/fileOrElement/for/forThroughNonCollectionIndices.kt +++ b/j2k/testData/fileOrElement/for/forThroughNonCollectionIndices.kt @@ -6,7 +6,7 @@ internal class X { internal class C { fun foo(x: X) { - for (i in 0..x.size() - 1) { + for (i in 0 until x.size()) { print(i) } } diff --git a/j2k/testData/fileOrElement/issues/kt-899.kt b/j2k/testData/fileOrElement/issues/kt-899.kt index 032f79ab84f..6054f96f1d9 100644 --- a/j2k/testData/fileOrElement/issues/kt-899.kt +++ b/j2k/testData/fileOrElement/issues/kt-899.kt @@ -4,15 +4,15 @@ internal class Test { println(i1) val b: Byte = 1 - for (i2 in 0..b - 1) + for (i2 in 0 until b) println(i2) val s: Short = 1 - for (i3 in 0..s - 1) + for (i3 in 0 until s) println(i3) val l = 1L - for (i4 in 0..l - 1) + for (i4 in 0 until l) println(i4) val d = 1.0