[kotlin] "'StringBuilder.append(CharArray, offset, len)' call on the JVM": add !! for nullable CharArray

^KTIJ-22737 Fixed

closes https://github.com/JetBrains/intellij-community/pull/2154

GitOrigin-RevId: 5d5d8ab49727f51532487f8a394f19181c1b269f
This commit is contained in:
Toshiaki Kameyama
2022-09-13 07:58:07 +00:00
committed by intellij-monorepo-bot
parent ecf23ca073
commit 1ebf8b1cac
6 changed files with 49 additions and 0 deletions
@@ -12,10 +12,12 @@ import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.codeinsight.api.classic.inspections.AbstractKotlinInspection
import org.jetbrains.kotlin.idea.refactoring.fqName.fqName
import org.jetbrains.kotlin.idea.util.getDataFlowAwareTypes
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.isNullable
import org.jetbrains.kotlin.types.typeUtil.isInt
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
@@ -61,6 +63,7 @@ class ReplaceWithStringBuilderAppendRangeInspection : AbstractKotlinInspection()
val callExpression = calleeExpression.parent as? KtCallExpression ?: return
val args = callExpression.valueArguments
val firstArg = args.getOrNull(0)?.getArgumentExpression() ?: return
val secondArg = args.getOrNull(1)?.getArgumentExpression() ?: return
val thirdArg = args.getOrNull(2)?.getArgumentExpression() ?: return
@@ -74,11 +77,19 @@ class ReplaceWithStringBuilderAppendRangeInspection : AbstractKotlinInspection()
} else if (secondArgAsInt != 0) {
thirdArg.replace(psiFactory.createExpressionByPattern("$0 + $1", secondArg, thirdArg))
}
if (firstArg.isNullable()) {
firstArg.replace(psiFactory.createExpressionByPattern("$0!!", firstArg))
}
}
private fun KtPsiFactory.createCalleeExpression(functionName: String): KtExpression =
(createExpression("$functionName()") as KtCallExpression).calleeExpression!!
private fun KtExpression.toIntOrNull(): Int? = safeAs<KtConstantExpression>()?.text?.toIntOrNull()
private fun KtExpression.isNullable(): Boolean {
return getDataFlowAwareTypes(this).any { it.isNullable() }
}
}
}
@@ -13294,6 +13294,16 @@ public abstract class LocalInspectionTestGenerated extends AbstractLocalInspecti
runTest("testData/inspectionsLocal/replaceWithStringBuilderAppendRange/hasReceiver.kt");
}
@TestMetadata("nullableCharArray.kt")
public void testNullableCharArray() throws Exception {
runTest("testData/inspectionsLocal/replaceWithStringBuilderAppendRange/nullableCharArray.kt");
}
@TestMetadata("nullableCharArray2.kt")
public void testNullableCharArray2() throws Exception {
runTest("testData/inspectionsLocal/replaceWithStringBuilderAppendRange/nullableCharArray2.kt");
}
@TestMetadata("precedence.kt")
public void testPrecedence() throws Exception {
runTest("testData/inspectionsLocal/replaceWithStringBuilderAppendRange/precedence.kt");
@@ -0,0 +1,6 @@
// WITH_STDLIB
fun test(charArray: CharArray?, len: Int): String {
return buildString {
<caret>append(charArray, 0, len)
}
}
@@ -0,0 +1,6 @@
// WITH_STDLIB
fun test(charArray: CharArray?, len: Int): String {
return buildString {
appendRange(charArray!!, 0, len)
}
}
@@ -0,0 +1,8 @@
// WITH_STDLIB
fun test(charArray: CharArray?, len: Int): String {
return buildString {
if (charArray != null) {
<caret>append(charArray, 0, len)
}
}
}
@@ -0,0 +1,8 @@
// WITH_STDLIB
fun test(charArray: CharArray?, len: Int): String {
return buildString {
if (charArray != null) {
appendRange(charArray, 0, len)
}
}
}