Fix for incompatible method call regarding IDEA <2018.2.

Heavy refactoring regarding quick fixes (using more extensions).
Even more refactoring.
Fixed/extended AssertThatGuavaOptionalInspection regarding static.
imports and wrong reference to core assertThat() where Guava assertThat() actually was necessary.
This commit is contained in:
2019-04-13 18:35:49 +02:00
parent 4e6d53b3dc
commit b58d8cfd2f
27 changed files with 425 additions and 290 deletions
@@ -10,6 +10,8 @@ class AssertJClassNames {
@NonNls
const val ABSTRACT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractAssert"
@NonNls
const val ABSTRACT_OBJECT_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractObjectAssert"
@NonNls
const val ABSTRACT_BOOLEAN_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractBooleanAssert"
@NonNls
const val ABSTRACT_INTEGER_ASSERT_CLASSNAME = "org.assertj.core.api.AbstractIntegerAssert"
@@ -1,12 +1,14 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.*
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.util.PsiTreeUtil
val PsiMethodCallExpression.qualifierExpression: PsiExpression get() = this.methodExpression.qualifierExpression!!
val PsiMethodCallExpression.firstArg: PsiExpression get() = this.argumentList.expressions[0]!!
fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiExpression) {
fun PsiMethodCallExpression.replaceQualifier(qualifier: PsiElement) {
this.qualifierExpression.replace(qualifier)
}
@@ -14,6 +16,32 @@ fun PsiMethodCallExpression.replaceQualifierFromMethodCall(oldMethodCall: PsiMet
this.qualifierExpression.replace(oldMethodCall.qualifierExpression)
}
fun PsiElement.findOutmostMethodCall(): PsiMethodCallExpression? {
val statement = PsiTreeUtil.getParentOfType(this, PsiStatement::class.java) ?: return null
return PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java)
}
fun PsiMethodCallExpression.getArg(n: Int): PsiExpression = this.argumentList.expressions[n]
fun <T> Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse
fun <T> Boolean.map(forTrue: T, forFalse: T) = if (this) forTrue else forFalse
fun PsiMethod.addAsStaticImport(context: PsiElement, vararg allowedClashes: String) {
val factory = JavaPsiFacade.getElementFactory(context.project)
val methodName = this.name
val containingClass = this.containingClass ?: return
val importList = (context.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == this.containingClass))
}
if (notImportedStatically) {
importList.add(factory.createImportStaticStatement(containingClass, methodName))
}
}
fun PsiElement.shortenAndReformat() {
val codeStyleManager = JavaCodeStyleManager.getInstance(project)
codeStyleManager.shortenClassReferences(this)
CodeStyleManager.getInstance(project).reformat(this)
}
@@ -0,0 +1,33 @@
package de.platon42.intellij.plugins.cajon
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
fun createAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.ASSERTIONS_CLASSNAME, actualExpression)
}
fun createGuavaAssertThat(context: PsiElement, actualExpression: PsiExpression): PsiMethodCallExpression {
return createAssertThat(context, AssertJClassNames.GUAVA_ASSERTIONS_CLASSNAME, actualExpression)
}
fun createAssertThat(context: PsiElement, baseclass: String, actualExpression: PsiExpression): PsiMethodCallExpression {
return createMethodCall(context, "$baseclass.${MethodNames.ASSERT_THAT}", actualExpression)
}
fun createExpectedMethodCall(context: PsiElement, methodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
return createMethodCall(context, "a.$methodName", *arguments)
}
fun createMethodCall(context: PsiElement, fullQualifiedMethodName: String, vararg arguments: PsiElement): PsiMethodCallExpression {
val factory = JavaPsiFacade.getElementFactory(context.project)
val argString = generateSequence('b') { it + 1 }.take(arguments.size).joinToString(", ")
val expectedExpression = factory.createExpressionFromText(
"$fullQualifiedMethodName($argString)", context
) as PsiMethodCallExpression
arguments.forEachIndexed { index, newArg -> expectedExpression.getArg(index).replace(newArg) }
return expectedExpression
}
@@ -1,6 +1,7 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.AbstractBaseJavaLocalInspectionTool
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope
@@ -18,8 +19,6 @@ import de.platon42.intellij.plugins.cajon.AssertJClassNames.Companion.GUAVA_OPTI
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.RemoveExpectedOutmostMethodCallQuickFix
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSimpleMethodCallQuickFix
open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
@@ -174,30 +173,17 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
holder.registerProblem(expression, message, quickFix)
}
protected fun registerRemoveActualOutmostMethod(
protected fun registerReplaceMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false
quickFixSupplier: (String, String) -> LocalQuickFix
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val originalMethod = getOriginalMethodName(oldExpectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = RemoveActualOutmostMethodCallQuickFix(description, replacementMethod, noExpectedExpression)
holder.registerProblem(expression, message, quickfix)
}
protected fun registerRemoveExpectedOutmostMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = RemoveExpectedOutmostMethodCallQuickFix(description, replacementMethod)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
@@ -239,6 +225,6 @@ open class AbstractAssertJInspection : AbstractBaseJavaLocalInspectionTool() {
val findClass =
JavaPsiFacade.getInstance(element.project).findClass(classname, GlobalSearchScope.allScope(element.project))
?: return false
return findClass.findMethodsByName(methodname).isNotEmpty()
return findClass.allMethods.any { it.name == methodname }
}
}
@@ -1,12 +1,13 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
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.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.SplitBinaryExpressionMethodCallQuickFix
@@ -30,18 +31,13 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
return
}
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val expectedResult = getExpectedBooleanResult(expectedCallExpression) ?: return
val assertThatArgument = expression.firstArg
if (assertThatArgument is PsiMethodCallExpression && OBJECT_EQUALS.test(assertThatArgument)) {
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)
registerSplitMethod(holder, expression, "${MethodNames.EQUALS}()", replacementMethod, ::SplitEqualsExpressionMethodCallQuickFix)
return
}
@@ -56,7 +52,9 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
return
} else if (isLeftNull || isRightNull) {
val replacementMethod = if (expectedResult) IS_NULL else IS_NOT_NULL
registerSplitBinaryExpressionMethod(holder, expression, replacementMethod, pickRightOperand = isLeftNull, noExpectedExpression = true)
registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = isLeftNull, noExpectedExpression = true)
}
return
}
@@ -76,21 +74,22 @@ class AssertThatBinaryExpressionIsTrueOrFalseInspection : AbstractAssertJInspect
(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)
registerSplitMethod(holder, expression, "binary", replacementMethod) { desc, method ->
SplitBinaryExpressionMethodCallQuickFix(desc, method, pickRightOperand = swapExpectedAndActual)
}
}
private fun registerSplitBinaryExpressionMethod(
private fun registerSplitMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
type: String,
replacementMethod: String,
pickRightOperand: Boolean = false,
noExpectedExpression: Boolean = false
quickFixSupplier: (String, String) -> LocalQuickFix
) {
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)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
}
}
@@ -1,13 +1,13 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.JavaElementVisitor
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiElementVisitor
import com.intellij.psi.PsiMethodCallExpression
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
import de.platon42.intellij.plugins.cajon.*
import de.platon42.intellij.plugins.cajon.quickfixes.*
class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
@@ -27,35 +27,87 @@ class AssertThatGuavaOptionalInspection : AbstractAssertJInspection() {
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
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val isEqualTo = IS_EQUAL_TO_OBJECT.test(expectedCallExpression)
val isNotEqualTo = IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)
if (assertThatGuava) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
if (isEqualTo) {
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)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
} else if (IS_NOT_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
} else if (isNotEqualTo) {
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)
// we're not calling an assertThat() from Guava, but a core-AssertJ one!
// We need to replace that by the Guava one, if we want to apply a formally correct fix.
val actualExpression = expression.firstArg as? PsiMethodCallExpression
if (actualExpression != null) {
if (GUAVA_OPTIONAL_GET.test(actualExpression) && isEqualTo) {
registerRemoveActualOutmostForGuavaMethod(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)
registerRemoveActualOutmostForGuavaMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
}
}
if (isEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_OF.test(innerExpectedCall) || GUAVA_OPTIONAL_FROM_NULLABLE.test(innerExpectedCall)) {
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveExpectedOutmostMethodCallQuickFix(desc, method),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
} else if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_ABSENT)
}
} else if (isNotEqualTo) {
val innerExpectedCall = expectedCallExpression.firstArg as? PsiMethodCallExpression ?: return
if (GUAVA_OPTIONAL_ABSENT.test(innerExpectedCall)) {
registerSimplifyForGuavaMethod(holder, expectedCallExpression, MethodNames.IS_PRESENT)
}
}
}
}
}
}
private fun registerRemoveActualOutmostForGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
oldExpectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false
) {
registerReplaceMethod(holder, expression, oldExpectedCallExpression, replacementMethod) { desc, method ->
QuickFixWithPostfixDelegate(
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
}
}
private fun registerSimplifyForGuavaMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = SIMPLIFY_MESSAGE_TEMPLATE.format(originalMethod, replacementMethod)
val quickFix = QuickFixWithPostfixDelegate(
ReplaceSimpleMethodCallQuickFix(description, replacementMethod),
ForGuavaPostFix.REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT
)
holder.registerProblem(expression, message, quickFix)
}
}
@@ -4,11 +4,12 @@ import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.JavaElementVisitor
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.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
class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
@@ -25,14 +26,13 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (!ASSERT_THAT_ANY.test(expression)) {
return
}
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
if (ASSERT_THAT_JAVA8_OPTIONAL.test(expression)) {
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, MethodNames.CONTAINS)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS, ::RemoveExpectedOutmostMethodCallQuickFix)
} else if (OPTIONAL_EMPTY.test(innerExpectedCall)) {
registerSimplifyMethod(holder, expectedCallExpression, MethodNames.IS_NOT_PRESENT)
}
@@ -47,14 +47,20 @@ class AssertThatJava8OptionalInspection : AbstractAssertJInspection() {
if (OPTIONAL_GET.test(actualExpression)) {
if (IS_EQUAL_TO_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
} else if (IS_SAME_AS_OBJECT.test(expectedCallExpression)) {
registerRemoveActualOutmostMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.CONTAINS_SAME) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method)
}
}
} 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)
registerReplaceMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
RemoveActualOutmostMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
}
}
}
@@ -2,9 +2,9 @@ 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.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.map
import de.platon42.intellij.plugins.cajon.quickfixes.ReplaceSizeMethodCallQuickFix
@@ -34,18 +34,23 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
val actualExpression = expression.firstArg
if (isArrayLength(actualExpression) || isCollectionSize(actualExpression)) {
val statement = PsiTreeUtil.getParentOfType(expression, PsiStatement::class.java) ?: return
val expectedCallExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val expectedCallExpression = expression.findOutmostMethodCall() ?: return
val constValue = calculateConstantParameterValue(expectedCallExpression, 0)
if (IS_EQUAL_TO_INT.test(expectedCallExpression)) {
if (constValue == 0) {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY, noExpectedExpression = true)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.IS_EMPTY) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} else {
val equalToExpression = expectedCallExpression.firstArg
if (isCollectionSize(equalToExpression) || isArrayLength(equalToExpression)) {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS, expectedIsCollection = true)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SAME_SIZE_AS) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, expectedIsCollection = true)
}
} else {
registerReplaceSizeMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE)
registerReplaceMethod(holder, expression, expectedCallExpression, MethodNames.HAS_SIZE) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
}
}
}
} else {
@@ -57,11 +62,15 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
|| IS_NOT_ZERO.test(expectedCallExpression))
if (isTestForEmpty || isTestForNotEmpty) {
val replacementMethod = isTestForEmpty.map(MethodNames.IS_EMPTY, MethodNames.IS_NOT_EMPTY)
registerReplaceSizeMethod(holder, expression, expectedCallExpression, replacementMethod, noExpectedExpression = true)
registerReplaceMethod(holder, expression, expectedCallExpression, replacementMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method, noExpectedExpression = true)
}
} else if (hasAssertJMethod(expression, ABSTRACT_ITERABLE_ASSERT_CLASSNAME, MethodNames.HAS_SIZE_LESS_THAN)) {
// new stuff in AssertJ 13.2.0
val matchedMethod = BONUS_EXPRESSIONS_CALL_MATCHER_MAP.find { it.first.test(expectedCallExpression) }?.second ?: return
registerReplaceSizeMethod(holder, expression, expectedCallExpression, matchedMethod)
registerReplaceMethod(holder, expression, expectedCallExpression, matchedMethod) { desc, method ->
ReplaceSizeMethodCallQuickFix(desc, method)
}
}
}
}
@@ -74,21 +83,6 @@ class AssertThatSizeInspection : AbstractAssertJInspection() {
return ((psiReferenceExpression.qualifierExpression?.type is PsiArrayType)
&& ((psiReferenceExpression.resolve() as? PsiField)?.name == "length"))
}
private fun registerReplaceSizeMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
expectedCallExpression: PsiMethodCallExpression,
replacementMethod: String,
noExpectedExpression: Boolean = false,
expectedIsCollection: Boolean = false
) {
val originalMethod = getOriginalMethodName(expectedCallExpression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = MORE_CONCISE_MESSAGE_TEMPLATE.format(replacementMethod, originalMethod)
val quickfix = ReplaceSizeMethodCallQuickFix(description, replacementMethod, noExpectedExpression, expectedIsCollection)
holder.registerProblem(expression, message, quickfix)
}
}
}
}
@@ -1,5 +1,6 @@
package de.platon42.intellij.plugins.cajon.inspections
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemsHolder
import com.intellij.psi.*
import com.intellij.psi.search.GlobalSearchScope
@@ -121,43 +122,29 @@ class JUnitAssertToAssertJInspection : AbstractJUnitAssertInspection() {
}
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) {
registerDeltaReplacementMethod(holder, expression, mapping.replacement)
} else {
registerSimpleReplacementMethod(holder, expression, mapping.hasExpected, mapping.replacement)
}
return
val mapping = MAPPINGS.firstOrNull { it.callMatcher.test(expression) } ?: return
if (mapping.hasDelta) {
registerConvertMethod(holder, expression, mapping.replacement, ::ReplaceJUnitDeltaAssertMethodCallQuickFix)
} else {
registerConvertMethod(holder, expression, mapping.replacement) { desc, method ->
ReplaceJUnitAssertMethodCallQuickFix(desc, method, !mapping.hasExpected)
}
}
}
}
}
private fun registerSimpleReplacementMethod(
private fun registerConvertMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
hasExpected: Boolean,
replacementMethod: String
replacementMethod: String,
quickFixSupplier: (String, String) -> LocalQuickFix
) {
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)
holder.registerProblem(expression, message, quickFix)
}
private fun registerDeltaReplacementMethod(
holder: ProblemsHolder,
expression: PsiMethodCallExpression,
replacementMethod: String
) {
val originalMethod = getOriginalMethodName(expression) ?: return
val description = REPLACE_DESCRIPTION_TEMPLATE.format(originalMethod, replacementMethod)
val message = CONVERT_MESSAGE_TEMPLATE.format(originalMethod)
val quickFix = ReplaceJUnitDeltaAssertMethodCallQuickFix(description, replacementMethod)
holder.registerProblem(expression, message, quickFix)
val quickfix = quickFixSupplier(description, replacementMethod)
holder.registerProblem(expression, message, quickfix)
}
private class Mapping(
@@ -1,35 +1,9 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix
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
protected fun addStaticImport(method: PsiMethod, element: PsiMethodCallExpression, factory: PsiElementFactory, vararg allowedClashes: String) {
val methodName = method.name
val containingClass = method.containingClass ?: return
val importList = (element.containingFile as PsiJavaFile).importList ?: return
val notImportedStatically = importList.importStaticStatements.none {
val targetClass = it.resolveTargetClass() ?: return@none false
((it.referenceName == methodName) && !allowedClashes.contains(targetClass.qualifiedName))
|| (it.isOnDemand && (targetClass == method.containingClass))
}
if (notImportedStatically) {
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
}
}
@@ -0,0 +1,27 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import com.siyeh.ig.callMatcher.CallMatcher
import de.platon42.intellij.plugins.cajon.*
class ForGuavaPostFix {
companion object {
private val CORE_MATCHER = CallMatcher.staticCall(AssertJClassNames.ASSERTIONS_CLASSNAME, MethodNames.ASSERT_THAT)
val REPLACE_BY_GUAVA_ASSERT_THAT_AND_STATIC_IMPORT: (Project, ProblemDescriptor) -> Unit = exit@
{ _, descriptor ->
val element = descriptor.startElement
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return@exit
val methodCallExpression = PsiTreeUtil.findChildrenOfType(statement, PsiMethodCallExpression::class.java).find { CORE_MATCHER.test(it) } ?: return@exit
val newMethodCall = createGuavaAssertThat(element, methodCallExpression.firstArg)
newMethodCall.resolveMethod()?.addAsStaticImport(element, AssertJClassNames.ASSERTIONS_CLASSNAME)
val parentCall = PsiTreeUtil.getParentOfType(methodCallExpression, PsiMethodCallExpression::class.java) ?: return@exit
parentCall.replaceQualifier(newMethodCall)
parentCall.shortenAndReformat()
}
}
}
@@ -0,0 +1,16 @@
package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.LocalQuickFix
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
class QuickFixWithPostfixDelegate(
private val mainFix: LocalQuickFix,
private val postfix: (Project, ProblemDescriptor) -> Unit
) : LocalQuickFix by mainFix {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
mainFix.applyFix(project, descriptor)
postfix(project, descriptor)
}
}
@@ -2,19 +2,13 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
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
import de.platon42.intellij.plugins.cajon.*
class RemoveActualOutmostMethodCallQuickFix(
description: String,
private val replacementMethod: String,
private val noExpectedExpression: Boolean
private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -22,16 +16,10 @@ class RemoveActualOutmostMethodCallQuickFix(
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg as? PsiMethodCallExpression ?: return
assertExpression.replace(assertExpression.qualifierExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedExpression.firstArg.replace(oldExpectedExpression.firstArg)
}
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val args = if (noExpectedExpression) emptyArray() else oldExpectedExpression.argumentList.expressions
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
@@ -2,10 +2,9 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.findOutmostMethodCall
import de.platon42.intellij.plugins.cajon.firstArg
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
@@ -13,14 +12,9 @@ class RemoveExpectedOutmostMethodCallQuickFix(description: String, private val r
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression =
factory.createExpressionFromText("a.$replacementMethod(e)", element) as PsiMethodCallExpression
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedMethodCallExpression = oldExpectedExpression.firstArg as? PsiMethodCallExpression ?: return
expectedExpression.firstArg.replace(expectedMethodCallExpression.firstArg)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, expectedMethodCallExpression.firstArg)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
@@ -2,17 +2,12 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.codeStyle.CodeStyleManager
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import de.platon42.intellij.plugins.cajon.*
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 noExpectedExpression: Boolean, private val replacementMethod: String) :
class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val replacementMethod: String, private val noExpectedExpression: Boolean) :
AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -22,39 +17,26 @@ class ReplaceJUnitAssertMethodCallQuickFix(description: String, private val noEx
val count = args.expressions.size
val actualExpression = args.expressions[count - 1] ?: return
val (expectedExpression, messageExpression) = if (noExpectedExpression) {
val message = if (count > 1) args.expressions[0] else null
null to message
val message = args.expressions.getOrNull(count - 2)
emptyArray<PsiExpression>() to message
} else {
val expected = args.expressions[count - 2] ?: return
val message = if (count > 2) args.expressions[0] else null
expected to message
}
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedMethodCall = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedMethodCall.firstArg.replace(expectedExpression!!)
val message = args.expressions.getOrNull(count - 3)
arrayOf(expected) to message
}
val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, *expectedExpression)
val newMethodCall = createAssertThat(element, actualExpression)
if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.${MethodNames.AS}(desc)", element) as PsiMethodCallExpression
asExpression.firstArg.replace(messageExpression)
val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.replaceQualifier(newMethodCall)
expectedMethodCall.replaceQualifier(asExpression)
} else {
expectedMethodCall.replaceQualifier(newMethodCall)
}
val assertThatMethod = newMethodCall.resolveMethod() ?: return
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME)
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
element.replace(expectedMethodCall).shortenAndReformat()
}
}
@@ -2,14 +2,9 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
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.*
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
class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
@@ -18,44 +13,25 @@ class ReplaceJUnitDeltaAssertMethodCallQuickFix(description: String, private val
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val args = methodCallExpression.argumentList
val count = args.expressions.size
val actualExpression = args.expressions[count - 2] ?: return
val messageExpression = if (count > 3) args.expressions[0] else null
val messageExpression = args.expressions.getOrNull(count - 4)
val expectedExpression = args.expressions[count - 3] ?: return
val actualExpression = args.expressions[count - 2] ?: return
val deltaExpression = args.expressions[count - 1] ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val offsetMethodCall = factory.createExpressionFromText(
"org.assertj.core.data.Offset.offset(c)", element
) as PsiMethodCallExpression
offsetMethodCall.firstArg.replace(deltaExpression)
val expectedMethodCall = factory.createExpressionFromText(
"a.$replacementMethod(e, offs)", element
) as PsiMethodCallExpression
expectedMethodCall.firstArg.replace(expectedExpression)
expectedMethodCall.getArg(1).replace(offsetMethodCall)
val offsetMethodCall = createMethodCall(element, "org.assertj.core.data.Offset.offset", deltaExpression)
val expectedMethodCall = createExpectedMethodCall(element, replacementMethod, expectedExpression, offsetMethodCall)
val newMethodCall = createAssertThat(element, actualExpression)
if (messageExpression != null) {
val asExpression = factory.createExpressionFromText("a.as(desc)", element) as PsiMethodCallExpression
asExpression.firstArg.replace(messageExpression)
val asExpression = createExpectedMethodCall(element, MethodNames.AS, messageExpression)
asExpression.replaceQualifier(newMethodCall)
expectedMethodCall.replaceQualifier(asExpression)
} else {
expectedMethodCall.replaceQualifier(newMethodCall)
}
val assertThatMethod = newMethodCall.resolveMethod() ?: return
addStaticImport(assertThatMethod, element, factory, GUAVA_ASSERTIONS_CLASSNAME)
val offsetMethod = offsetMethodCall.resolveMethod() ?: return
addStaticImport(offsetMethod, element, factory)
val codeStyleManager = JavaCodeStyleManager.getInstance(element.project)
val newElement = element.replace(expectedMethodCall)
val shortened = codeStyleManager.shortenClassReferences(newElement)
CodeStyleManager.getInstance(element.project).reformat(shortened)
newMethodCall.resolveMethod()?.addAsStaticImport(element, GUAVA_ASSERTIONS_CLASSNAME)
offsetMethodCall.resolveMethod()?.addAsStaticImport(element)
element.replace(expectedMethodCall).shortenAndReformat()
}
}
@@ -2,19 +2,19 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiMethodCallExpression
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
class ReplaceSimpleMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
class ReplaceSimpleMethodCallQuickFix(
description: String,
private val replacementMethod: String
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
val element = descriptor.startElement
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression =
factory.createExpressionFromText("a.$replacementMethod()", element) as PsiMethodCallExpression
val expectedExpression = createExpectedMethodCall(element, replacementMethod)
expectedExpression.replaceQualifierFromMethodCall(methodCallExpression)
element.replace(expectedExpression)
}
@@ -2,18 +2,16 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
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
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiReferenceExpression
import de.platon42.intellij.plugins.cajon.*
class ReplaceSizeMethodCallQuickFix(
description: String,
private val replacementMethod: String,
private val noExpectedExpression: Boolean,
private val expectedIsCollection: Boolean
private val noExpectedExpression: Boolean = false,
private val expectedIsCollection: Boolean = false
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -21,19 +19,15 @@ class ReplaceSizeMethodCallQuickFix(
val methodCallExpression = element as? PsiMethodCallExpression ?: return
val assertExpression = methodCallExpression.firstArg
replaceCollectionSizeOrArrayLength(assertExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
if (expectedIsCollection) {
replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg)
}
expectedExpression.firstArg.replace(oldExpectedExpression.firstArg)
if (expectedIsCollection) {
replaceCollectionSizeOrArrayLength(oldExpectedExpression.firstArg)
}
val args = if (noExpectedExpression) emptyArray() else arrayOf(oldExpectedExpression.firstArg)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
@@ -2,20 +2,18 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiMethodCallExpression
import com.intellij.psi.PsiStatement
import com.intellij.psi.util.PsiTreeUtil
import de.platon42.intellij.plugins.cajon.createExpectedMethodCall
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.replaceQualifierFromMethodCall
class SplitBinaryExpressionMethodCallQuickFix(
description: String,
private val replacementMethod: String,
private val pickRightOperand: Boolean,
private val noExpectedExpression: Boolean
private val pickRightOperand: Boolean = false,
private val noExpectedExpression: Boolean = false
) : AbstractCommonQuickFix(description) {
override fun applyFix(project: Project, descriptor: ProblemDescriptor) {
@@ -25,16 +23,9 @@ class SplitBinaryExpressionMethodCallQuickFix(
val expectedArgument = (if (pickRightOperand) binaryExpression.lOperand else binaryExpression.rOperand)?.copy() ?: return
binaryExpression.replace(if (pickRightOperand) binaryExpression.rOperand!! else binaryExpression.lOperand)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod${noExpectedExpression.map("()", "(e)")}", element
) as PsiMethodCallExpression
if (!noExpectedExpression) {
expectedExpression.firstArg.replace(expectedArgument)
}
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val args = if (noExpectedExpression) emptyArray() else arrayOf(expectedArgument)
val expectedExpression = createExpectedMethodCall(element, replacementMethod, *args)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}
@@ -2,13 +2,8 @@ package de.platon42.intellij.plugins.cajon.quickfixes
import com.intellij.codeInspection.ProblemDescriptor
import com.intellij.openapi.project.Project
import com.intellij.psi.JavaPsiFacade
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.qualifierExpression
import de.platon42.intellij.plugins.cajon.replaceQualifierFromMethodCall
import de.platon42.intellij.plugins.cajon.*
class SplitEqualsExpressionMethodCallQuickFix(description: String, private val replacementMethod: String) : AbstractCommonQuickFix(description) {
@@ -19,14 +14,8 @@ class SplitEqualsExpressionMethodCallQuickFix(description: String, private val r
val expectedArgument = equalsMethodCall.firstArg.copy()
equalsMethodCall.replace(equalsMethodCall.qualifierExpression)
val statement = PsiTreeUtil.getParentOfType(element, PsiStatement::class.java) ?: return
val oldExpectedExpression = PsiTreeUtil.findChildOfType(statement, PsiMethodCallExpression::class.java) ?: return
val factory = JavaPsiFacade.getElementFactory(element.project)
val expectedExpression = factory.createExpressionFromText(
"a.$replacementMethod(e)", element
) as PsiMethodCallExpression
expectedExpression.firstArg.replace(expectedArgument)
val oldExpectedExpression = element.findOutmostMethodCall() ?: return
val expectedExpression = createExpectedMethodCall(element, replacementMethod, expectedArgument)
expectedExpression.replaceQualifierFromMethodCall(oldExpectedExpression)
oldExpectedExpression.replace(expectedExpression)
}