diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt b/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt new file mode 100644 index 0000000..26b6b11 --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/cajon/AssertJClassNames.kt @@ -0,0 +1,32 @@ +package de.platon42.intellij.plugins.cajon + +import org.jetbrains.annotations.NonNls + +class AssertJClassNames { + companion object { + @NonNls + const val ASSERTIONS_CLASSNAME = "org.assertj.core.api.Assertions" + + @NonNls + const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert" + @NonNls + const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert" + @NonNls + const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert" + @NonNls + const val ABSTRACT_COMPARABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractComparableAssert" + @NonNls + const val ABSTRACT_STRING_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractStringAssert" + @NonNls + const val ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractCharSequenceAssert" + @NonNls + const val ABSTRACT_ITERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIterableAssert" + @NonNls + const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert" + + @NonNls + const val GUAVA_OPTIONAL_CLASSNAME = "com.google.common.base.Optional" + @NonNls + const val GUAVA_ASSERTIONS_CLASSNAME = "org.assertj.guava.api.Assertions" + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt b/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt index e2319f5..0ce1d11 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/Extensions.kt @@ -15,3 +15,5 @@ fun PsiMethodCallExpression.replaceQualifierFromMethodCall(oldMethodCall: PsiMet } fun PsiMethodCallExpression.getArg(n: Int): PsiExpression = this.argumentList.expressions[n] + +fun Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt b/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt new file mode 100644 index 0000000..6b365ed --- /dev/null +++ b/src/main/java/de/platon42/intellij/plugins/cajon/MethodNames.kt @@ -0,0 +1,78 @@ +package de.platon42.intellij.plugins.cajon + +import org.jetbrains.annotations.NonNls + +class MethodNames { + + companion object { + + @NonNls + const val EQUALS = "equals" + + @NonNls + const val ASSERT_THAT = "assertThat" + @NonNls + const val AS = "as" + @NonNls + const val IS_EQUAL_TO = "isEqualTo" + @NonNls + const val IS_NOT_EQUAL_TO = "isNotEqualTo" + @NonNls + const val IS_SAME_AS = "isSameAs" + @NonNls + const val IS_NOT_SAME_AS = "isNotSameAs" + @NonNls + const val IS_GREATER_THAN = "isGreaterThan" + @NonNls + const val IS_GREATER_THAN_OR_EQUAL_TO = "isGreaterThanOrEqualTo" + @NonNls + const val IS_LESS_THAN = "isLessThan" + @NonNls + const val IS_LESS_THAN_OR_EQUAL_TO = "isLessThanOrEqualTo" + @NonNls + const val IS_ZERO = "isZero" + @NonNls + const val IS_NOT_ZERO = "isNotZero" + @NonNls + const val IS_TRUE = "isTrue" + @NonNls + const val IS_FALSE = "isFalse" + @NonNls + const val IS_NULL = "isNull" + @NonNls + const val IS_NOT_NULL = "isNotNull" + @NonNls + const val IS_CLOSE_TO = "isCloseTo" + @NonNls + const val IS_NOT_CLOSE_TO = "isNotCloseTo" + + @NonNls + const val IS_EMPTY = "isEmpty" + @NonNls + const val IS_NOT_EMPTY = "isNotEmpty" + @NonNls + const val HAS_SIZE = "hasSize" + @NonNls + const val HAS_SIZE_LESS_THAN = "hasSizeLessThan" + @NonNls + const val HAS_SIZE_LESS_THAN_OR_EQUAL_TO = "hasSizeLessThanOrEqualTo" + @NonNls + const val HAS_SIZE_GREATER_THAN = "hasSizeGreaterThan" + @NonNls + const val HAS_SIZE_GREATER_THAN_OR_EQUAL_TO = "hasSizeGreaterThanOrEqualTo" + @NonNls + const val HAS_SAME_SIZE_AS = "hasSameSizeAs" + @NonNls + const val CONTAINS = "contains" + @NonNls + const val CONTAINS_EXACTLY = "containsExactly" + @NonNls + const val CONTAINS_SAME = "containsSame" + @NonNls + const val IS_PRESENT = "isPresent" + @NonNls + const val IS_NOT_PRESENT = "isNotPresent" + @NonNls + const val IS_ABSENT = "isAbsent" + } +} \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt index a3bee2c..a464f15 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractAssertJInspection.kt @@ -7,81 +7,40 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.tree.IElementType import com.intellij.psi.util.PsiTypesUtil import com.siyeh.ig.callMatcher.CallMatcher +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_BOOLEAN_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_COMPARABLE_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_INTEGER_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ASSERTIONS_CLASSNAME +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.getArg import de.platon42.intellij.plugins.cajon.qualifierExpression import de.platon42.intellij.plugins.cajon.quickfixes.RemoveActualOutmostMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceExpectedOutmostMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix -import org.jetbrains.annotations.NonNls open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { companion object { - const val SIMPLIFY_MESSAGE_TEMPLATE = "%s can be simplified to %s" - const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s would be more concise than %s" - - const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s with %s" - - @NonNls - const val ASSERTIONS_CLASSNAME = "org.assertj.core.api.Assertions" - - @NonNls - const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert" - @NonNls - const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert" - @NonNls - const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert" - @NonNls - const val ABSTRACT_COMPARABLE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractComparableAssert" - @NonNls - const val ABSTRACT_STRING_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractStringAssert" - @NonNls - const val ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractCharSequenceAssert" - @NonNls - const val ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME = "org.assertj.core.api.EnumerableAssert" - - @NonNls - const val ASSERT_THAT_METHOD = "assertThat" - @NonNls - const val IS_EQUAL_TO_METHOD = "isEqualTo" - @NonNls - const val IS_NOT_EQUAL_TO_METHOD = "isNotEqualTo" - @NonNls - const val IS_SAME_AS_METHOD = "isSameAs" - @NonNls - const val IS_NOT_SAME_AS_METHOD = "isNotSameAs" - @NonNls - const val IS_GREATER_THAN_METHOD = "isGreaterThan" - @NonNls - const val IS_GREATER_THAN_OR_EQUAL_TO_METHOD = "isGreaterThanOrEqualTo" - @NonNls - const val IS_LESS_THAN_METHOD = "isLessThan" - @NonNls - const val IS_LESS_THAN_OR_EQUAL_TO_METHOD = "isLessThanOrEqualTo" - @NonNls - const val IS_ZERO_METHOD = "isZero" - @NonNls - const val IS_NOT_ZERO_METHOD = "isNotZero" - @NonNls - const val IS_TRUE_METHOD = "isTrue" - @NonNls - const val IS_FALSE_METHOD = "isFalse" - @NonNls - const val HAS_SIZE_METHOD = "hasSize" + const val SIMPLIFY_MESSAGE_TEMPLATE = "%s() can be simplified to %s()" + const val MORE_CONCISE_MESSAGE_TEMPLATE = "%s() would be more concise than %s" + const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()" val TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP = mapOf( - JavaTokenType.EQEQ to IS_EQUAL_TO_METHOD, - JavaTokenType.NE to IS_NOT_EQUAL_TO_METHOD, - JavaTokenType.GT to IS_GREATER_THAN_METHOD, - JavaTokenType.GE to IS_GREATER_THAN_OR_EQUAL_TO_METHOD, - JavaTokenType.LT to IS_LESS_THAN_METHOD, - JavaTokenType.LE to IS_LESS_THAN_OR_EQUAL_TO_METHOD + JavaTokenType.EQEQ to MethodNames.IS_EQUAL_TO, + JavaTokenType.NE to MethodNames.IS_NOT_EQUAL_TO, + JavaTokenType.GT to MethodNames.IS_GREATER_THAN, + JavaTokenType.GE to MethodNames.IS_GREATER_THAN_OR_EQUAL_TO, + JavaTokenType.LT to MethodNames.IS_LESS_THAN, + JavaTokenType.LE to MethodNames.IS_LESS_THAN_OR_EQUAL_TO ) val TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS = mapOf( - JavaTokenType.EQEQ to IS_SAME_AS_METHOD, - JavaTokenType.NE to IS_NOT_SAME_AS_METHOD + JavaTokenType.EQEQ to MethodNames.IS_SAME_AS, + JavaTokenType.NE to MethodNames.IS_NOT_SAME_AS ) val SWAP_SIDE_OF_BINARY_OPERATOR = mapOf( @@ -101,55 +60,58 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { ) - val ASSERT_THAT_INT = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, ASSERT_THAT_METHOD) + val ASSERT_THAT_INT = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) .parameterTypes("int")!! - val ASSERT_THAT_BOOLEAN = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, ASSERT_THAT_METHOD) + val ASSERT_THAT_BOOLEAN = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) .parameterTypes("boolean")!! - val ASSERT_THAT_ANY = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, ASSERT_THAT_METHOD) + val ASSERT_THAT_ANY = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) .parameterCount(1)!! - val ASSERT_THAT_JAVA8_OPTIONAL = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, ASSERT_THAT_METHOD) + val ASSERT_THAT_JAVA8_OPTIONAL = CallMatcher.staticCall(ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) .parameterTypes(CommonClassNames.JAVA_UTIL_OPTIONAL)!! - val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) + val ASSERT_THAT_GUAVA_OPTIONAL = CallMatcher.staticCall(GUAVA_ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT) + .parameterTypes()!! + + val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO) .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! - val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO_METHOD) + val IS_NOT_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_NOT_EQUAL_TO) .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! - val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) + val IS_EQUAL_TO_BOOLEAN = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO) .parameterTypes("boolean")!! val IS_NOT_EQUAL_TO_BOOLEAN = - CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_NOT_EQUAL_TO_METHOD) + CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_NOT_EQUAL_TO) .parameterTypes("boolean")!! - val IS_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_SAME_AS_METHOD) + val IS_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_SAME_AS) .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! - val IS_NOT_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_NOT_SAME_AS_METHOD) + val IS_NOT_SAME_AS_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_NOT_SAME_AS) .parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!! - val HAS_SIZE = CallMatcher.instanceCall(ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME, HAS_SIZE_METHOD) + val HAS_SIZE = CallMatcher.instanceCall(ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE) .parameterTypes("int")!! - val IS_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, IS_EQUAL_TO_METHOD) + val IS_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO) .parameterTypes("int")!! - val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_GREATER_THAN_METHOD) + val IS_GREATER_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN) .parameterTypes("int")!! - val IS_GREATER_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_GREATER_THAN_OR_EQUAL_TO_METHOD) + val IS_GREATER_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_GREATER_THAN_OR_EQUAL_TO) .parameterTypes("int")!! - val IS_LESS_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_LESS_THAN_METHOD) + val IS_LESS_THAN_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_LESS_THAN) .parameterTypes("int")!! - val IS_LESS_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, IS_LESS_THAN_OR_EQUAL_TO_METHOD) + val IS_LESS_THAN_OR_EQUAL_TO_INT = CallMatcher.instanceCall(ABSTRACT_COMPARABLE_ASSERT_CLASSNAME, MethodNames.IS_LESS_THAN_OR_EQUAL_TO) .parameterTypes("int")!! - val IS_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, IS_ZERO_METHOD) + val IS_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, MethodNames.IS_ZERO) .parameterCount(0)!! - val IS_NOT_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, IS_NOT_ZERO_METHOD) + val IS_NOT_ZERO = CallMatcher.instanceCall(ABSTRACT_INTEGER_ASSERT_CLASSNAME, MethodNames.IS_NOT_ZERO) .parameterCount(0)!! - val IS_TRUE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_TRUE_METHOD) + val IS_TRUE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_TRUE) .parameterCount(0)!! - val IS_FALSE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, IS_FALSE_METHOD) + val IS_FALSE = CallMatcher.instanceCall(ABSTRACT_BOOLEAN_ASSERT_CLASSNAME, MethodNames.IS_FALSE) .parameterCount(0)!! val COLLECTION_SIZE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size") @@ -185,8 +147,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { return assertedClass.isEquivalentTo(expectedClass) || assertedClass.isInheritor(expectedClass, true) } - protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = - expression.resolveMethod()?.name?.plus("()") + protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = expression.resolveMethod()?.name protected fun registerSimplifyMethod( holder: ProblemsHolder, @@ -261,11 +222,10 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() { return null } - protected fun hasAssertJMethod(element: PsiElement, classAndMethod: String): Boolean { - val classname = "org.assertj.core.api.${classAndMethod.substringBeforeLast(".")}" + protected fun hasAssertJMethod(element: PsiElement, classname: String, methodname: String): Boolean { val findClass = JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project)) ?: return false - return findClass.findMethodsByName(classAndMethod.substringAfterLast(".")).isNotEmpty() + return findClass.findMethodsByName(methodname).isNotEmpty() } } \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt index a21bd09..aae1115 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AbstractJUnitAssertInspection.kt @@ -9,7 +9,7 @@ open class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool() companion object { const val CONVERT_MESSAGE_TEMPLATE = "%s can be converted to AssertJ style" - const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s with assertThat().%s" + const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with assertThat().%s()" @NonNls const val JUNIT_ASSERT_CLASSNAME = "org.junit.Assert" @@ -38,6 +38,5 @@ open class AbstractJUnitAssertInspection : AbstractBaseJavaLocalInspectionTool() return "AssertJ" } - protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = - expression.resolveMethod()?.name?.plus("()") + protected fun getOriginalMethodName(expression: PsiMethodCallExpression) = expression.resolveMethod()?.name } \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBinaryExpressionIsTrueOrFalseInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBinaryExpressionIsTrueOrFalseInspection.kt index bf8981e..b6dc738 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBinaryExpressionIsTrueOrFalseInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBinaryExpressionIsTrueOrFalseInspection.kt @@ -4,7 +4,11 @@ import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil import com.intellij.psi.util.TypeConversionUtil +import de.platon42.intellij.plugins.cajon.MethodNames +import de.platon42.intellij.plugins.cajon.MethodNames.Companion.IS_NOT_NULL +import de.platon42.intellij.plugins.cajon.MethodNames.Companion.IS_NULL import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.quickfixes.SplitBinaryExpressionMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.SplitEqualsExpressionMethodCallQuickFix @@ -12,10 +16,8 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect companion object { private const val DISPLAY_NAME = "Asserting a binary expression" - private const val SPLIT_BINARY_EXPRESSION_DESCRIPTION = "Split binary expression out of assertThat()" - private const val SPLIT_EQUALS_EXPRESSION_DESCRIPTION = "Split equals() expression out of assertThat()" - private const val BINARY_MORE_MEANINGFUL_MESSAGE = "Moving binary expression out of assertThat() would be more meaningful" - private const val EQUALS_MORE_MEANINGFUL_MESSAGE = "Moving equals() expression out of assertThat() would be more meaningful" + private const val SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE = "Split %s expression out of assertThat()" + private const val MORE_MEANINGFUL_MESSAGE_TEMPLATE = "Moving %s expression out of assertThat() would be more meaningful" } override fun getDisplayName() = DISPLAY_NAME @@ -34,9 +36,12 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect val assertThatArgument = expression.firstArg if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) { - val replacementMethod = if (expectedResult) "isEqualTo()" else "isNotEqualTo()" - val quickFix = SplitEqualsExpressionMethodCallQuickFix(SPLIT_EQUALS_EXPRESSION_DESCRIPTION, replacementMethod) - holder.registerProblem(expression, EQUALS_MORE_MEANINGFUL_MESSAGE, quickFix) + val replacementMethod = if (expectedResult) MethodNames.IS_EQUAL_TO else MethodNames.IS_NOT_EQUAL_TO + val type = "${MethodNames.EQUALS}()" + val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type) + val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type) + val quickFix = SplitEqualsExpressionMethodCallQuickFix(description, replacementMethod) + holder.registerProblem(expression, message, quickFix) return } @@ -50,7 +55,7 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect if (isLeftNull && isRightNull) { return } else if (isLeftNull || isRightNull) { - val replacementMethod = if (expectedResult) "isNull()" else "isNotNull()" + val replacementMethod = if (expectedResult) IS_NULL else IS_NOT_NULL registerSplitBinaryExpressionMethod(holder, expression, replacementMethod, pickRightOperand = isLeftNull, noExpectedExpression = true) return } @@ -68,14 +73,10 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect if (expectedResult) it else INVERT_BINARY_OPERATOR.getOrDefault(it, it) } ?: return val mappingToUse = - if (isPrimitive || isNumericType) { - TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP - } else { - TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS - } + (isPrimitive || isNumericType).map(TOKEN_TO_ASSERTJ_FOR_PRIMITIVE_MAP, TOKEN_TO_ASSERTJ_FOR_OBJECT_MAPPINGS) val replacementMethod = mappingToUse[tokenType] ?: return - registerSplitBinaryExpressionMethod(holder, expression, "$replacementMethod()", pickRightOperand = swapExpectedAndActual) + registerSplitBinaryExpressionMethod(holder, expression, replacementMethod, pickRightOperand = swapExpectedAndActual) } private fun registerSplitBinaryExpressionMethod( @@ -85,8 +86,11 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect pickRightOperand: Boolean = false, noExpectedExpression: Boolean = false ) { - val quickFix = SplitBinaryExpressionMethodCallQuickFix(SPLIT_BINARY_EXPRESSION_DESCRIPTION, replacementMethod, pickRightOperand, noExpectedExpression) - holder.registerProblem(expression, BINARY_MORE_MEANINGFUL_MESSAGE, quickFix) + val type = "binary" + val description = SPLIT_EXPRESSION_DESCRIPTION_TEMPLATE.format(type) + val message = MORE_MEANINGFUL_MESSAGE_TEMPLATE.format(type) + val quickFix = SplitBinaryExpressionMethodCallQuickFix(description, replacementMethod, pickRightOperand, noExpectedExpression) + holder.registerProblem(expression, message, quickFix) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBooleanIsTrueOrFalseInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBooleanIsTrueOrFalseInspection.kt index f5bc260..60a027e 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBooleanIsTrueOrFalseInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatBooleanIsTrueOrFalseInspection.kt @@ -5,7 +5,10 @@ import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.util.TypeConversionUtil +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_BOOLEAN_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map class AssertThatBooleanIsTrueOrFalseInspection : AbstractAssertJInspection() { @@ -37,7 +40,7 @@ class AssertThatBooleanIsTrueOrFalseInspection : AbstractAssertJInspection() { val expectedResult = calculateConstantParameterValue(expression, 0) as? Boolean ?: return val flippedBooleanTest = matchingCalls.drop(2).any { it } - val replacementMethod = if (expectedResult xor flippedBooleanTest) "isTrue()" else "isFalse()" + val replacementMethod = (expectedResult xor flippedBooleanTest).map(MethodNames.IS_TRUE, MethodNames.IS_FALSE) registerSimplifyMethod(holder, expression, replacementMethod) } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatEnumerableIsEmptyInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatEnumerableIsEmptyInspection.kt index fd07ab9..8d14403 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatEnumerableIsEmptyInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatEnumerableIsEmptyInspection.kt @@ -4,6 +4,7 @@ import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression +import de.platon42.intellij.plugins.cajon.MethodNames class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() { @@ -23,7 +24,7 @@ class AssertThatEnumerableIsEmptyInspection : AbstractAssertJInspection() { val value = calculateConstantParameterValue(expression, 0) ?: return if (value == 0) { - registerSimplifyMethod(holder, expression, "isEmpty()") + registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt index df8117a..4fe0c7a 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatJava8OptionalInspection.kt @@ -6,7 +6,9 @@ import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiStatement import com.intellij.psi.util.PsiTreeUtil +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { @@ -30,14 +32,14 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return if (OPTIONAL_OF.test(innerExpectedCall) || OPTIONAL_OF_NULLABLE.test(innerExpectedCall)) { - registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, "contains()") + registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) } else if (OPTIONAL_EMPTY.test(innerExpectedCall)) { - registerSimplifyMethod(holder, expectedCallExpression, "isNotPresent()") + registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT) } } else if (IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)) { val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return if (OPTIONAL_EMPTY.test(innerExpectedCall)) { - registerSimplifyMethod(holder, expectedCallExpression, "isPresent()") + registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT) } } } else { @@ -48,13 +50,13 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() { if (isGet || isIsPresent) { if (isGet) { if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) { - registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, "contains()") + registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) } else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) { - registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, "containsSame()") + registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME) } } else { val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return - val replacementMethod = if (expectedPresence) "isPresent()" else "isNotPresent()" + val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT) registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true) } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatObjectIsNullOrNotNullInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatObjectIsNullOrNotNullInspection.kt index f4e56fb..fb96191 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatObjectIsNullOrNotNullInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatObjectIsNullOrNotNullInspection.kt @@ -5,7 +5,9 @@ import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiType +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map class AssertThatObjectIsNullOrNotNullInspection : AbstractAssertJInspection() { @@ -26,7 +28,7 @@ class AssertThatObjectIsNullOrNotNullInspection : AbstractAssertJInspection() { } if (expression.firstArg.type == PsiType.NULL) { - registerSimplifyMethod(holder, expression, if (isEqualTo) "isNull()" else "isNotNull()") + registerSimplifyMethod(holder, expression, isEqualTo.map(MethodNames.IS_NULL, MethodNames.IS_NOT_NULL)) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt index 7a86a2c..c812968 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatSizeInspection.kt @@ -3,18 +3,22 @@ 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.AssertJClassNames.Companion.ABSTRACT_ITERABLE_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.MethodNames 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 or array" + private val BONUS_EXPRESSIONS_CALL_MATCHER_MAP = listOf( - IS_GREATER_THAN_INT to "hasSizeGreaterThan()", - IS_GREATER_THAN_OR_EQUAL_TO_INT to "hasSizeGreaterThanOrEqualTo()", - IS_LESS_THAN_OR_EQUAL_TO_INT to "hasSizeLessThanOrEqualTo()", - IS_LESS_THAN_INT to "hasSizeLessThan()" + IS_LESS_THAN_INT to MethodNames.HAS_SIZE_LESS_THAN, + IS_LESS_THAN_OR_EQUAL_TO_INT to MethodNames.HAS_SIZE_LESS_THAN_OR_EQUAL_TO, + IS_GREATER_THAN_INT to MethodNames.HAS_SIZE_GREATER_THAN, + IS_GREATER_THAN_OR_EQUAL_TO_INT to MethodNames.HAS_SIZE_GREATER_THAN_OR_EQUAL_TO ) } @@ -35,13 +39,13 @@ class AssertThatSizeInspection : AbstractAssertJInspection() { val constValue = calculateConstantParameterValue(expectedCallExpression, 0) if (IS_EQUAL_TO_INT.test(expectedCallExpression)) { if (constValue == 0) { - registerReplaceSizeMethod(holder, expression, expectedCallExpression, "isEmpty()", noExpectedExpression = true) + registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY, noExpectedExpression = true) } else { val equalToExpression = expectedCallExpression.firstArg if (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) { - registerReplaceSizeMethod(holder, expression, expectedCallExpression, "hasSameSizeAs()", expectedIsCollection = true) + registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS, expectedIsCollection = true) } else { - registerReplaceSizeMethod(holder, expression, expectedCallExpression, "hasSize()") + registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE) } } } else { @@ -51,14 +55,13 @@ class AssertThatSizeInspection : AbstractAssertJInspection() { val isTestForNotEmpty = ((IS_GREATER_THAN_INT.test(expectedCallExpression) && (constValue == 0)) || (IS_GREATER_THAN_OR_EQUAL_TO_INT.test(expectedCallExpression) && (constValue == 1)) || IS_NOT_ZERO.test(expectedCallExpression)) - when { - isTestForEmpty -> registerReplaceSizeMethod(holder, expression, expectedCallExpression, "isEmpty()", noExpectedExpression = true) - isTestForNotEmpty -> registerReplaceSizeMethod(holder, expression, expectedCallExpression, "isNotEmpty()", noExpectedExpression = true) + if (isTestForEmpty || isTestForNotEmpty) { + val replacementMethod = isTestForEmpty.map(MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY) + registerReplaceSizeMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true) + } else if (hasAssertJMethod(expression, ABSTRACT_ITERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE_LESS_THAN)) { // new stuff in AssertJ 13.2.0 - hasAssertJMethod(expression, "AbstractIterableAssert.hasSizeLessThan") -> { - val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return - registerReplaceSizeMethod(holder, expression, expectedCallExpression, matchedMethod) - } + val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return + registerReplaceSizeMethod(holder, expression, expectedCallExpression, matchedMethod) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatStringIsEmptyInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatStringIsEmptyInspection.kt index d68a395..48176dd 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatStringIsEmptyInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/AssertThatStringIsEmptyInspection.kt @@ -4,6 +4,8 @@ import com.intellij.codeInspection.ProblemsHolder import com.intellij.psi.JavaElementVisitor import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME +import de.platon42.intellij.plugins.cajon.MethodNames class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() { @@ -29,7 +31,7 @@ class AssertThatStringIsEmptyInspection : AbstractAssertJInspection() { val value = calculateConstantParameterValue(expression, 0) ?: return if ((isEqual && (value == "")) || (hasSize && (value == 0))) { - registerSimplifyMethod(holder, expression, "isEmpty()") + registerSimplifyMethod(holder, expression, MethodNames.IS_EMPTY) } } } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt index 78a280e..248b17c 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/inspections/JUnitAssertToAssertJInspection.kt @@ -7,6 +7,7 @@ import com.intellij.psi.PsiElementVisitor import com.intellij.psi.PsiMethodCallExpression import com.siyeh.ig.callMatcher.CallMatcher import com.siyeh.ig.callMatcher.CallMatcher.anyOf +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitDeltaAssertMethodCallQuickFix @@ -21,28 +22,28 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_TRUE_METHOD).parameterTypes("boolean") ), - "isTrue()", false + MethodNames.IS_TRUE, false ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "boolean"), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_FALSE_METHOD).parameterTypes("boolean") ), - "isFalse()", false + MethodNames.IS_FALSE, false ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) ), - "isNull()", false + MethodNames.IS_NULL, false ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, CommonClassNames.JAVA_LANG_OBJECT), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_NULL_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_OBJECT) ), - "isNotNull()", false + MethodNames.IS_NOT_NULL, false ), Mapping( anyOf( @@ -51,14 +52,14 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterTypes("float", "float", "float") ), - "isCloseTo()", hasDelta = true + MethodNames.IS_CLOSE_TO, hasDelta = true ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(3), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_EQUALS_METHOD).parameterCount(2) ), - "isEqualTo()" + MethodNames.IS_EQUAL_TO ), Mapping( anyOf( @@ -67,28 +68,28 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float", "float", "float"), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterTypes("float", "float", "float") ), - "isNotCloseTo()", hasDelta = true + MethodNames.IS_NOT_CLOSE_TO, hasDelta = true ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(3), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_EQUALS_METHOD).parameterCount(2) ), - "isNotEqualTo()" + MethodNames.IS_NOT_EQUAL_TO ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(3), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_SAME_METHOD).parameterCount(2) ), - "isSameAs()" + MethodNames.IS_SAME_AS ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(3), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_NOT_SAME_METHOD).parameterCount(2) ), - "isNotSameAs()" + MethodNames.IS_NOT_SAME_AS ), Mapping( anyOf( @@ -97,14 +98,14 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes(CommonClassNames.JAVA_LANG_STRING, "float[]", "float[]", "float"), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterTypes("float[]", "float[]", "float") ), - "containsExactly()", hasDelta = true + MethodNames.CONTAINS_EXACTLY, hasDelta = true ), Mapping( anyOf( CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(2), CallMatcher.staticCall(JUNIT_ASSERT_CLASSNAME, ASSERT_ARRAY_EQUALS_METHOD).parameterCount(3) ), - "containsExactly()" + MethodNames.CONTAINS_EXACTLY ) ) } @@ -142,7 +143,7 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() { val originalMethod = getOriginalMethodName(expression) ?: return val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod) val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod) - val quickFix = ReplaceJUnitAssertMethodCallQuickFix(description, hasExpected, replacementMethod) + val quickFix = ReplaceJUnitAssertMethodCallQuickFix(description, !hasExpected, replacementMethod) holder.registerProblem(expression, message, quickFix) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/AbstractCommonQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/AbstractCommonQuickFix.kt index 2234d25..5efe2c7 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/AbstractCommonQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/AbstractCommonQuickFix.kt @@ -1,21 +1,15 @@ package de.platon42.intellij.plugins.cajon.quickfixes import com.intellij.codeInspection.LocalQuickFix -import com.intellij.psi.PsiElementFactory -import com.intellij.psi.PsiJavaFile -import com.intellij.psi.PsiMethod -import com.intellij.psi.PsiMethodCallExpression -import org.jetbrains.annotations.NonNls +import com.intellij.psi.* +import de.platon42.intellij.plugins.cajon.AssertJClassNames +import de.platon42.intellij.plugins.cajon.MethodNames +import de.platon42.intellij.plugins.cajon.firstArg abstract class AbstractCommonQuickFix(private val description: String) : LocalQuickFix { override fun getFamilyName() = description - companion object { - @NonNls - const val GUAVA_ASSERTIONS_CLASSNAME = "org.assertj.guava.api.Assertions" - } - protected fun addStaticImport(method: PsiMethod, element: PsiMethodCallExpression, factory: PsiElementFactory, vararg allowedClashes: String) { val methodName = method.name val containingClass = method.containingClass ?: return @@ -29,4 +23,13 @@ abstract class AbstractCommonQuickFix(private val description: String) : LocalQu importList.add(factory.createImportStaticStatement(containingClass, methodName)) } } + + protected fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression { + val factory = JavaPsiFacade.getElementFactory(context.project) + val newMethodCall = factory.createExpressionFromText( + "${AssertJClassNames.ASSERTIONS_CLASSNAME}.${MethodNames.ASSERT_THAT}(a)", context + ) as PsiMethodCallExpression + newMethodCall.firstArg.replace(actualExpression) + return newMethodCall + } } \ No newline at end of file diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveActualOutmostMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveActualOutmostMethodCallQuickFix.kt index 0d18b1b..3d70865 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveActualOutmostMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/RemoveActualOutmostMethodCallQuickFix.kt @@ -7,6 +7,7 @@ import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiStatement import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.qualifierExpression import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall @@ -25,8 +26,9 @@ class RemoveActualOutmostMethodCallQuickFix( val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val factory = JavaPsiFacade.getElementFactory(element.project) - val expectedExpression = - factory.createExpressionFromText("a.${if (noExpectedExpression) replacementMethod else replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression + val expectedExpression = factory.createExpressionFromText( + "a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element + ) as PsiMethodCallExpression if (!noExpectedExpression) { expectedExpression.firstArg.replace(oldExpectedExpression.firstArg) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceExpectedOutmostMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceExpectedOutmostMethodCallQuickFix.kt index efbec6a..84d5c96 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceExpectedOutmostMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceExpectedOutmostMethodCallQuickFix.kt @@ -18,7 +18,7 @@ class ReplaceExpectedOutmostMethodCallQuickFix(description: String, private val val factory = JavaPsiFacade.getElementFactory(element.project) val expectedExpression = - factory.createExpressionFromText("a.${replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression + factory.createExpressionFromText("a.$replacementMethod(e)", element) as PsiMethodCallExpression val expectedMethodCallExpression = oldExpectedExpression.firstArg as? PsiMethodCallExpression ?: return expectedExpression.firstArg.replace(expectedMethodCallExpression.firstArg) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt index c3c6b48..f5756d2 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitAssertMethodCallQuickFix.kt @@ -6,10 +6,13 @@ import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.JavaCodeStyleManager +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME +import de.platon42.intellij.plugins.cajon.MethodNames import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.replaceQualifier -class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val hasExpected: Boolean, private val replacementMethod: String) : +class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val noExpectedExpression: Boolean, private val replacementMethod: String) : AbstractCommonQuickFix(description) { override fun applyFix(project: Project, descriptor: ProblemDescriptor) { @@ -18,30 +21,27 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val hasE val args = methodCallExpression.argumentList val count = args.expressionCount val actualExpression = args.expressions[count - 1] ?: return - val (expectedExpression, messageExpression) = if (hasExpected) { + val (expectedExpression, messageExpression) = if (noExpectedExpression) { + val message = if (count > 1) args.expressions[0] else null + null to message + } else { val expected = args.expressions[count - 2] ?: return val message = if (count > 2) args.expressions[0] else null expected to message - } else { - val message = if (count > 1) args.expressions[0] else null - null to message } val factory = JavaPsiFacade.getElementFactory(element.project) val expectedMethodCall = factory.createExpressionFromText( - "a.${if (hasExpected) replacementMethod.replace("()", "(e)") else replacementMethod}", element + "a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element ) as PsiMethodCallExpression - if (hasExpected) { + if (!noExpectedExpression) { expectedMethodCall.firstArg.replace(expectedExpression!!) } - val newMethodCall = factory.createExpressionFromText( - "org.assertj.core.api.Assertions.assertThat(a)", element - ) as PsiMethodCallExpression - newMethodCall.firstArg.replace(actualExpression) + val newMethodCall = createAssertThat(element, actualExpression) if (messageExpression != null) { - val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression + val asExpression = factory.createExpressionFromText("a.${MethodNames.AS}(desc)", element) as PsiMethodCallExpression asExpression.firstArg.replace(messageExpression) asExpression.replaceQualifier(newMethodCall) expectedMethodCall.replaceQualifier(asExpression) diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt index 050bdf5..244656c 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceJUnitDeltaAssertMethodCallQuickFix.kt @@ -6,6 +6,7 @@ import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.codeStyle.CodeStyleManager import com.intellij.psi.codeStyle.JavaCodeStyleManager +import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_ASSERTIONS_CLASSNAME import de.platon42.intellij.plugins.cajon.firstArg import de.platon42.intellij.plugins.cajon.getArg import de.platon42.intellij.plugins.cajon.replaceQualifier @@ -30,16 +31,13 @@ class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val offsetMethodCall.firstArg.replace(deltaExpression) val expectedMethodCall = factory.createExpressionFromText( - "a.${replacementMethod.removeSuffix("()")}(e, offs)", element + "a.$replacementMethod(e, offs)", element ) as PsiMethodCallExpression expectedMethodCall.firstArg.replace(expectedExpression) expectedMethodCall.getArg(1).replace(offsetMethodCall) - val newMethodCall = factory.createExpressionFromText( - "org.assertj.core.api.Assertions.assertThat(a)", element - ) as PsiMethodCallExpression - newMethodCall.firstArg.replace(actualExpression) + val newMethodCall = createAssertThat(element, actualExpression) if (messageExpression != null) { val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSimpleMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSimpleMethodCallQuickFix.kt index 7bb7ebc..46d7564 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSimpleMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSimpleMethodCallQuickFix.kt @@ -14,7 +14,7 @@ class ReplaceSimpleMethodCallQuickFix(description: String, private val replaceme val factory = JavaPsiFacade.getElementFactory(element.project) val expectedExpression = - factory.createExpressionFromText("a.$replacementMethod", element) as PsiMethodCallExpression + factory.createExpressionFromText("a.$replacementMethod()", element) as PsiMethodCallExpression expectedExpression.replaceQualifierFromMethodCall(methodCallExpression) element.replace(expectedExpression) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt index 590df21..37b0426 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/ReplaceSizeMethodCallQuickFix.kt @@ -5,6 +5,7 @@ import com.intellij.openapi.project.Project import com.intellij.psi.* import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.qualifierExpression import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall @@ -24,8 +25,9 @@ class ReplaceSizeMethodCallQuickFix( val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val factory = JavaPsiFacade.getElementFactory(element.project) - val expectedExpression = - factory.createExpressionFromText("a.${if (noExpectedExpression) replacementMethod else replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression + val expectedExpression = factory.createExpressionFromText( + "a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element + ) as PsiMethodCallExpression if (!noExpectedExpression) { if (expectedIsCollection) { replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg) diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitBinaryExpressionMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitBinaryExpressionMethodCallQuickFix.kt index 1d37ed9..5495590 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitBinaryExpressionMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitBinaryExpressionMethodCallQuickFix.kt @@ -8,6 +8,7 @@ import com.intellij.psi.PsiMethodCallExpression import com.intellij.psi.PsiStatement import com.intellij.psi.util.PsiTreeUtil import de.platon42.intellij.plugins.cajon.firstArg +import de.platon42.intellij.plugins.cajon.map import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall class SplitBinaryExpressionMethodCallQuickFix( @@ -28,8 +29,9 @@ class SplitBinaryExpressionMethodCallQuickFix( val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val factory = JavaPsiFacade.getElementFactory(element.project) - val expectedExpression = - factory.createExpressionFromText("a.${if (noExpectedExpression) replacementMethod else replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression + val expectedExpression = factory.createExpressionFromText( + "a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element + ) as PsiMethodCallExpression if (!noExpectedExpression) { expectedExpression.firstArg.replace(expectedArgument) } diff --git a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitEqualsExpressionMethodCallQuickFix.kt b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitEqualsExpressionMethodCallQuickFix.kt index 92b71ef..7d562a2 100644 --- a/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitEqualsExpressionMethodCallQuickFix.kt +++ b/src/main/java/de/platon42/intellij/plugins/cajon/quickfixes/SplitEqualsExpressionMethodCallQuickFix.kt @@ -23,8 +23,9 @@ class SplitEqualsExpressionMethodCallQuickFix(description: String, private val r val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return val factory = JavaPsiFacade.getElementFactory(element.project) - val expectedExpression = - factory.createExpressionFromText("a.${replacementMethod.replace("()", "(e)")}", element) as PsiMethodCallExpression + val expectedExpression = factory.createExpressionFromText( + "a.$replacementMethod(e)", element + ) as PsiMethodCallExpression expectedExpression.firstArg.replace(expectedArgument) expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression) oldExpectedExpression.replace(expectedExpression)