Convert 'simplify when' from intention to inspection
Related to KT-20492
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
<html>
|
||||
<body>
|
||||
This inspection detects 'when' with 'true' or 'false' branches that can be simplified.
|
||||
</body>
|
||||
</html>
|
||||
-1
@@ -1 +0,0 @@
|
||||
val foo = "foo"
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
val foo = when {
|
||||
true -> "foo"
|
||||
false -> "bar"
|
||||
else -> "baz"
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
<html>
|
||||
<body>
|
||||
This intention simplifies a when expression that has branch conditions which are true or false
|
||||
</body>
|
||||
</html>
|
||||
@@ -1650,11 +1650,6 @@
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<intentionAction>
|
||||
<className>org.jetbrains.kotlin.idea.inspections.SimplifyWhenWithBooleanConstantConditionIntention</className>
|
||||
<category>Kotlin</category>
|
||||
</intentionAction>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.intentions.ObjectLiteralToLambdaInspection"
|
||||
displayName="Object literal can be converted to lambda"
|
||||
groupPath="Kotlin"
|
||||
@@ -2678,6 +2673,16 @@
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
<localInspection implementationClass="org.jetbrains.kotlin.idea.inspections.SimplifyWhenWithBooleanConstantConditionInspection"
|
||||
displayName="Simplifiable 'when'"
|
||||
groupPath="Kotlin"
|
||||
groupName="Redundant constructs"
|
||||
enabledByDefault="true"
|
||||
level="WEAK WARNING"
|
||||
language="kotlin"
|
||||
/>
|
||||
|
||||
|
||||
<referenceImporter implementation="org.jetbrains.kotlin.idea.quickfix.KotlinReferenceImporter"/>
|
||||
|
||||
<fileType.fileViewProviderFactory filetype="KJSM" implementationClass="com.intellij.psi.ClassFileViewProviderFactory"/>
|
||||
|
||||
+38
-20
@@ -14,47 +14,64 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
package org.jetbrains.kotlin.idea.inspections
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.codeInspection.*
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.inspections.replaceWithBranch
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.isFalseConstant
|
||||
import org.jetbrains.kotlin.idea.intentions.loopToCallChain.isTrueConstant
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtWhenConditionWithExpression
|
||||
import org.jetbrains.kotlin.psi.KtWhenEntry
|
||||
import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression
|
||||
|
||||
class SimplifyWhenWithBooleanConstantConditionIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Simplify when expression") {
|
||||
class SimplifyWhenWithBooleanConstantConditionInspection : AbstractKotlinInspection() {
|
||||
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
if (element.closeBrace == null) return null
|
||||
if (element.subjectExpression != null) return null
|
||||
if (element.entries.none { it.isTrueConstantCondition() || it.isFalseConstantCondition() }) return null
|
||||
return element.whenKeyword.textRange
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||
return object : KtVisitorVoid() {
|
||||
|
||||
override fun visitWhenExpression(expression: KtWhenExpression) {
|
||||
super.visitWhenExpression(expression)
|
||||
|
||||
if (expression.closeBrace == null) return
|
||||
if (expression.subjectExpression != null) return
|
||||
if (expression.entries.none { it.isTrueConstantCondition() || it.isFalseConstantCondition() }) return
|
||||
|
||||
holder.registerProblem(expression.whenKeyword,
|
||||
"This 'when' is simplifiable",
|
||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||
SimplifyWhenFix())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor?) {
|
||||
private class SimplifyWhenFix : LocalQuickFix {
|
||||
override fun getName() = "Simplify 'when'"
|
||||
|
||||
override fun getFamilyName() = name
|
||||
|
||||
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
|
||||
val element = descriptor.psiElement.getStrictParentOfType<KtWhenExpression>() ?: return
|
||||
val closeBrace = element.closeBrace ?: return
|
||||
val project = editor?.project ?: return
|
||||
val factory = KtPsiFactory(project)
|
||||
val usedAsExpression = element.isUsedAsExpression(element.analyze())
|
||||
element.deleteFalseEntry(usedAsExpression)
|
||||
element.deleteFalseEntries(usedAsExpression)
|
||||
element.replaceTrueEntry(usedAsExpression, closeBrace, factory)
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtWhenExpression.deleteFalseEntry(usedAsExpression: Boolean) {
|
||||
private fun KtWhenExpression.deleteFalseEntries(usedAsExpression: Boolean) {
|
||||
for (entry in entries) {
|
||||
if (entry.isFalseConstantCondition()) {
|
||||
entry.delete()
|
||||
}
|
||||
}
|
||||
|
||||
val entries = entries
|
||||
if (entries.isEmpty() && !usedAsExpression) {
|
||||
delete()
|
||||
}
|
||||
@@ -64,6 +81,7 @@ private fun KtWhenExpression.deleteFalseEntry(usedAsExpression: Boolean) {
|
||||
}
|
||||
|
||||
private fun KtWhenExpression.replaceTrueEntry(usedAsExpression: Boolean, closeBrace: PsiElement, factory: KtPsiFactory) {
|
||||
val entries = entries
|
||||
val trueIndex = entries.indexOfFirst { it.isTrueConstantCondition() }
|
||||
if (trueIndex == -1) return
|
||||
|
||||
@@ -74,8 +92,8 @@ private fun KtWhenExpression.replaceTrueEntry(usedAsExpression: Boolean, closeBr
|
||||
}
|
||||
else {
|
||||
val elseEntry = factory.createWhenEntry("else -> ${expression.text}")
|
||||
for (index in trueIndex until entries.size) {
|
||||
entries[index].delete()
|
||||
for (entry in entries.subList(trueIndex, entries.size)) {
|
||||
entry.delete()
|
||||
}
|
||||
addBefore(elseEntry, closeBrace)
|
||||
}
|
||||
+1
@@ -0,0 +1 @@
|
||||
org.jetbrains.kotlin.idea.inspections.SimplifyWhenWithBooleanConstantConditionInspection
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// PROBLEM: none
|
||||
// WITH_RUNTIME
|
||||
fun test(b: Boolean) {
|
||||
<caret>when(b) {
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
// IS_APPLICABLE: false
|
||||
// PROBLEM: none
|
||||
// WITH_RUNTIME
|
||||
fun test(i: Int) {
|
||||
<caret>when {
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
// WITH_RUNTIME
|
||||
fun test() {
|
||||
when<caret> {
|
||||
wh<caret>en {
|
||||
true -> {
|
||||
println(1)
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
org.jetbrains.kotlin.idea.intentions.SimplifyWhenWithBooleanConstantConditionIntention
|
||||
@@ -2250,6 +2250,99 @@ public class LocalInspectionTestGenerated extends AbstractLocalInspectionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimplifyWhenWithBooleanConstantCondition extends AbstractLocalInspectionTest {
|
||||
public void testAllFilesPresentInSimplifyWhenWithBooleanConstantCondition() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse1.kt")
|
||||
public void testFalseAndElse1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseAndElse1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse2.kt")
|
||||
public void testFalseAndElse2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseAndElse2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse3.kt")
|
||||
public void testFalseAndElse3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseAndElse3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly1.kt")
|
||||
public void testFalseOnly1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseOnly1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly2.kt")
|
||||
public void testFalseOnly2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseOnly2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly3.kt")
|
||||
public void testFalseOnly3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/falseOnly3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("hasSubject.kt")
|
||||
public void testHasSubject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/hasSubject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noBoolean.kt")
|
||||
public void testNoBoolean() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/noBoolean.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop1.kt")
|
||||
public void testTrueIsNotTop1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsNotTop1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop2.kt")
|
||||
public void testTrueIsNotTop2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsNotTop2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop3.kt")
|
||||
public void testTrueIsNotTop3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsNotTop3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop1.kt")
|
||||
public void testTrueIsTop1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsTop1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop2.kt")
|
||||
public void testTrueIsTop2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsTop2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop3.kt")
|
||||
public void testTrueIsTop3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/inspectionsLocal/simplifyWhenWithBooleanConstantCondition/trueIsTop3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/inspectionsLocal/unnecessaryVariable")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
@@ -15216,99 +15216,6 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
public static class SimplifyWhenWithBooleanConstantCondition extends AbstractIntentionTest {
|
||||
public void testAllFilesPresentInSimplifyWhenWithBooleanConstantCondition() throws Exception {
|
||||
KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), TargetBackend.ANY, true);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse1.kt")
|
||||
public void testFalseAndElse1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseAndElse1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse2.kt")
|
||||
public void testFalseAndElse2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseAndElse2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseAndElse3.kt")
|
||||
public void testFalseAndElse3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseAndElse3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly1.kt")
|
||||
public void testFalseOnly1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseOnly1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly2.kt")
|
||||
public void testFalseOnly2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseOnly2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("falseOnly3.kt")
|
||||
public void testFalseOnly3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/falseOnly3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("hasSubject.kt")
|
||||
public void testHasSubject() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/hasSubject.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("noBooolean.kt")
|
||||
public void testNoBooolean() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/noBooolean.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop1.kt")
|
||||
public void testTrueIsNotTop1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsNotTop1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop2.kt")
|
||||
public void testTrueIsNotTop2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsNotTop2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsNotTop3.kt")
|
||||
public void testTrueIsNotTop3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsNotTop3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop1.kt")
|
||||
public void testTrueIsTop1() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsTop1.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop2.kt")
|
||||
public void testTrueIsTop2() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsTop2.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("trueIsTop3.kt")
|
||||
public void testTrueIsTop3() throws Exception {
|
||||
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/simplifyWhenWithBooleanConstantCondition/trueIsTop3.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
@TestMetadata("idea/testData/intentions/specifyExplicitLambdaSignature")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
@RunWith(JUnit3RunnerWithInners.class)
|
||||
|
||||
Reference in New Issue
Block a user