Boolean literal arguments: don't report on a call, just on an element

This commit is contained in:
Mikhail Glukhikh
2018-11-29 15:16:22 +03:00
parent 0d7116aa5d
commit d31e0b9632
7 changed files with 21 additions and 75 deletions
@@ -8,16 +8,16 @@ package org.jetbrains.kotlin.idea.inspections
import com.intellij.codeInspection.IntentionWrapper
import com.intellij.codeInspection.ProblemHighlightType.GENERIC_ERROR_OR_WARNING
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.KtNodeTypes
import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
import org.jetbrains.kotlin.idea.intentions.AddNameToArgumentIntention
import org.jetbrains.kotlin.idea.intentions.AddNamesToCallArgumentsIntention
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtCallExpression
import org.jetbrains.kotlin.psi.KtConstantExpression
import org.jetbrains.kotlin.psi.KtValueArgument
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.startOffset
import org.jetbrains.kotlin.psi.valueArgumentVisitor
class BooleanLiteralArgumentInspection : AbstractKotlinInspection() {
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean) =
@@ -37,21 +37,6 @@ class BooleanLiteralArgumentInspection : AbstractKotlinInspection() {
GENERIC_ERROR_OR_WARNING,
IntentionWrapper(AddNameToArgumentIntention(), argument.containingKtFile)
)
AddNamesToCallArgumentsIntention.canAddNamesToCallArguments(call) ->
holder.registerProblem(
holder.manager.createProblemDescriptor(
call,
argument.textRange.shiftRight(-call.startOffset),
description,
highlightType,
isOnTheFly,
IntentionWrapper(AddNamesIntention(), file)
)
)
}
})
private class AddNamesIntention : AddNamesToCallArgumentsIntention() {
override fun applicabilityRange(element: KtCallElement): TextRange? = element.textRange
}
}
@@ -23,12 +23,26 @@ import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
open class AddNamesToCallArgumentsIntention : SelfTargetingRangeIntention<KtCallElement>(
class AddNamesToCallArgumentsIntention : SelfTargetingRangeIntention<KtCallElement>(
KtCallElement::class.java,
"Add names to call arguments"
) {
override fun applicabilityRange(element: KtCallElement): TextRange? =
element.calleeExpression?.textRange?.takeIf { canAddNamesToCallArguments(element) }
override fun applicabilityRange(element: KtCallElement): TextRange? {
val arguments = element.valueArguments
if (arguments.all { it.isNamed() || it is LambdaArgument }) return null
val resolvedCall = element.resolveToCall() ?: return null
if (!resolvedCall.resultingDescriptor.hasStableParameterNames()) return null
if (arguments.all {
AddNameToArgumentIntention.argumentMatchedAndCouldBeNamedInCall(it, resolvedCall, element.languageVersionSettings)
}
) {
return element.calleeExpression?.textRange
}
return null
}
override fun applyTo(element: KtCallElement, editor: Editor?) {
val arguments = element.valueArguments
@@ -45,19 +59,4 @@ open class AddNamesToCallArgumentsIntention : SelfTargetingRangeIntention<KtCall
argument.replace(newArgument)
}
}
companion object {
fun canAddNamesToCallArguments(element: KtCallElement): Boolean {
val arguments = element.valueArguments
if (arguments.all { it.isNamed() || it is LambdaArgument }) return false
val resolvedCall = element.resolveToCall() ?: return false
if (!resolvedCall.resultingDescriptor.hasStableParameterNames()) return false
return arguments.all {
AddNameToArgumentIntention.argumentMatchedAndCouldBeNamedInCall(it, resolvedCall, element.languageVersionSettings)
}
}
}
}
@@ -1,7 +0,0 @@
// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
// FIX: Add names to call arguments
fun foo(a: Boolean, b: Boolean, c: Boolean) {}
fun test() {
foo(true, true<caret>, true)
}
@@ -1,7 +0,0 @@
// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
// FIX: Add names to call arguments
fun foo(a: Boolean, b: Boolean, c: Boolean) {}
fun test() {
foo(a = true, b = true, c = true)
}
@@ -1,7 +0,0 @@
// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
// FIX: Add names to call arguments
fun foo(a: Boolean, b: Boolean, c: Boolean) {}
fun test() {
foo(<caret>true, true, c = true)
}
@@ -1,7 +0,0 @@
// HIGHLIGHT: GENERIC_ERROR_OR_WARNING
// FIX: Add names to call arguments
fun foo(a: Boolean, b: Boolean, c: Boolean) {}
fun test() {
foo(a = true, b = true, c = true)
}
@@ -69,21 +69,11 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
runTest("idea/testData/inspectionsLocal/booleanLiteralArgument/booleanLiteral.kt");
}
@TestMetadata("booleanLiteral2.kt")
public void testBooleanLiteral2() throws Exception {
runTest("idea/testData/inspectionsLocal/booleanLiteralArgument/booleanLiteral2.kt");
}
@TestMetadata("booleanLiteral3.kt")
public void testBooleanLiteral3() throws Exception {
runTest("idea/testData/inspectionsLocal/booleanLiteralArgument/booleanLiteral3.kt");
}
@TestMetadata("booleanLiteral4.kt")
public void testBooleanLiteral4() throws Exception {
runTest("idea/testData/inspectionsLocal/booleanLiteralArgument/booleanLiteral4.kt");
}
@TestMetadata("hasError.kt")
public void testHasError() throws Exception {
runTest("idea/testData/inspectionsLocal/booleanLiteralArgument/hasError.kt");