KT-11425: replace call with binary operator works now also with equals() and ==

(cherry picked from commit 5d47fdf)
This commit is contained in:
Mikhail Glukhikh
2016-07-27 18:47:19 +03:00
committed by Mikhail Glukhikh
parent 39d7d3381c
commit 2850a7898d
4 changed files with 31 additions and 11 deletions
@@ -20,18 +20,22 @@ import com.intellij.codeInsight.intention.HighPriorityAction
import com.intellij.openapi.editor.Editor import com.intellij.openapi.editor.Editor
import com.intellij.openapi.util.TextRange import com.intellij.openapi.util.TextRange
import org.jetbrains.kotlin.idea.intentions.* import org.jetbrains.kotlin.idea.intentions.*
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtPsiFactory
import org.jetbrains.kotlin.psi.createExpressionByPattern
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.expressions.OperatorConventions import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.util.OperatorNameConventions
class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace call with binary operator"), HighPriorityAction { class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(
KtDotQualifiedExpression::class.java,
"Replace call with binary operator"
), HighPriorityAction {
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? { override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
val operation = operation(element.calleeName) ?: return null val calleeExpression = element.callExpression?.calleeExpression as? KtSimpleNameExpression ?: return null
val operation = operation(calleeExpression) ?: return null
val resolvedCall = element.toResolvedCall(BodyResolveMode.PARTIAL) ?: return null val resolvedCall = element.toResolvedCall(BodyResolveMode.PARTIAL) ?: return null
if (!resolvedCall.isReallySuccess()) return null if (!resolvedCall.isReallySuccess()) return null
@@ -42,19 +46,23 @@ class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDot
if (!element.isReceiverExpressionWithValue()) return null if (!element.isReceiverExpressionWithValue()) return null
text = "Replace with '$operation' operator" text = "Replace with '$operation' operator"
return element.callExpression!!.calleeExpression!!.textRange return calleeExpression.textRange
} }
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) { override fun applyTo(element: KtDotQualifiedExpression, editor: Editor?) {
val operation = operation(element.calleeName)!! val callExpression = element.callExpression ?: return
val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!! val operation = operation(callExpression.calleeExpression as? KtSimpleNameExpression ?: return) ?: return
val argument = callExpression.valueArguments.single().getArgumentExpression() ?: return
val receiver = element.receiverExpression val receiver = element.receiverExpression
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $operation $1", receiver, argument)) element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $operation $1", receiver, argument))
} }
private fun operation(functionName: String?): String? { private fun operation(calleeExpression: KtSimpleNameExpression): String? {
if (functionName == null) return null val identifier = calleeExpression.getReferencedNameAsName()
return OperatorConventions.BINARY_OPERATION_NAMES.inverse()[Name.identifier(functionName)]?.value if (identifier == OperatorNameConventions.EQUALS) {
return KtTokens.EQEQ.value
}
return OperatorConventions.BINARY_OPERATION_NAMES.inverse()[identifier]?.value
} }
} }
@@ -0,0 +1,3 @@
// INTENTION_TEXT: Replace with '==' operator
val x = 2.equals<caret>(2)
@@ -0,0 +1,3 @@
// INTENTION_TEXT: Replace with '==' operator
val x = 2 == 2
@@ -2738,6 +2738,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest {
doTest(fileName); doTest(fileName);
} }
@TestMetadata("equals.kt")
public void testEquals() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/equals.kt");
doTest(fileName);
}
@TestMetadata("extensionFunction.kt") @TestMetadata("extensionFunction.kt")
public void testExtensionFunction() throws Exception { public void testExtensionFunction() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/extensionFunction.kt"); String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/extensionFunction.kt");