diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/jdk2k/ReplaceJavaStaticMethodWithKotlinAnalogInspection.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/jdk2k/ReplaceJavaStaticMethodWithKotlinAnalogInspection.kt index 23009e435ec9..f5a2686225f9 100644 --- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/jdk2k/ReplaceJavaStaticMethodWithKotlinAnalogInspection.kt +++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/inspections/jdk2k/ReplaceJavaStaticMethodWithKotlinAnalogInspection.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKot import org.jetbrains.kotlin.idea.inspections.collections.isCalling import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtCallExpression +import org.jetbrains.kotlin.psi.KtConstantExpression import org.jetbrains.kotlin.psi.KtSimpleNameExpression import org.jetbrains.kotlin.psi.callExpressionVisitor import org.jetbrains.kotlin.psi.psiUtil.getReceiverExpression @@ -87,8 +88,19 @@ class ReplaceJavaStaticMethodWithKotlinAnalogInspection : AbstractKotlinInspecti "Float" to "Float" ).flatMap { (javaPrimitive, kotlinPrimitive) -> listOf( + // If radix is not a literal, it is considered an unsafe replacement (Kotlin has checks for an invalid radix) + Replacement("java.lang.$javaPrimitive.toString", "kotlin.text.toString", ToExtensionFunctionWithNonNullableReceiver, mayChangeSemantics = true) { + if (it.valueArguments.size != 2) return@Replacement false + val radix = it.valueArguments.last().getArgumentExpression() + radix !is KtConstantExpression + }, + // If radix is an int literal within bounds, the conversion is safe Replacement("java.lang.$javaPrimitive.toString", "kotlin.text.toString", ToExtensionFunctionWithNonNullableReceiver) { - it.valueArguments.size == 2 + if (it.valueArguments.size != 2) return@Replacement false + val radixExpr = it.valueArguments.last().getArgumentExpression() + if (radixExpr !is KtConstantExpression) return@Replacement false + val radix = radixExpr.text.toIntOrNull() ?: return@Replacement false + radix in 2..36 }, Replacement( "java.lang.$javaPrimitive.toString", diff --git a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java index 7888c29c82c6..fed35141553d 100644 --- a/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java +++ b/plugins/kotlin/idea/tests/test/org/jetbrains/kotlin/idea/inspections/LocalInspectionTestGenerated.java @@ -12739,6 +12739,16 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti runTest("testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt"); } + @TestMetadata("intToStringWithInvalidLiteralRadix.kt") + public void testIntToStringWithInvalidLiteralRadix() throws Exception { + runTest("testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithInvalidLiteralRadix.kt"); + } + + @TestMetadata("intToStringWithLiteralRadix.kt") + public void testIntToStringWithLiteralRadix() throws Exception { + runTest("testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt"); + } + @TestMetadata("longToString.kt") public void testLongToString() throws Exception { runTest("testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString.kt"); diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt index 725720b514c2..7fd2a48d1549 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt @@ -1,4 +1,5 @@ // WITH_STDLIB +// FIX: Replace with 'toString' function (may change semantics) fun foo() { val b = listOf(42, 10) diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt.after index 119a6be00ef9..4dc7a6a6ca9d 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToString2.kt.after @@ -1,4 +1,5 @@ // WITH_STDLIB +// FIX: Replace with 'toString' function (may change semantics) fun foo() { val b = listOf(42, 10) diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithInvalidLiteralRadix.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithInvalidLiteralRadix.kt new file mode 100644 index 000000000000..b839ba982aaf --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithInvalidLiteralRadix.kt @@ -0,0 +1,5 @@ +// WITH_STDLIB +// PROBLEM: none +fun foo() { + Integer.toString(42, 1) +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt new file mode 100644 index 000000000000..8708150f0ecf --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt @@ -0,0 +1,5 @@ +// WITH_STDLIB + +fun foo() { + Integer.toString(42, 8) +} \ No newline at end of file diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt.after new file mode 100644 index 000000000000..145e33b86f0d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/intToStringWithLiteralRadix.kt.after @@ -0,0 +1,5 @@ +// WITH_STDLIB + +fun foo() { + 42.toString(8) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt index 67496771bbe4..2b264ccdc712 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt @@ -1,5 +1,7 @@ // WITH_STDLIB +// FIX: Replace with 'toString' function (may change semantics) fun foo() { - val t = java.lang.Long.toString(5, 42) + 6 + val radix = 42 + val t = java.lang.Long.toString(5, radix) + 6 } diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt.after index 8d15bf3ae418..f00b804734b3 100644 --- a/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt.after +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/replaceJavaStaticMethodWithKotlinAnalog/toString/longToString2.kt.after @@ -1,5 +1,7 @@ // WITH_STDLIB +// FIX: Replace with 'toString' function (may change semantics) fun foo() { - val t = 5.toString(42) + 6 + val radix = 42 + val t = 5.toString(radix) + 6 }