Implemented AssertThatBooleanIsTrueOrFalseInspection.

This commit is contained in:
2019-03-23 22:44:22 +01:00
parent 80104004d0
commit 8051511524
14 changed files with 241 additions and 12 deletions
@@ -7,14 +7,19 @@ import com.siyeh.ig.callMatcher.CallMatcher
open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
companion object {
private const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert"
private const val IS_EQUAL_TO = "isEqualTo"
private const val IS_NOT_EQUAL_TO = "isNotEqualTo"
const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert"
const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert"
const val IS_EQUAL_TO = "isEqualTo"
const val IS_NOT_EQUAL_TO = "isNotEqualTo"
val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO)
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_EQUAL_TO)
.parameterTypes("boolean")!!
val IS_NOT_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO)
.parameterTypes("boolean")!!
}
override fun getGroupDisplayName(): String {
@@ -0,0 +1,96 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.codeInspection.ProblemHighlightType
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.openapi.project.Project
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.util.TypeConversionUtil
import org.jetbrains.annotations.NonNls
class AssertThatBooleanIsTrueOrFalseInspection : AbstractAssertJInspection() {
companion object {
@NonNls
private val DISPLAY_NAME = "Asserting true or false"
@NonNls
private val INSPECTION_MESSAGE = "isEqualTo(true/false) can be simplified to isTrue()/isFalse()"
@NonNls
private val QUICKFIX_DESCRIPTION_IS_TRUE = "Replace isEqualTo(true/false) with isTrue()/isFalse()"
@NonNls
private val QUICKFIX_DESCRIPTION_NOT_IS_TRUE = "Replace isNotEqualTo(true/false) with isFalse()/isTrue()"
}
override fun getDisplayName() = DISPLAY_NAME
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
val isEqualToObject = IS_EQUAL_TO_OBJECT.test(expression)
val isEqualToBoolean = IS_EQUAL_TO_BOOLEAN.test(expression)
val isNotEqualToObject = IS_NOT_EQUAL_TO_OBJECT.test(expression)
val isNotEqualToBoolean = IS_NOT_EQUAL_TO_BOOLEAN.test(expression)
val normalBooleanTest = isEqualToObject || isEqualToBoolean
val flippedBooleanTest = isNotEqualToObject || isNotEqualToBoolean
if (!(normalBooleanTest || flippedBooleanTest)) {
return
}
var assertedType = expression.methodExpression.qualifierExpression?.type
if (assertedType is PsiCapturedWildcardType) {
assertedType = assertedType.upperBound
}
val assertedTypeIsBoolean =
assertedType?.canonicalText?.startsWith(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME) ?: false
val equalToExpression = expression.argumentList.expressions[0]!!
if (!TypeConversionUtil.isBooleanType(equalToExpression.type) || !assertedTypeIsBoolean) {
return
}
val constantEvaluationHelper = JavaPsiFacade.getInstance(holder.project).constantEvaluationHelper
var result = constantEvaluationHelper.computeConstantExpression(equalToExpression)
if (result == null) {
val field = (equalToExpression as? PsiReferenceExpression)?.resolve() as? PsiField
if (field?.containingClass?.qualifiedName == CommonClassNames.JAVA_LANG_BOOLEAN) {
when {
field.name == "TRUE" -> result = true
field.name == "FALSE" -> result = false
}
}
}
val expectedResult = result as? Boolean ?: return
holder.registerProblem(
expression,
INSPECTION_MESSAGE,
ProblemHighlightType.INFORMATION,
null as TextRange?,
ReplaceWithIsNullQuickFix(
expectedResult xor flippedBooleanTest,
if (flippedBooleanTest) QUICKFIX_DESCRIPTION_NOT_IS_TRUE else QUICKFIX_DESCRIPTION_IS_TRUE
)
)
}
}
}
private class ReplaceWithIsNullQuickFix(val expectedResult: Boolean, val quickfixName: String) : LocalQuickFix {
override fun getFamilyName() = quickfixName
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val factory = JavaPsiFacade.getElementFactory(element.project)
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val oldQualifier = methodCallExpression.methodExpression.qualifierExpression ?: return
val methodName = if (expectedResult) "isTrue()" else "isFalse()"
val isNullExpression =
factory.createExpressionFromText("a.$methodName", null) as PsiMethodCallExpression
isNullExpression.methodExpression.qualifierExpression!!.replace(oldQualifier)
element.replace(isNullExpression)
}
}
}
@@ -13,7 +13,7 @@ class AssertThatObjectIsNotNullInspection : AbstractAssertJInspection() {
companion object {
@NonNls
private val DISPLAY_NAME = "Comparing to non-null"
private val DISPLAY_NAME = "Asserting non-null"
@NonNls
private val INSPECTION_MESSAGE = "isNotEqualTo(null) can be simplified to isNotNull()"
@@ -13,7 +13,7 @@ class AssertThatObjectIsNullInspection : AbstractAssertJInspection() {
companion object {
@NonNls
private val DISPLAY_NAME = "Comparing to null"
private val DISPLAY_NAME = "Asserting null"
@NonNls
private val INSPECTION_MESSAGE = "isEqualTo(null) can be simplified to isNull()"
+3
View File
@@ -22,6 +22,9 @@
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNullInspection"/>
<localInspection groupPath="Java" shortName="AssertThatObjectIsNotNull" enabledByDefault="true" level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatObjectIsNotNullInspection"/>
<localInspection groupPath="Java" shortName="AssertThatBooleanIsTrueOrFalse" enabledByDefault="true"
level="WARNING"
implementationClass="de.platon42.intellij.plugins.cajon.inspections.AssertThatBooleanIsTrueOrFalseInspection"/>
</extensions>
<actions>
@@ -0,0 +1,7 @@
<html>
<body>
Turns assertThat(booleanExpression).isEqualTo(true/false) or assertThat(booleanExpression).isNotEqualTo(true/false)
into assertThat(booleanExpression).isTrue() or assertThat(booleanExpression).isFalse().
<!-- tooltip end -->
</body>
</html>