SimplifiableCallChainInspection: don't report if suspend function cannot be called correctly

#KT-23934 Fixed
This commit is contained in:
Toshiaki Kameyama
2020-01-29 14:15:57 +09:00
committed by Yan Zhulanow
parent 1e9bb00744
commit b008e6c9be
7 changed files with 60 additions and 3 deletions
@@ -68,7 +68,8 @@ abstract class AbstractCallChainChecker : AbstractKotlinInspection() {
@NonNls val secondFqName: String,
@NonNls val replacement: String,
@NonNls val additionalArgument: String? = null,
val withNotNullAssertion: Boolean = false
val withNotNullAssertion: Boolean = false,
val enableSuspendFunctionCall: Boolean = true
) {
private fun String.convertToShort() = takeLastWhile { it != '.' }
@@ -7,13 +7,17 @@ package org.jetbrains.kotlin.idea.inspections.collections
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.idea.KotlinBundle
import org.jetbrains.kotlin.js.resolve.JsPlatformAnalyzerServices
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.psiUtil.anyDescendantOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.qualifiedExpressionVisitor
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
import org.jetbrains.kotlin.types.typeUtil.builtIns
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
@@ -36,6 +40,12 @@ class SimplifiableCallChainInspection : AbstractCallChainChecker() {
}
) return@check false
}
if (!conversion.enableSuspendFunctionCall) {
val isCallingSuspendFunction = firstResolvedCall.call.callElement.anyDescendantOfType<KtCallExpression> {
it.getResolvedCall(context)?.resultingDescriptor?.isSuspend == true
}
if (isCallingSuspendFunction) return@check false
}
true
} ?: return
@@ -99,8 +109,8 @@ class SimplifiableCallChainInspection : AbstractCallChainChecker() {
Conversion("kotlin.text.filter", "kotlin.text.isNotEmpty", "any"),
Conversion("kotlin.text.filter", "kotlin.text.isEmpty", "none"),
Conversion("kotlin.collections.map", "kotlin.collections.joinTo", "joinTo"),
Conversion("kotlin.collections.map", "kotlin.collections.joinToString", "joinToString"),
Conversion("kotlin.collections.map", "kotlin.collections.joinTo", "joinTo", enableSuspendFunctionCall = false),
Conversion("kotlin.collections.map", "kotlin.collections.joinToString", "joinToString", enableSuspendFunctionCall = false),
Conversion("kotlin.collections.map", "kotlin.collections.filterNotNull", "mapNotNull"),
Conversion("kotlin.collections.listOf", "kotlin.collections.filterNotNull", "listOfNotNull")
@@ -0,0 +1,8 @@
// PROBLEM: none
// WITH_RUNTIME
suspend fun mapString(input: String): String = ""
suspend fun main() {
val x = listOf("1", "2", "3").<caret>map { mapString(it) }.joinToString()
}
@@ -0,0 +1,9 @@
// PROBLEM: none
// WITH_RUNTIME
suspend fun mapString(input: String): String = ""
suspend fun main() {
val sb = StringBuilder()
val x = listOf("1", "2", "3").<caret>map { mapString(it) }.joinTo(sb)
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
suspend fun mapString(input: String): String? = ""
suspend fun main() {
val x = listOf("1", "2", "3").<caret>map { mapString(it) }.filterNotNull()
}
@@ -0,0 +1,7 @@
// WITH_RUNTIME
suspend fun mapString(input: String): String? = ""
suspend fun main() {
val x = listOf("1", "2", "3").mapNotNull { mapString(it) }
}
@@ -1897,11 +1897,21 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/joinToStringWithReferenceFake.kt");
}
@TestMetadata("joinToStringWithSuspendFunctionCall.kt")
public void testJoinToStringWithSuspendFunctionCall() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/joinToStringWithSuspendFunctionCall.kt");
}
@TestMetadata("joinToWithComment.kt")
public void testJoinToWithComment() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/joinToWithComment.kt");
}
@TestMetadata("joinToWithSuspendFunctionCall.kt")
public void testJoinToWithSuspendFunctionCall() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/joinToWithSuspendFunctionCall.kt");
}
@TestMetadata("listOfNotNull.kt")
public void testListOfNotNull() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/listOfNotNull.kt");
@@ -1917,6 +1927,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/mapNotNull.kt");
}
@TestMetadata("mapNotNullWithSuspendFunctionCall.kt")
public void testMapNotNullWithSuspendFunctionCall() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/mapNotNullWithSuspendFunctionCall.kt");
}
@TestMetadata("mapWithReturn.kt")
public void testMapWithReturn() throws Exception {
runTest("idea/testData/inspectionsLocal/collections/simplifiableCallChain/mapWithReturn.kt");