From be06c51aa76e198a48c4a5c38aa4cb016fc2143a Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Mon, 20 Jul 2020 14:49:19 +0300 Subject: [PATCH] KT-40363 Handle non-octal int literals in for-loop conversions - See EA-210233 - ^KT-40363 Fixed --- .../src/org/jetbrains/kotlin/utils/numbers.kt | 8 ++++++++ .../kotlin/nj2k/conversions/ForConversion.kt | 20 +++++++++++++++++-- .../newJ2k/literalExpression/kt-40363.java | 7 +++++++ .../newJ2k/literalExpression/kt-40363.kt | 6 ++++++ ...otlinConverterSingleFileTestGenerated.java | 5 +++++ 5 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 nj2k/testData/newJ2k/literalExpression/kt-40363.java create mode 100644 nj2k/testData/newJ2k/literalExpression/kt-40363.kt diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/numbers.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/numbers.kt index 30e872e9725..a30e2c2c7f8 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/numbers.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/numbers.kt @@ -23,3 +23,11 @@ fun extractRadix(value: String): NumberWithRadix = when { value.startsWith("0b") || value.startsWith("0B") -> NumberWithRadix(value.substring(2), 2) else -> NumberWithRadix(value, 10) } + +val NumberWithRadix.radixPrefix: String + get() = when (radix) { + 2 -> "0b" + 10 -> "" + 16 -> "0x" + else -> error("Invalid radix for $this") + } diff --git a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt index 184e7948901..c3a83cfd3bb 100644 --- a/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt +++ b/nj2k/src/org/jetbrains/kotlin/nj2k/conversions/ForConversion.kt @@ -17,6 +17,8 @@ import org.jetbrains.kotlin.nj2k.tree.* import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType import org.jetbrains.kotlin.nj2k.types.JKNoType +import org.jetbrains.kotlin.utils.extractRadix +import org.jetbrains.kotlin.utils.radixPrefix import kotlin.math.abs @@ -200,8 +202,11 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver if (correction == 0) return bound if (bound is JKLiteralExpression && bound.type == JKLiteralExpression.LiteralType.INT) { - val value = bound.literal.toInt() - return JKLiteralExpression((value + correction).toString(), bound.type) + val correctedLiteral = addCorrectionToIntLiteral(bound.literal, correction) + + if (correctedLiteral != null) { + return JKLiteralExpression(correctedLiteral, bound.type) + } } val sign = if (correction > 0) JKOperatorToken.PLUS else JKOperatorToken.MINUS @@ -215,6 +220,17 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver ) } + private fun addCorrectionToIntLiteral(intLiteral: String, correction: Int): String? { + require(!intLiteral.startsWith("-")) { "This function does not work with signed literals, but $intLiteral was supplied" } + + val numberWithRadix = extractRadix(intLiteral) + + val value = numberWithRadix.number.toIntOrNull(numberWithRadix.radix) ?: return null + val fixedValue = (value + correction).toString(numberWithRadix.radix) + + return "${numberWithRadix.radixPrefix}${fixedValue}" + } + private fun indicesIterationRange( start: JKExpression, bound: JKExpression, diff --git a/nj2k/testData/newJ2k/literalExpression/kt-40363.java b/nj2k/testData/newJ2k/literalExpression/kt-40363.java new file mode 100644 index 00000000000..6bcf6590903 --- /dev/null +++ b/nj2k/testData/newJ2k/literalExpression/kt-40363.java @@ -0,0 +1,7 @@ +class A { + { + for (int i = 0; i < 0x12b; i++) { + + } + } +} \ No newline at end of file diff --git a/nj2k/testData/newJ2k/literalExpression/kt-40363.kt b/nj2k/testData/newJ2k/literalExpression/kt-40363.kt new file mode 100644 index 00000000000..dff9c92cc9c --- /dev/null +++ b/nj2k/testData/newJ2k/literalExpression/kt-40363.kt @@ -0,0 +1,6 @@ +internal class A { + init { + for (i in 0..0x12a) { + } + } +} \ No newline at end of file diff --git a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java index 03ef1cb7730..755e97a6cbc 100644 --- a/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java +++ b/nj2k/tests/org/jetbrains/kotlin/nj2k/NewJavaToKotlinConverterSingleFileTestGenerated.java @@ -3538,6 +3538,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew runTest("nj2k/testData/newJ2k/literalExpression/kt-15991.java"); } + @TestMetadata("kt-40363.java") + public void testKt_40363() throws Exception { + runTest("nj2k/testData/newJ2k/literalExpression/kt-40363.java"); + } + @TestMetadata("long.java") public void testLong() throws Exception { runTest("nj2k/testData/newJ2k/literalExpression/long.java");