Extended AssertThatSize inspection to Maps, too.

This commit is contained in:
2019-08-23 18:21:08 +02:00
parent 36f63d26d2
commit 315b93d90d
10 changed files with 142 additions and 64 deletions
@@ -130,6 +130,8 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
val COLLECTION_SIZE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_COLLECTION, "size")
.parameterCount(0)!!
val MAP_SIZE = CallMatcher.instanceCall(CommonClassNames.JAVA_UTIL_MAP, "size")
.parameterCount(0)!!
val CHAR_SEQUENCE_LENGTH = CallMatcher.instanceCall("java.lang.CharSequence", "length")
.parameterCount(0)!!
val OBJECT_EQUALS = CallMatcher.instanceCall(CommonClassNames.JAVA_LANG_OBJECT, "equals")
@@ -11,7 +11,7 @@ import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickF
class AssertThatSizeInspection : AbstractAssertJInspection() {
companion object {
private const val DISPLAY_NAME = "Asserting the size of an collection, array or string"
private const val DISPLAY_NAME = "Asserting the size of an collection, map, array or string"
private const val REMOVE_SIZE_DESCRIPTION_TEMPLATE = "Remove size determination of expected expression and replace %s() with %s()"
private const val REMOVE_ALL_MESSAGE = "Try to operate on the iterable itself rather than its size"
@@ -26,13 +26,15 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
private fun isCollectionSize(expression: PsiExpression) = (expression is PsiMethodCallExpression) && COLLECTION_SIZE.test(expression)
private fun isMapSize(expression: PsiExpression) = (expression is PsiMethodCallExpression) && MAP_SIZE.test(expression)
private fun isArrayLength(expression: PsiExpression): Boolean {
val psiReferenceExpression = expression as? PsiReferenceExpression ?: return false
return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType)
&& ((psiReferenceExpression.resolve() as? PsiField)?.name == "length"))
}
fun getMatch(expression: PsiMethodCallExpression, isForArrayOrCollection: Boolean, isForString: Boolean): Match? {
fun getMatch(expression: PsiMethodCallExpression, isForArrayCollectionOrMap: Boolean, isForString: Boolean): Match? {
val isLastExpression = expression.parent is PsiStatement
val constValue = expression.calculateConstantParameterValue(0)
if (IS_EQUAL_TO_INT.test(expression)) {
@@ -40,8 +42,10 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
Match(expression, MethodNames.IS_EMPTY, noExpectedExpression = true)
} else {
val equalToExpression = expression.firstArg
if (isForArrayOrCollection && (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) ||
isForString && (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression) || isCharSequenceLength(equalToExpression))
val equalsArrayCollectionOrMapSize = isArrayLength(equalToExpression) ||
isCollectionSize(equalToExpression) || isMapSize(equalToExpression)
if (isForArrayCollectionOrMap && equalsArrayCollectionOrMapSize ||
isForString && (equalsArrayCollectionOrMapSize || isCharSequenceLength(equalToExpression))
) {
Match(expression, MethodNames.HAS_SAME_SIZE_AS, expectedIsCollection = true)
} else {
@@ -79,12 +83,12 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
if (!ASSERT_THAT_INT.test(staticMethodCall)) return
val actualExpression = staticMethodCall.firstArg
val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
val isForArrayCollectionOrMap = isArrayLength(actualExpression) || isCollectionSize(actualExpression) || isMapSize(actualExpression)
val isForString = isCharSequenceLength(actualExpression)
if (!(isForArrayOrCollection || isForString)) return
if (!(isForArrayCollectionOrMap || isForString)) return
val matches = staticMethodCall.collectMethodCallsUpToStatement()
.mapNotNull { getMatch(it, isForArrayOrCollection, isForString) }
.mapNotNull { getMatch(it, isForArrayCollectionOrMap, isForString) }
.toList()
if (matches.isNotEmpty()) {
if (matches.size == 1) {
@@ -112,9 +116,9 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
if (!HAS_SIZE.test(expression)) return
val actualExpression = expression.firstArg
val isForArrayOrCollection = isArrayLength(actualExpression) || isCollectionSize(actualExpression)
val isForArrayCollectionOrMap = isArrayLength(actualExpression) || isCollectionSize(actualExpression) || isMapSize(actualExpression)
val isForString = isCharSequenceLength(actualExpression)
if (!(isForArrayOrCollection
if (!(isForArrayCollectionOrMap
|| (isForString && checkAssertedType(expression, ABSTRACT_CHAR_SEQUENCE_ASSERT_CLASSNAME)))
) return
@@ -15,7 +15,7 @@ class ReplaceHasSizeMethodCallQuickFix(description: String, private val replacem
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val methodCallExpression = descriptor.startElement as? PsiMethodCallExpression ?: return
replaceCollectionSizeOrArrayLength(methodCallExpression.firstArg)
replaceCollectionAndMapSizeOrArrayLength(methodCallExpression.firstArg)
val expectedExpression = createExpectedMethodCall(methodCallExpression, replacementMethod, methodCallExpression.firstArg)
@@ -23,7 +23,7 @@ class ReplaceHasSizeMethodCallQuickFix(description: String, private val replacem
methodCallExpression.replace(expectedExpression)
}
private fun replaceCollectionSizeOrArrayLength(assertExpression: PsiExpression) {
private fun replaceCollectionAndMapSizeOrArrayLength(assertExpression: PsiExpression) {
assertExpression.replace(
when (assertExpression) {
is PsiReferenceExpression -> assertExpression.qualifierExpression!!
@@ -26,10 +26,10 @@ class ReplaceSizeMethodCallQuickFix(
val outmostCallExpression = descriptor.startElement as? PsiMethodCallExpression ?: return
val assertThatMethodCall = outmostCallExpression.findStaticMethodCall() ?: return
val assertExpression = assertThatMethodCall.firstArg
replaceCollectionSizeOrArrayLength(assertExpression)
replaceCollectionAndMapSizeOrArrayLength(assertExpression)
if (expectedIsCollection) {
replaceCollectionSizeOrArrayLength(outmostCallExpression.firstArg)
replaceCollectionAndMapSizeOrArrayLength(outmostCallExpression.firstArg)
}
val args = if (noExpectedExpression) emptyArray() else arrayOf(outmostCallExpression.firstArg)
@@ -39,7 +39,7 @@ class ReplaceSizeMethodCallQuickFix(
outmostCallExpression.replace(expectedExpression)
}
private fun replaceCollectionSizeOrArrayLength(assertExpression: PsiExpression) {
private fun replaceCollectionAndMapSizeOrArrayLength(assertExpression: PsiExpression) {
assertExpression.replace(
when (assertExpression) {
is PsiReferenceExpression -> assertExpression.qualifierExpression!!
@@ -1,6 +1,6 @@
<html>
<body>
Makes assertions on sizes of arrays, collections, strings, or CharSequences more concise by replacing them with isEmpty(), isNotEmpty(), hasSize(), or hasSameSizeAs().
Makes assertions on sizes of arrays, collections, maps, strings, or CharSequences more concise by replacing them with isEmpty(), isNotEmpty(), hasSize(), or hasSameSizeAs().
<!-- tooltip end -->
<br>Several more conversions are available with AssertJ 3.12.0 or later.
</body>