From 06b48484068f6bb2aca00de6ada972e526400bad Mon Sep 17 00:00:00 2001 From: Alexey Belkov Date: Sun, 9 Nov 2025 20:11:39 +0400 Subject: [PATCH] [kotlin] KTIJ-19869 Add KotlinArrayToStringInspection KTIJ-6515 KTIJ-19869 KTIJ-16730 GitOrigin-RevId: 65d5a332fb53589c4c67da28d5fdc6cda767e59e --- .../messages/KotlinBundle.properties | 6 + .../KotlinArrayToString.html | 54 ++++ ...ntellij.kotlin.codeInsight.inspections.xml | 8 + .../KotlinArrayToStringInspection.kt | 276 ++++++++++++++++++ .../tests/K2LocalInspectionTestGenerated.java | 109 +++++++ .../LocalInspectionTestGenerated.java | 109 +++++++ .../arrayToString/.k2Inspection | 1 + .../arrayToString/genericTypeArray.kt | 8 + .../arrayToString/genericTypeArray.kt.after | 8 + .../implicitNestedArrayConcatenation.kt | 9 + .../implicitNestedArrayConcatenation.kt.after | 9 + .../implicitStringConcatenation.kt | 9 + .../implicitStringConcatenation.kt.after | 9 + .../arrayToString/intArray.kt | 9 + .../arrayToString/intArray.kt.after | 9 + ...ultidimensionalArrayContentDeepToString.kt | 10 + ...mensionalArrayContentDeepToString.kt.after | 10 + .../multidimensionalArrayContentToString.kt | 9 + ...tidimensionalArrayContentToString.kt.after | 9 + .../arrayToString/noInspection.kt | 8 + .../arrayToString/nullableArray.kt | 9 + .../arrayToString/nullableArray.kt.after | 9 + .../arrayToString/printArray.kt | 9 + .../arrayToString/printArray.kt.after | 9 + .../arrayToString/printlnArray.kt | 9 + .../arrayToString/printlnArray.kt.after | 9 + .../arrayToString/printlnNestedArray.kt | 9 + .../arrayToString/printlnNestedArray.kt.after | 9 + .../arrayToString/simpleArray.kt | 9 + .../arrayToString/simpleArray.kt.after | 9 + .../arrayToString/stringBufferAppend.kt | 10 + .../arrayToString/stringBufferAppend.kt.after | 10 + .../arrayToString/stringBuilderAppend.kt | 10 + .../stringBuilderAppend.kt.after | 10 + .../stringBuilderAppendNestedArray.kt | 10 + .../stringBuilderAppendNestedArray.kt.after | 10 + .../arrayToString/stringTemplate.kt | 9 + .../arrayToString/stringTemplate.kt.after | 9 + .../stringTemplateNestedArray.kt | 9 + .../stringTemplateNestedArray.kt.after | 9 + .../arrayToString/stringTemplateSimpleName.kt | 9 + .../stringTemplateSimpleName.kt.after | 9 + .../arrayToString/varargParameter.kt | 9 + .../arrayToString/varargParameter.kt.after | 9 + .../codeinsight/GenerateK2InspectionTests.kt | 1 + 45 files changed, 902 insertions(+) create mode 100644 plugins/kotlin/code-insight/descriptions/resources-en/inspectionDescriptions/KotlinArrayToString.html create mode 100644 plugins/kotlin/code-insight/inspections-k2/src/org/jetbrains/kotlin/idea/k2/codeinsight/inspections/KotlinArrayToStringInspection.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/.k2Inspection create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/noInspection.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt.after create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt create mode 100644 plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt.after diff --git a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties index d7167284d9dd..a091a8866ec5 100644 --- a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties +++ b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties @@ -2646,6 +2646,12 @@ array.hash.code.problem.descriptor='hashCode()' called on array replace.with.content.hash.code=Replace with 'contentHashCode()' replace.with.content.deep.hash.code=Replace with 'contentDeepHashCode()' +inspection.array.to.string.display.name='toString()' called on array +array.to.string.problem.descriptor='toString()' called on array +array.implicit.to.string.problem.descriptor=Implicit 'toString()' called on array +replace.with.content.to.string=Replace with 'contentToString()' +replace.with.content.deep.to.string=Replace with 'contentDeepToString()' + inspection.string.referential.equality.display.name=String compared with referential equality string.comparison.using.referential.equality.triple.equals=String comparison using '===' instead of '==' string.comparison.using.referential.equality.triple.not.equals=String comparison using '!==' instead of '!=' diff --git a/plugins/kotlin/code-insight/descriptions/resources-en/inspectionDescriptions/KotlinArrayToString.html b/plugins/kotlin/code-insight/descriptions/resources-en/inspectionDescriptions/KotlinArrayToString.html new file mode 100644 index 000000000000..e08cf527a08f --- /dev/null +++ b/plugins/kotlin/code-insight/descriptions/resources-en/inspectionDescriptions/KotlinArrayToString.html @@ -0,0 +1,54 @@ + + +

Calling toString() on an array returns the address of the object in memory, + not a string representation of the array's contents. This is almost never what you want.

+

To get a string representation of an array correctly, use:

+ +

Example (explicit toString):

+

+  fun main() {
+      val a = arrayOf(1, 2, 3)
+      val s = a.toString() // incorrect
+  }
+
+

After the quick-fix is applied:

+

+  fun main() {
+      val a = arrayOf(1, 2, 3)
+      val s = a.contentToString() // correct
+  }
+
+

Example (implicit toString in string template):

+

+  fun main() {
+      val a = arrayOf(1, 2, 3)
+      println("Array: $a") // incorrect - prints address
+  }
+
+

After the quick-fix is applied:

+

+  fun main() {
+      val a = arrayOf(1, 2, 3)
+      println("Array: ${a.contentToString()}") // correct - prints [1, 2, 3]
+  }
+
+

Example (multidimensional array):

+

+  fun main() {
+      val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4))
+      val s = a2d.toString() // incorrect
+  }
+
+

After the quick-fix is applied:

+

+  fun main() {
+      val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4))
+      val s = a2d.contentDeepToString() // correct - prints [[1, 2], [3, 4]]
+  }
+
+ + + diff --git a/plugins/kotlin/code-insight/inspections-k2/resources/intellij.kotlin.codeInsight.inspections.xml b/plugins/kotlin/code-insight/inspections-k2/resources/intellij.kotlin.codeInsight.inspections.xml index f619c73cf23c..3cae9281321a 100644 --- a/plugins/kotlin/code-insight/inspections-k2/resources/intellij.kotlin.codeInsight.inspections.xml +++ b/plugins/kotlin/code-insight/inspections-k2/resources/intellij.kotlin.codeInsight.inspections.xml @@ -388,6 +388,14 @@ language="kotlin" key="inspection.array.hash.code.display.name" bundle="messages.KotlinBundle"/> + + = setOf("append", "print", "println") +private val TO_STRING_CALLABLE_ID = CallableId(StandardClassIds.Any, Name.identifier("toString")) + +// This also handles Kotlin typealiases to Java underlying types +private val IMPLICIT_TO_STRING_CALLABLE_IDS: Set = setOf( + CallableId(ClassId.topLevel(FqName("java.lang.StringBuilder")), Name.identifier("append")), + CallableId(ClassId.topLevel(FqName("java.lang.StringBuffer")), Name.identifier("append")), + CallableId(ClassId.topLevel(FqName("java.io.PrintStream")), Name.identifier("print")), + CallableId(ClassId.topLevel(FqName("java.io.PrintStream")), Name.identifier("println")), + CallableId(ClassId.topLevel(FqName("java.io.PrintWriter")), Name.identifier("print")), + CallableId(ClassId.topLevel(FqName("java.io.PrintWriter")), Name.identifier("println")), + CallableId(FqName("kotlin.io"), Name.identifier("print")), + CallableId(FqName("kotlin.io"), Name.identifier("println")) +) + +internal class KotlinArrayToStringInspection : KotlinApplicableInspectionBase() { + data class Context(val isNestedArray: Boolean, val isImplicitConversion: Boolean) + + override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): KtVisitorVoid = object : KtVisitorVoid() { + override fun visitQualifiedExpression(expression: KtQualifiedExpression) { + visitTargetElement(expression, holder, isOnTheFly) + } + + override fun visitBinaryExpression(expression: KtBinaryExpression) { + visitTargetElement(expression, holder, isOnTheFly) + } + + override fun visitCallExpression(expression: KtCallExpression) { + visitTargetElement(expression, holder, isOnTheFly) + } + + override fun visitStringTemplateEntry(entry: KtStringTemplateEntry) { + if (entry is KtStringTemplateEntryWithExpression) { + entry.expression?.let { visitTargetElement(it, holder, isOnTheFly) } + } + } + } + + override fun isApplicableByPsi(element: KtExpression): Boolean { + return when (element) { + is KtQualifiedExpression -> { + val callExpression = element.selectorExpression as? KtCallExpression ?: return false + if (callExpression.valueArguments.isNotEmpty()) return false + val calleeName = callExpression.calleeExpression?.text ?: return false + calleeName == "toString" + } + + is KtBinaryExpression -> { + element.operationReference.text == "+" + } + + is KtCallExpression -> { + val calleeName = element.getCallNameExpression()?.text ?: return false + calleeName in IMPLICIT_TO_STRING_METHOD_NAMES + } + + else -> { + // Check if this is inside a string template + val parent = element.parent + parent is KtBlockStringTemplateEntry || parent is KtSimpleNameStringTemplateEntry + } + } + } + + override fun KaSession.prepareContext(element: KtExpression): Context? { + return when (element) { + is KtQualifiedExpression -> { + val receiverType = element.receiverExpression.expressionType ?: return null + if (!receiverType.isArrayOrPrimitiveArray) return null + val callExpression = element.selectorExpression as? KtCallExpression ?: return null + val call = callExpression.resolveToCall()?.successfulFunctionCallOrNull() ?: return null + val functionSymbol = call.symbol as? KaNamedFunctionSymbol ?: return null + if (functionSymbol.callableId != TO_STRING_CALLABLE_ID) return null + + Context(receiverType.isNestedArray, isImplicitConversion = false) + } + + is KtBinaryExpression -> { + // String concatenation only works as String + Any (not Any + String) + if (element.left?.expressionType?.isStringType != true) return null + val rightType = element.right?.expressionType ?: return null + if (!rightType.isArrayOrPrimitiveArray) return null + + Context(rightType.isNestedArray, isImplicitConversion = true) + } + + is KtCallExpression -> { + val call = element.resolveToCall()?.successfulFunctionCallOrNull() ?: return null + val functionSymbol = call.symbol as? KaNamedFunctionSymbol ?: return null + val callableId = functionSymbol.callableId ?: return null + if (callableId !in IMPLICIT_TO_STRING_CALLABLE_IDS) return null + + val arguments = element.valueArguments + if (arguments.size != 1) return null + val argType = arguments[0].getArgumentExpression()?.expressionType ?: return null + if (!argType.isArrayOrPrimitiveArray) return null + + Context(argType.isNestedArray, isImplicitConversion = true) + } + + else -> { + val parent = element.parent + if (parent !is KtBlockStringTemplateEntry && parent !is KtSimpleNameStringTemplateEntry) return null + val expressionType = element.expressionType ?: return null + if (!expressionType.isArrayOrPrimitiveArray) return null + + Context(expressionType.isNestedArray, isImplicitConversion = true) + } + } + } + + override fun getApplicableRanges(element: KtExpression): List { + return when (element) { + is KtQualifiedExpression -> { + val selectorExpression = element.selectorExpression ?: return emptyList() + ApplicabilityRange.single(element) { selectorExpression } + } + + is KtBinaryExpression -> { + ApplicabilityRange.single(element) { element.operationReference } + } + + is KtCallExpression -> { + val calleeExpression = element.getCallNameExpression() ?: return emptyList() + ApplicabilityRange.single(element) { calleeExpression } + } + + else -> { + // For string templates, highlight the entire expression + ApplicabilityRange.single(element) { element } + } + } + } + + override fun InspectionManager.createProblemDescriptor( + element: KtExpression, + context: Context, + rangeInElement: TextRange?, + onTheFly: Boolean + ): ProblemDescriptor { + val message = if (context.isImplicitConversion) { + KotlinBundle.message("array.implicit.to.string.problem.descriptor") + } else { + KotlinBundle.message("array.to.string.problem.descriptor") + } + + val fixes = if (context.isNestedArray) { + arrayOf(ReplaceWithContentToStringFix(), ReplaceWithContentDeepToStringFix()) + } else { + arrayOf(ReplaceWithContentToStringFix()) + } + + return createProblemDescriptor( + /* psiElement = */ element, + /* rangeInElement = */ rangeInElement, + /* descriptionTemplate = */ message, + /* highlightType = */ ProblemHighlightType.GENERIC_ERROR_OR_WARNING, + /* onTheFly = */ onTheFly, + /* ...fixes = */ *fixes + ) + } +} + +private class ReplaceWithContentToStringFix : KotlinModCommandQuickFix() { + override fun getFamilyName(): @IntentionFamilyName String = + KotlinBundle.message("replace.with.content.to.string") + + override fun applyFix(project: Project, element: KtExpression, updater: ModPsiUpdater) { + replaceWithArrayContentMethod(project, element, methodName = "contentToString") + } +} + +private class ReplaceWithContentDeepToStringFix : KotlinModCommandQuickFix(), HighPriorityAction { + override fun getFamilyName(): @IntentionFamilyName String = + KotlinBundle.message("replace.with.content.deep.to.string") + + override fun applyFix(project: Project, element: KtExpression, updater: ModPsiUpdater) { + replaceWithArrayContentMethod(project, element, methodName = "contentDeepToString") + } +} + +private fun replaceWithArrayContentMethod(project: Project, element: KtExpression, methodName: String) { + val psiFactory = KtPsiFactory(project) + when (element) { + is KtQualifiedExpression -> { + val receiver = element.receiverExpression + val operator = element.operationSign.value // . or ?. + val newExpression = psiFactory.createExpressionByPattern("$0$operator$methodName()", receiver) + element.replace(newExpression) + } + + is KtBinaryExpression -> { + val left = element.left ?: return + val right = element.right ?: return + // Only string + array pattern is valid for string concatenation + val newExpression = psiFactory.createExpressionByPattern("$0 + $1.$methodName()", left, right) + element.replace(newExpression) + } + + is KtCallExpression -> { + val calleeName = element.getCallNameExpression()?.text ?: return + when (calleeName) { + "append" -> { + // receiver.append(array) -> receiver.append(array.contentToString()) + val receiver = element.parent as? KtDotQualifiedExpression + if (receiver != null) { + val receiverExpr = receiver.receiverExpression + val argument = element.valueArguments.firstOrNull()?.getArgumentExpression() ?: return + val operator = receiver.operationSign.value + val newExpression = psiFactory.createExpressionByPattern( + "$0${operator}$calleeName($1.$methodName())", + receiverExpr, + argument + ) + receiver.replace(newExpression) + } else { + // Just append(array) without receiver -> append(array.contentToString()) + val argument = element.valueArguments.firstOrNull()?.getArgumentExpression() ?: return + val newExpression = psiFactory.createExpressionByPattern("$calleeName($0.$methodName())", argument) + element.replace(newExpression) + } + } + + "print", "println" -> { + // print(array) -> print(array.contentToString()) + val argument = element.valueArguments.firstOrNull()?.getArgumentExpression() ?: return + val newExpression = psiFactory.createExpressionByPattern("$calleeName($0.$methodName())", argument) + element.replace(newExpression) + } + } + } + + else -> { + // String template + val parent = element.parent + when (parent) { + is KtBlockStringTemplateEntry -> { + // "${array}" -> "${array.contentToString()}" + val newExpression = psiFactory.createExpressionByPattern("$0.$methodName()", element) + element.replace(newExpression) + } + is KtSimpleNameStringTemplateEntry -> { + // "$array" -> "${array.contentToString()}" + val newExpression = psiFactory.createExpressionByPattern("$0.$methodName()", element) + val newEntry = psiFactory.createBlockStringTemplateEntry(newExpression) + parent.replace(newEntry) + } + } + } + } +} diff --git a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java index 5ad38e472cb5..8475d6945d09 100644 --- a/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java +++ b/plugins/kotlin/code-insight/inspections-k2/tests/test/org/jetbrains/kotlin/idea/k2/inspections/tests/K2LocalInspectionTestGenerated.java @@ -4353,6 +4353,115 @@ public abstract class K2LocalInspectionTestGenerated extends AbstractK2LocalInsp } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("../../../idea/tests/testData/inspectionsLocal/arrayToString") + public static class ArrayToString extends AbstractK2LocalInspectionTest { + @java.lang.Override + @org.jetbrains.annotations.NotNull + public final KotlinPluginMode getPluginMode() { + return KotlinPluginMode.K2; + } + + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("genericTypeArray.kt") + public void testGenericTypeArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt"); + } + + @TestMetadata("implicitNestedArrayConcatenation.kt") + public void testImplicitNestedArrayConcatenation() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt"); + } + + @TestMetadata("implicitStringConcatenation.kt") + public void testImplicitStringConcatenation() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt"); + } + + @TestMetadata("intArray.kt") + public void testIntArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt"); + } + + @TestMetadata("multidimensionalArrayContentDeepToString.kt") + public void testMultidimensionalArrayContentDeepToString() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt"); + } + + @TestMetadata("multidimensionalArrayContentToString.kt") + public void testMultidimensionalArrayContentToString() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt"); + } + + @TestMetadata("noInspection.kt") + public void testNoInspection() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/noInspection.kt"); + } + + @TestMetadata("nullableArray.kt") + public void testNullableArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt"); + } + + @TestMetadata("printArray.kt") + public void testPrintArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt"); + } + + @TestMetadata("printlnArray.kt") + public void testPrintlnArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt"); + } + + @TestMetadata("printlnNestedArray.kt") + public void testPrintlnNestedArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt"); + } + + @TestMetadata("simpleArray.kt") + public void testSimpleArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt"); + } + + @TestMetadata("stringBufferAppend.kt") + public void testStringBufferAppend() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt"); + } + + @TestMetadata("stringBuilderAppend.kt") + public void testStringBuilderAppend() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt"); + } + + @TestMetadata("stringBuilderAppendNestedArray.kt") + public void testStringBuilderAppendNestedArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt"); + } + + @TestMetadata("stringTemplate.kt") + public void testStringTemplate() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt"); + } + + @TestMetadata("stringTemplateNestedArray.kt") + public void testStringTemplateNestedArray() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt"); + } + + @TestMetadata("stringTemplateSimpleName.kt") + public void testStringTemplateSimpleName() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt"); + } + + @TestMetadata("varargParameter.kt") + public void testVarargParameter() throws Exception { + runTest("../../../idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("../../../idea/tests/testData/inspectionsLocal/stringReferentialEquality") public static class StringReferentialEquality extends AbstractK2LocalInspectionTest { 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 c37b3e15d32f..1ba5cbf1c370 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 @@ -192,6 +192,115 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti } } + @RunWith(JUnit3RunnerWithInners.class) + @TestMetadata("testData/inspectionsLocal/arrayToString") + public static class ArrayToString extends AbstractLocalInspectionTest { + @java.lang.Override + @org.jetbrains.annotations.NotNull + public final KotlinPluginMode getPluginMode() { + return KotlinPluginMode.K1; + } + + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("genericTypeArray.kt") + public void testGenericTypeArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/genericTypeArray.kt"); + } + + @TestMetadata("implicitNestedArrayConcatenation.kt") + public void testImplicitNestedArrayConcatenation() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt"); + } + + @TestMetadata("implicitStringConcatenation.kt") + public void testImplicitStringConcatenation() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt"); + } + + @TestMetadata("intArray.kt") + public void testIntArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/intArray.kt"); + } + + @TestMetadata("multidimensionalArrayContentDeepToString.kt") + public void testMultidimensionalArrayContentDeepToString() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt"); + } + + @TestMetadata("multidimensionalArrayContentToString.kt") + public void testMultidimensionalArrayContentToString() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt"); + } + + @TestMetadata("noInspection.kt") + public void testNoInspection() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/noInspection.kt"); + } + + @TestMetadata("nullableArray.kt") + public void testNullableArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/nullableArray.kt"); + } + + @TestMetadata("printArray.kt") + public void testPrintArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/printArray.kt"); + } + + @TestMetadata("printlnArray.kt") + public void testPrintlnArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/printlnArray.kt"); + } + + @TestMetadata("printlnNestedArray.kt") + public void testPrintlnNestedArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/printlnNestedArray.kt"); + } + + @TestMetadata("simpleArray.kt") + public void testSimpleArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/simpleArray.kt"); + } + + @TestMetadata("stringBufferAppend.kt") + public void testStringBufferAppend() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringBufferAppend.kt"); + } + + @TestMetadata("stringBuilderAppend.kt") + public void testStringBuilderAppend() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt"); + } + + @TestMetadata("stringBuilderAppendNestedArray.kt") + public void testStringBuilderAppendNestedArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt"); + } + + @TestMetadata("stringTemplate.kt") + public void testStringTemplate() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringTemplate.kt"); + } + + @TestMetadata("stringTemplateNestedArray.kt") + public void testStringTemplateNestedArray() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt"); + } + + @TestMetadata("stringTemplateSimpleName.kt") + public void testStringTemplateSimpleName() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt"); + } + + @TestMetadata("varargParameter.kt") + public void testVarargParameter() throws Exception { + runTest("testData/inspectionsLocal/arrayToString/varargParameter.kt"); + } + } + @RunWith(JUnit3RunnerWithInners.class) @TestMetadata("testData/inspectionsLocal/booleanLiteralArgument") public static class BooleanLiteralArgument extends AbstractLocalInspectionTest { diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/.k2Inspection b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/.k2Inspection new file mode 100644 index 000000000000..89dbd6949322 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/.k2Inspection @@ -0,0 +1 @@ +org.jetbrains.kotlin.idea.k2.codeinsight.inspections.KotlinArrayToStringInspection diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt new file mode 100644 index 000000000000..9d0ca8d1b199 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt @@ -0,0 +1,8 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun stringifyArray(arr: Array): String { + return arr.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt.after new file mode 100644 index 000000000000..a24c9814b1de --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/genericTypeArray.kt.after @@ -0,0 +1,8 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun stringifyArray(arr: Array): String { + return arr.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt new file mode 100644 index 000000000000..10466fd6f315 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val result = "Nested: " + arr +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt.after new file mode 100644 index 000000000000..19ac669265b0 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitNestedArrayConcatenation.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val result = "Nested: " + arr.contentDeepToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt new file mode 100644 index 000000000000..0b23d163617e --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: " + arr +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt.after new file mode 100644 index 000000000000..2739d828e608 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/implicitStringConcatenation.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: " + arr.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt new file mode 100644 index 000000000000..d13c9cc5fb73 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a1 = intArrayOf(1, 2, 3) + val s = a1.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt.after new file mode 100644 index 000000000000..7c614bc76363 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/intArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a1 = intArrayOf(1, 2, 3) + val s = a1.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt new file mode 100644 index 000000000000..1f57cf6f6ba4 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt @@ -0,0 +1,10 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// PRIORITY: HIGH +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val s = a2d.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt.after new file mode 100644 index 000000000000..a8cf21bd216b --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentDeepToString.kt.after @@ -0,0 +1,10 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// PRIORITY: HIGH +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val s = a2d.contentDeepToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt new file mode 100644 index 000000000000..6e36e7e6559a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val s = a2d.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt.after new file mode 100644 index 000000000000..4acbd3c01bd3 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/multidimensionalArrayContentToString.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a2d = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val s = a2d.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/noInspection.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/noInspection.kt new file mode 100644 index 000000000000..597ae395bb4f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/noInspection.kt @@ -0,0 +1,8 @@ +// PROBLEM: none +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val notArray = "test" + val s = notArray.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt new file mode 100644 index 000000000000..63f734e2cfe5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr: IntArray? = intArrayOf(1, 2, 3) + val s = arr?.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt.after new file mode 100644 index 000000000000..cab5d6cc702c --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/nullableArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr: IntArray? = intArrayOf(1, 2, 3) + val s = arr?.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt new file mode 100644 index 000000000000..49c9509ad86d --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf("a", "b", "c") + print(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt.after new file mode 100644 index 000000000000..60c457c9845b --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf("a", "b", "c") + print(arr.contentToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt new file mode 100644 index 000000000000..da4f5a1b5566 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = doubleArrayOf(1.0, 2.0, 3.0) + println(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt.after new file mode 100644 index 000000000000..01f28327210f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = doubleArrayOf(1.0, 2.0, 3.0) + println(arr.contentToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt new file mode 100644 index 000000000000..f3eaa17376e7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(intArrayOf(1, 2), intArrayOf(3, 4)) + println(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt.after new file mode 100644 index 000000000000..c513995f35c5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/printlnNestedArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(intArrayOf(1, 2), intArrayOf(3, 4)) + println(arr.contentDeepToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt new file mode 100644 index 000000000000..670a65f92885 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a = arrayOf(1, 2, 3) + val s = a.toString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt.after new file mode 100644 index 000000000000..e4a4a5d172f7 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/simpleArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val a = arrayOf(1, 2, 3) + val s = a.contentToString() +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt new file mode 100644 index 000000000000..70623050b72f --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = intArrayOf(1, 2, 3) + val sb = StringBuffer() + sb.append(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt.after new file mode 100644 index 000000000000..641a325bb059 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBufferAppend.kt.after @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = intArrayOf(1, 2, 3) + val sb = StringBuffer() + sb.append(arr.contentToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt new file mode 100644 index 000000000000..7b85a1eadaf3 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val sb = StringBuilder() + sb.append(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt.after new file mode 100644 index 000000000000..0ae37676d86a --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppend.kt.after @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val sb = StringBuilder() + sb.append(arr.contentToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt new file mode 100644 index 000000000000..c0d4412c18fe --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val sb = StringBuilder() + sb.append(arr) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt.after new file mode 100644 index 000000000000..e917d5ee4c56 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringBuilderAppendNestedArray.kt.after @@ -0,0 +1,10 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf(1, 2), arrayOf(3, 4)) + val sb = StringBuilder() + sb.append(arr.contentDeepToString()) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt new file mode 100644 index 000000000000..4656c553c040 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: ${arr}" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt.after new file mode 100644 index 000000000000..b304cbec0ab9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplate.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: ${arr.contentToString()}" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt new file mode 100644 index 000000000000..2d3e796c09ab --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf("a", "b"), arrayOf("c", "d")) + val result = "Nested: ${arr}" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt.after new file mode 100644 index 000000000000..32369ffb4b4e --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateNestedArray.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentDeepToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(arrayOf("a", "b"), arrayOf("c", "d")) + val result = "Nested: ${arr.contentDeepToString()}" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt new file mode 100644 index 000000000000..d3862d9ed4f4 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: $arr" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt.after new file mode 100644 index 000000000000..b304cbec0ab9 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/stringTemplateSimpleName.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: Implicit 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun main() { + val arr = arrayOf(1, 2, 3) + val result = "Array: ${arr.contentToString()}" +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt new file mode 100644 index 000000000000..6787bb95f2f5 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun printItems(vararg items: Int) { + val s = items.toString() + println(s) +} diff --git a/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt.after b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt.after new file mode 100644 index 000000000000..b3c99ad704a0 --- /dev/null +++ b/plugins/kotlin/idea/tests/testData/inspectionsLocal/arrayToString/varargParameter.kt.after @@ -0,0 +1,9 @@ +// PROBLEM: 'toString()' called on array +// FIX: Replace with 'contentToString()' +// IGNORE_K1 +// WITH_STDLIB + +fun printItems(vararg items: Int) { + val s = items.contentToString() + println(s) +} diff --git a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2InspectionTests.kt b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2InspectionTests.kt index f581ab7ec3b9..d36ddba80d37 100644 --- a/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2InspectionTests.kt +++ b/plugins/kotlin/util/test-generator-fir/test/org/jetbrains/kotlin/fir/testGenerator/codeinsight/GenerateK2InspectionTests.kt @@ -60,6 +60,7 @@ internal fun MutableTWorkspace.generateK2InspectionTests() { model("${idea}/inspectionsLocal/redundantRequireNotNullCall") model("${idea}/inspectionsLocal/suspiciousCallOnCollectionToAddOrRemovePath") model("${idea}/inspectionsLocal/arrayHashCode") + model("${idea}/inspectionsLocal/arrayToString") model("${idea}/inspectionsLocal/stringReferentialEquality") model("${idea}/inspectionsLocal/suspiciousCascadingIf") model("${idea}/inspectionsLocal/equalsOrHashCode")