Added Guava Optional opt.orNull() == null case. Added Java 8 Optional opt.orElse(null) == null case, too.
This commit is contained in:
@@ -100,6 +100,21 @@ fun PsiMethodCallExpression.getExpectedBooleanResult(): Boolean? {
|
||||
return null
|
||||
}
|
||||
|
||||
fun PsiMethodCallExpression.getExpectedNullNonNullResult(): Boolean? {
|
||||
val isNull = AbstractAssertJInspection.IS_NULL.test(this)
|
||||
val isNotNull = AbstractAssertJInspection.IS_NOT_NULL.test(this)
|
||||
if (isNull || isNotNull) {
|
||||
return isNotNull
|
||||
} else {
|
||||
val isEqualTo = AbstractAssertJInspection.IS_EQUAL_TO_OBJECT.test(this)
|
||||
val isNotEqualTo = AbstractAssertJInspection.IS_NOT_EQUAL_TO_OBJECT.test(this)
|
||||
if ((isEqualTo || isNotEqualTo) && firstArg.type == PsiType.NULL) {
|
||||
return isNotEqualTo
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun PsiMethodCallExpression.calculateConstantParameterValue(argIndex: Int): Any? {
|
||||
if (argIndex >= argumentList.expressions.size) return null
|
||||
val valueExpression = getArg(argIndex)
|
||||
@@ -145,4 +160,31 @@ fun PsiExpression.getAllTheSameExpectedBooleanConstants(): Boolean? {
|
||||
}
|
||||
}
|
||||
return lockedResult
|
||||
}
|
||||
|
||||
fun PsiExpression.getAllTheSameNullNotNullConstants(): Boolean? {
|
||||
val assertThatMethodCall = findStaticMethodCall() ?: return null
|
||||
var lockedResult: Boolean? = null
|
||||
val methodsToView = generateSequence(assertThatMethodCall) { PsiTreeUtil.getParentOfType(it, PsiMethodCallExpression::class.java) }
|
||||
|
||||
for (methodCall in methodsToView) {
|
||||
val expectedResult = methodCall.getExpectedNullNonNullResult()
|
||||
if (expectedResult != null) {
|
||||
if ((lockedResult != null) && (lockedResult != expectedResult)) {
|
||||
return null
|
||||
}
|
||||
lockedResult = expectedResult
|
||||
} else {
|
||||
val isNotConstant = CallMatcher.anyOf(
|
||||
EXTENSION_POINTS,
|
||||
MORE_EXTENSION_POINTS,
|
||||
AbstractAssertJInspection.IS_EQUAL_TO_OBJECT,
|
||||
AbstractAssertJInspection.IS_NOT_EQUAL_TO_OBJECT
|
||||
).test(methodCall)
|
||||
if (isNotConstant) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
return lockedResult
|
||||
}
|
||||
+9
@@ -93,6 +93,11 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
val IS_NOT_SAME_AS_OBJECT = CallMatcher.instanceCall(ASSERT_INTERFACE, MethodNames.IS_NOT_SAME_AS)
|
||||
.parameterTypes(CommonClassNames.JAVA_LANG_OBJECT)!!
|
||||
|
||||
val IS_NULL = CallMatcher.instanceCall(ASSERT_INTERFACE, MethodNames.IS_NULL)
|
||||
.parameterCount(0)!!
|
||||
val IS_NOT_NULL = CallMatcher.instanceCall(ASSERT_INTERFACE, MethodNames.IS_NOT_NULL)
|
||||
.parameterCount(0)!!
|
||||
|
||||
val HAS_SIZE = CallMatcher.instanceCall(ABSTRACT_ENUMERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE)
|
||||
.parameterTypes("int")!!
|
||||
|
||||
@@ -129,6 +134,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
.parameterCount(0)!!
|
||||
val OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "isPresent")
|
||||
.parameterCount(0)!!
|
||||
val OPTIONAL_OR_ELSE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "orElse")
|
||||
.parameterCount(1)!!
|
||||
|
||||
val OPTIONAL_OF = CallMatcher.staticCall(CommonClassNames.JAVA_UTIL_OPTIONAL, "of")
|
||||
.parameterCount(1)!!
|
||||
@@ -141,6 +148,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
|
||||
.parameterCount(0)!!
|
||||
val GUAVA_OPTIONAL_IS_PRESENT = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "isPresent")
|
||||
.parameterCount(0)!!
|
||||
val GUAVA_OPTIONAL_OR_NULL = CallMatcher.instanceCall(GUAVA_OPTIONAL_CLASSNAME, "orNull")
|
||||
.parameterCount(0)!!
|
||||
|
||||
val GUAVA_OPTIONAL_OF = CallMatcher.staticCall(GUAVA_OPTIONAL_CLASSNAME, "of")
|
||||
.parameterCount(1)!!
|
||||
|
||||
+3
-1
@@ -36,7 +36,9 @@ class AssertThatBinaryExpressionInspection : AbstractAssertJInspection() {
|
||||
val assertThatArgument = staticMethodCall.firstArg
|
||||
if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) {
|
||||
val replacementMethod = expectedResult.map(MethodNames.IS_EQUAL_TO, MethodNames.IS_NOT_EQUAL_TO)
|
||||
registerSplitMethod(holder, expectedCallExpression, "${MethodNames.EQUALS}()", replacementMethod, ::MoveOutMethodCallExpressionQuickFix)
|
||||
registerSplitMethod(holder, expectedCallExpression, "${MethodNames.EQUALS}()", replacementMethod) { desc, method ->
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -58,7 +58,9 @@ class AssertThatCollectionOrMapExpressionInspection : AbstractAssertJInspection(
|
||||
val expectedResult = expectedCallExpression.getAllTheSameExpectedBooleanConstants() ?: return
|
||||
|
||||
val replacementMethod = if (expectedResult) mapping.replacementForTrue else mapping.replacementForFalse ?: return
|
||||
registerMoveOutMethod(holder, expectedCallExpression, assertThatArgument, replacementMethod, ::MoveOutMethodCallExpressionQuickFix)
|
||||
registerMoveOutMethod(holder, expectedCallExpression, assertThatArgument, replacementMethod) { desc, method ->
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -51,6 +51,15 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
|
||||
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
||||
)
|
||||
}
|
||||
} else if (GUAVA_OPTIONAL_OR_NULL.test(actualExpression)) {
|
||||
val expectedPresence = outmostMethodCall.getAllTheSameNullNotNullConstants() ?: return
|
||||
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_ABSENT)
|
||||
registerMoveOutMethod(holder, outmostMethodCall, actualExpression, replacementMethod) { desc, method ->
|
||||
QuickFixWithPostfixDelegate(
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method, useNullNonNull = true),
|
||||
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+7
-4
@@ -1,10 +1,7 @@
|
||||
package de.platon42.intellij.plugins.cajon.inspections
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder
|
||||
import com.intellij.psi.JavaElementVisitor
|
||||
import com.intellij.psi.PsiElementVisitor
|
||||
import com.intellij.psi.PsiExpressionStatement
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
import com.intellij.psi.*
|
||||
import com.siyeh.ig.callMatcher.CallMatcher
|
||||
import de.platon42.intellij.plugins.cajon.*
|
||||
import de.platon42.intellij.plugins.cajon.quickfixes.MoveOutMethodCallExpressionQuickFix
|
||||
@@ -50,6 +47,12 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
|
||||
registerMoveOutMethod(holder, outmostMethodCall, actualExpression, replacementMethod) { desc, method ->
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method)
|
||||
}
|
||||
} else if (OPTIONAL_OR_ELSE.test(actualExpression) && (actualExpression.firstArg.type == PsiType.NULL)) {
|
||||
val expectedPresence = outmostMethodCall.getAllTheSameNullNotNullConstants() ?: return
|
||||
val replacementMethod = expectedPresence.map(MethodNames.IS_PRESENT, MethodNames.IS_NOT_PRESENT)
|
||||
registerMoveOutMethod(holder, outmostMethodCall, actualExpression, replacementMethod) { desc, method ->
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method, useNullNonNull = true, noExpectedExpression = true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -62,7 +62,9 @@ class AssertThatStringExpressionInspection : AbstractAssertJInspection() {
|
||||
val expectedResult = expectedCallExpression.getAllTheSameExpectedBooleanConstants() ?: return
|
||||
|
||||
val replacementMethod = if (expectedResult) mapping.replacementForTrue else mapping.replacementForFalse
|
||||
registerMoveOutMethod(holder, expectedCallExpression, assertThatArgument, replacementMethod, ::MoveOutMethodCallExpressionQuickFix)
|
||||
registerMoveOutMethod(holder, expectedCallExpression, assertThatArgument, replacementMethod) { desc, method ->
|
||||
MoveOutMethodCallExpressionQuickFix(desc, method)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-3
@@ -5,7 +5,13 @@ import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.PsiMethodCallExpression
|
||||
import de.platon42.intellij.plugins.cajon.*
|
||||
|
||||
class MoveOutMethodCallExpressionQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
|
||||
class MoveOutMethodCallExpressionQuickFix(
|
||||
description: String,
|
||||
private val replacementMethod: String,
|
||||
private val useNullNonNull: Boolean = false,
|
||||
private val noExpectedExpression: Boolean = false
|
||||
) :
|
||||
AbstractCommonQuickFix(description) {
|
||||
|
||||
companion object {
|
||||
private const val REMOVE_ACTUAL_EXPRESSION_DESCRIPTION = "Move method calls in actual expressions out of assertThat()"
|
||||
@@ -19,10 +25,10 @@ class MoveOutMethodCallExpressionQuickFix(description: String, private val repla
|
||||
val outmostCallExpression = descriptor.startElement as? PsiMethodCallExpression ?: return
|
||||
val assertThatMethodCall = outmostCallExpression.findStaticMethodCall() ?: return
|
||||
val assertExpression = assertThatMethodCall.firstArg as? PsiMethodCallExpression ?: return
|
||||
val assertExpressionArg = assertExpression.getArgOrNull(0)?.copy()
|
||||
val assertExpressionArg = if (noExpectedExpression) null else assertExpression.getArgOrNull(0)?.copy()
|
||||
|
||||
val methodsToFix = assertThatMethodCall.collectMethodCallsUpToStatement()
|
||||
.filter { it.getExpectedBooleanResult() != null }
|
||||
.filter { (if (useNullNonNull) it.getExpectedNullNonNullResult() else it.getExpectedBooleanResult()) != null }
|
||||
.toList()
|
||||
|
||||
assertExpression.replace(assertExpression.qualifierExpression)
|
||||
|
||||
Reference in New Issue
Block a user