KT-40363 Handle non-octal int literals in for-loop conversions
- See EA-210233 - ^KT-40363 Fixed
This commit is contained in:
@@ -23,3 +23,11 @@ fun extractRadix(value: String): NumberWithRadix = when {
|
|||||||
value.startsWith("0b") || value.startsWith("0B") -> NumberWithRadix(value.substring(2), 2)
|
value.startsWith("0b") || value.startsWith("0B") -> NumberWithRadix(value.substring(2), 2)
|
||||||
else -> NumberWithRadix(value, 10)
|
else -> NumberWithRadix(value, 10)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val NumberWithRadix.radixPrefix: String
|
||||||
|
get() = when (radix) {
|
||||||
|
2 -> "0b"
|
||||||
|
10 -> ""
|
||||||
|
16 -> "0x"
|
||||||
|
else -> error("Invalid radix for $this")
|
||||||
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ import org.jetbrains.kotlin.nj2k.tree.*
|
|||||||
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
import org.jetbrains.kotlin.nj2k.types.JKJavaPrimitiveType
|
||||||
import org.jetbrains.kotlin.nj2k.types.JKNoType
|
import org.jetbrains.kotlin.nj2k.types.JKNoType
|
||||||
|
import org.jetbrains.kotlin.utils.extractRadix
|
||||||
|
import org.jetbrains.kotlin.utils.radixPrefix
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
|
||||||
|
|
||||||
@@ -200,8 +202,11 @@ class ForConversion(context: NewJ2kConverterContext) : RecursiveApplicableConver
|
|||||||
if (correction == 0) return bound
|
if (correction == 0) return bound
|
||||||
|
|
||||||
if (bound is JKLiteralExpression && bound.type == JKLiteralExpression.LiteralType.INT) {
|
if (bound is JKLiteralExpression && bound.type == JKLiteralExpression.LiteralType.INT) {
|
||||||
val value = bound.literal.toInt()
|
val correctedLiteral = addCorrectionToIntLiteral(bound.literal, correction)
|
||||||
return JKLiteralExpression((value + correction).toString(), bound.type)
|
|
||||||
|
if (correctedLiteral != null) {
|
||||||
|
return JKLiteralExpression(correctedLiteral, bound.type)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val sign = if (correction > 0) JKOperatorToken.PLUS else JKOperatorToken.MINUS
|
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(
|
private fun indicesIterationRange(
|
||||||
start: JKExpression,
|
start: JKExpression,
|
||||||
bound: JKExpression,
|
bound: JKExpression,
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
class A {
|
||||||
|
{
|
||||||
|
for (int i = 0; i < 0x12b; i++) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
internal class A {
|
||||||
|
init {
|
||||||
|
for (i in 0..0x12a) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+5
@@ -3538,6 +3538,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
|||||||
runTest("nj2k/testData/newJ2k/literalExpression/kt-15991.java");
|
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")
|
@TestMetadata("long.java")
|
||||||
public void testLong() throws Exception {
|
public void testLong() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/literalExpression/long.java");
|
runTest("nj2k/testData/newJ2k/literalExpression/long.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user