Reduced minimal supported IDEA version from 2018.2 to 2017.2.
Added AssertThatGuavaOptional inspection. Prepared next release. Bumped to Kotlin 1.3.30.
This commit is contained in:
+18
-5
@@ -14,18 +14,19 @@ import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.ABSTRACT_E
|
||||
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.AssertJClassNames.Companion.GUAVA_OPTIONAL_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.RemoveExpectedOutmostMethodCallQuickFix
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix
|
||||
|
||||
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 MORE_CONCISE_MESSAGE_TEMPLATE = "%s() would be more concise than %s()"
|
||||
|
||||
const val REPLACE_DESCRIPTION_TEMPLATE = "Replace %s() with %s()"
|
||||
|
||||
@@ -73,7 +74,7 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
.parameterTypes(CommonClassNames.JAVA_UTIL_OPTIONAL)!!
|
||||
|
||||
val ASSERT_THAT_GUAVA_OPTIONAL = CallMatcher.staticCall(GUAVA_ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
|
||||
.parameterTypes()!!
|
||||
.parameterTypes(GUAVA_OPTIONAL_CLASSNAME)!!
|
||||
|
||||
val IS_EQUAL_TO_OBJECT = CallMatcher.instanceCall(ABSTRACT_ASSERT_CLASSNAME, MethodNames.IS_EQUAL_TO)
|
||||
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
|
||||
@@ -130,6 +131,18 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
.parameterCount(1)!!
|
||||
val OPTIONAL_EMPTY = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "empty")
|
||||
.parameterCount(0)!!
|
||||
|
||||
val GUAVA_OPTIONAL_GET = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "get")
|
||||
.parameterCount(0)!!
|
||||
val GUAVA_OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "isPresent")
|
||||
.parameterCount(0)!!
|
||||
|
||||
val GUAVA_OPTIONAL_OF = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "of")
|
||||
.parameterCount(1)!!
|
||||
val GUAVA_OPTIONAL_FROM_NULLABLE = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "fromNullable")
|
||||
.parameterCount(1)!!
|
||||
val GUAVA_OPTIONAL_ABSENT = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "absent")
|
||||
.parameterCount(0)!!
|
||||
}
|
||||
|
||||
override fun getGroupDisplayName(): String {
|
||||
@@ -184,12 +197,12 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
|
||||
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
|
||||
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
|
||||
val quickfix = ReplaceExpectedOutmostMethodCallQuickFix(description, replacementMethod)
|
||||
val quickfix = RemoveExpectedOutmostMethodCallQuickFix(description, replacementMethod)
|
||||
holder.registerProblem(expression, message, quickfix)
|
||||
}
|
||||
|
||||
protected fun calculateConstantParameterValue(expression: PsiMethodCallExpression, argIndex: Int): Any? {
|
||||
if (argIndex >= expression.argumentList.expressionCount) return null
|
||||
if (argIndex >= expression.argumentList.expressions.size) return null
|
||||
val valueExpression = expression.getArg(argIndex)
|
||||
val constantEvaluationHelper = JavaPsiFacade.getInstance(expression.project).constantEvaluationHelper
|
||||
val value = constantEvaluationHelper.computeConstantExpression(valueExpression)
|
||||
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
package de.platon42.intellij.plugins.cajon.inspections
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||
import de.platon42.intellij.plugins.cajon.firstArg
|
||||
import de.platon42.intellij.plugins.cajon.map
|
||||
|
||||
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
||||
|
||||
companion object {
|
||||
private const val DISPLAY_NAME = "Asserting an Optional (Guava)"
|
||||
}
|
||||
|
||||
override fun getDisplayName() = DISPLAY_NAME
|
||||
|
||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean): PsiElementVisitor {
|
||||
return object : JavaElementVisitor() {
|
||||
override fun visitMethodCallExpression(expression: PsiMethodCallExpression) {
|
||||
super.visitMethodCallExpression(expression)
|
||||
JavaPsiFacade.getInstance(expression.project)
|
||||
.findClass(AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
|
||||
val assertThatGuava = ASSERT_THAT_GUAVA_OPTIONAL.test(expression)
|
||||
if (!(ASSERT_THAT_ANY.test(expression) || assertThatGuava)) {
|
||||
return
|
||||
}
|
||||
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return
|
||||
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
|
||||
|
||||
if (assertThatGuava) {
|
||||
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
|
||||
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
||||
if (GUAVA_OPTIONAL_OF.test(innerExpectedCall) || GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) {
|
||||
registerRemoveExpectedOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
||||
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
|
||||
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
|
||||
}
|
||||
} else if (IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
|
||||
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
|
||||
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
|
||||
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
val actualExpression = expression.firstArg as? PsiMethodCallExpression ?: return
|
||||
|
||||
if (GUAVA_OPTIONAL_GET.test(actualExpression) && IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
||||
} else if (GUAVA_OPTIONAL_IS_PRESENT.test(actualExpression)) {
|
||||
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
|
||||
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_ABSENT)
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+9
-13
@@ -44,21 +44,17 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
|
||||
}
|
||||
} else {
|
||||
val actualExpression = expression.firstArg as? PsiMethodCallExpression ?: return
|
||||
val isGet = OPTIONAL_GET.test(actualExpression)
|
||||
val isIsPresent = OPTIONAL_IS_PRESENT.test(actualExpression)
|
||||
|
||||
if (isGet || isIsPresent) {
|
||||
if (isGet) {
|
||||
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
||||
} else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) {
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME)
|
||||
}
|
||||
} else {
|
||||
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
|
||||
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT)
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
|
||||
if (OPTIONAL_GET.test(actualExpression)) {
|
||||
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
|
||||
} else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) {
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME)
|
||||
}
|
||||
} else if (OPTIONAL_IS_PRESENT.test(actualExpression)) {
|
||||
val expectedPresence = getExpectedBooleanResult(expectedCallExpression) ?: return
|
||||
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT)
|
||||
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
-4
@@ -1,12 +1,11 @@
|
||||
package de.platon42.intellij.plugins.cajon.inspections
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import com.intellij.psi.JavaElementVisitor
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
import com.intellij.psi.*
|
||||
import com.intellij.psi.search.GlobalSearchScope
|
||||
import com.siyeh.ig.callMatcher.CallMatcher
|
||||
import com.siyeh.ig.callMatcher.CallMatcher.anyOf
|
||||
import de.platon42.intellij.plugins.cajon.AssertJClassNames
|
||||
import de.platon42.intellij.plugins.cajon.MethodNames
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitAssertMethodCallQuickFix
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceJUnitDeltaAssertMethodCallQuickFix
|
||||
@@ -120,6 +119,8 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
|
||||
if (!isJUnitAssertCall) {
|
||||
return // early exit
|
||||
}
|
||||
JavaPsiFacade.getInstance(expression.project)
|
||||
.findClass(AssertJClassNames.ASSERTIONS_CLASSNAME, GlobalSearchScope.allScope(expression.project)) ?: return
|
||||
for (mapping in MAPPINGS) {
|
||||
if (mapping.callMatcher.test(expression)) {
|
||||
if (mapping.hasDelta) {
|
||||
|
||||
Reference in New Issue
Block a user