Extended AssertThatSize inspection to transform hasSize() into hasSameSizeAs(), if possible.

This commit is contained in:
2019-04-23 20:16:43 +02:00
parent 8b0da63f86
commit 666e373405
11 changed files with 83 additions and 33 deletions
@@ -29,7 +29,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()"
const val REMOVE_EXPECTED_OUTMOST_DESCRIPTION_TEMPLATE = "Remove unwrapping of expected expression and replace %s() with %s()"
const val REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()"
const val UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE = "Unwrap actual expression and replace %s() with %s()"
val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf<IElementType, String>(
JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO,
@@ -219,7 +219,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
registerConciseMethod(REMOVE_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
registerConciseMethod(UNWRAP_ACTUAL_OUTMOST_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod, quickFixSupplier)
}
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
@@ -39,7 +39,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(GUAVA_OPTIONAL_OF, GUAVA_OPTIONAL_FROM_NULLABLE).test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
@@ -88,7 +88,7 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
) {
registerConciseMethod(REMOVE_EXPECTED_OUTMOST_GUAVA_DESCRIPTION_TEMPLATE, holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveExpectedOutmostMethodCallQuickFix(desc, method),
UnwrapExpectedStaticMethodCallQuickFix(desc, method),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
@@ -10,7 +10,7 @@ import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.RemoveExpectedOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.UnwrapExpectedStaticMethodCallQuickFix
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
@@ -33,7 +33,7 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (CallMatcher.anyOf(OPTIONAL_OF, OPTIONAL_OF_NULLABLE).test(innerExpectedCall)) {
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::UnwrapExpectedStaticMethodCallQuickFix)
} else if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT)
}
@@ -2,17 +2,17 @@ package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME
import de.platon42.intellij.plugins.cajon.MethodNames
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
class AssertThatSizeInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting the size of an collection, array or string"
private const val REMOVE_SIZE_DESCRIPTION_TEMPLATE = "Remove size determination of expected expression and replace %s() with %s()"
private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf(
IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN,
@@ -28,14 +28,29 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
return object : JavaElementVisitor() {
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
super.visitMethodCallExpression(expression)
if (!ASSERT_THAT_INT.test(expression)) {
val isAssertThatWithInt = ASSERT_THAT_INT.test(expression)
val isHasSize = HAS_SIZE.test(expression)
if (!(isAssertThatWithInt || isHasSize)) {
return
}
val actualExpression = expression.firstArg
val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
val isForString = isCharSequenceLength(actualExpression)
if (isForArrayOrCollection || isForString) {
if (isHasSize && (isForArrayOrCollection
|| (isForString && checkAssertedType(expression, ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME)))
) {
val assertThatCall = PsiTreeUtil.findChildrenOfType(expression, PsiMethodCallExpression::class.java).find { CORE_ASSERT_THAT_MATCHER.test(it) } ?: return
registerConciseMethod(
REMOVE_SIZE_DESCRIPTION_TEMPLATE,
holder,
assertThatCall,
expression,
MethodNames.HAS_SAME_SIZE_AS
) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true, keepActualAsIs = true)
}
} else if (isForArrayOrCollection || isForString) {
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val constValue = calculateConstantParameterValue(expectedCallExpression, 0)
if (IS_EQUAL_TO_INT.test(expectedCallExpression)) {