IDE: Don't do any resolution in ReplaceInfixOrOperatorCallFix.invoke().
This commit is contained in:
committed by
teamcityserver
parent
06adb405e1
commit
5a6d543fba
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.diagnostics.Diagnostic
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
import org.jetbrains.kotlin.diagnostics.Errors
|
||||||
import org.jetbrains.kotlin.idea.KotlinBundle
|
import org.jetbrains.kotlin.idea.KotlinBundle
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
|
||||||
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
|
||||||
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
|
import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue
|
||||||
@@ -23,7 +23,8 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
|||||||
|
|
||||||
class ReplaceInfixOrOperatorCallFix(
|
class ReplaceInfixOrOperatorCallFix(
|
||||||
element: KtExpression,
|
element: KtExpression,
|
||||||
private val notNullNeeded: Boolean
|
private val notNullNeeded: Boolean,
|
||||||
|
private val binaryOperatorName: String = ""
|
||||||
) : KotlinQuickFixAction<KtExpression>(element) {
|
) : KotlinQuickFixAction<KtExpression>(element) {
|
||||||
|
|
||||||
override fun getText() = KotlinBundle.message("replace.with.safe.call")
|
override fun getText() = KotlinBundle.message("replace.with.safe.call")
|
||||||
@@ -58,20 +59,18 @@ class ReplaceInfixOrOperatorCallFix(
|
|||||||
replacement = element.replace(newExpression)
|
replacement = element.replace(newExpression)
|
||||||
}
|
}
|
||||||
is KtBinaryExpression -> {
|
is KtBinaryExpression -> {
|
||||||
replacement = if (element.operationToken == KtTokens.IDENTIFIER) {
|
val left = element.left ?: return
|
||||||
val newExpression = psiFactory.createExpressionByPattern(
|
val right = element.right ?: return
|
||||||
"$0?.$1($2)$elvis", element.left ?: return, element.operationReference.text, element.right ?: return
|
|
||||||
)
|
// `a += b` is replaced with `a = a?.plus(b)` when the += operator is not available
|
||||||
element.replace(newExpression)
|
val isNormalAssignment = element.operationToken in KtTokens.AUGMENTED_ASSIGNMENTS &&
|
||||||
|
Name.identifier(binaryOperatorName) !in OperatorConventions.ASSIGNMENT_OPERATIONS.values
|
||||||
|
val newExpression = if (isNormalAssignment) {
|
||||||
|
psiFactory.createExpressionByPattern("$0 = $0?.$1($2)", left, binaryOperatorName, right)
|
||||||
} else {
|
} else {
|
||||||
val nameExpression = OperatorToFunctionIntention.convert(element).second
|
psiFactory.createExpressionByPattern("$0?.$1($2)$elvis", left, binaryOperatorName, right)
|
||||||
val callExpression = nameExpression.parent as KtCallExpression
|
|
||||||
val qualifiedExpression = callExpression.parent as KtDotQualifiedExpression
|
|
||||||
val safeExpression = psiFactory.createExpressionByPattern(
|
|
||||||
"$0?.$1$elvis", qualifiedExpression.receiverExpression, callExpression
|
|
||||||
)
|
|
||||||
qualifiedExpression.replace(safeExpression)
|
|
||||||
}
|
}
|
||||||
|
replacement = element.replace(newExpression)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (elvis.isNotEmpty()) {
|
if (elvis.isNotEmpty()) {
|
||||||
@@ -95,7 +94,17 @@ class ReplaceInfixOrOperatorCallFix(
|
|||||||
parent.left == null || parent.right == null -> null
|
parent.left == null || parent.right == null -> null
|
||||||
parent.operationToken == KtTokens.EQ -> null
|
parent.operationToken == KtTokens.EQ -> null
|
||||||
parent.operationToken in OperatorConventions.COMPARISON_OPERATIONS -> null
|
parent.operationToken in OperatorConventions.COMPARISON_OPERATIONS -> null
|
||||||
else -> ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType())
|
else -> {
|
||||||
|
val binaryOperatorName = if (parent.operationToken == KtTokens.IDENTIFIER) {
|
||||||
|
// Get name of infix function call
|
||||||
|
parent.operationReference.text
|
||||||
|
} else {
|
||||||
|
parent.resolveToCall(BodyResolveMode.FULL)?.candidateDescriptor?.name?.asString()
|
||||||
|
}
|
||||||
|
binaryOperatorName?.let {
|
||||||
|
ReplaceInfixOrOperatorCallFix(parent, parent.shouldHaveNotNullType(), binaryOperatorName)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is KtCallExpression -> {
|
is KtCallExpression -> {
|
||||||
|
|||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with safe (?.) call" "true"
|
||||||
|
class A {
|
||||||
|
operator fun plusAssign(other: A) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(b: A) {
|
||||||
|
var a: A? = A()
|
||||||
|
a <caret>+= b
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with safe (?.) call" "true"
|
||||||
|
class A {
|
||||||
|
operator fun plusAssign(other: A) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(b: A) {
|
||||||
|
var a: A? = A()
|
||||||
|
a?.plusAssign(b)
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with safe (?.) call" "true"
|
||||||
|
class A {
|
||||||
|
operator fun plus(other: A) = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(b: A) {
|
||||||
|
var a: A? = A()
|
||||||
|
a <caret>+= b
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Replace with safe (?.) call" "true"
|
||||||
|
class A {
|
||||||
|
operator fun plus(other: A) = this
|
||||||
|
}
|
||||||
|
|
||||||
|
fun foo(b: A) {
|
||||||
|
var a: A? = A()
|
||||||
|
a = a?.plus(b)
|
||||||
|
}
|
||||||
@@ -11673,6 +11673,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
|
|||||||
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/assignmentList.kt");
|
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/assignmentList.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("augmentedAssignmentAvailable.kt")
|
||||||
|
public void testAugmentedAssignmentAvailable() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/augmentedAssignmentAvailable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("augmentedAssignmentNotAvailable.kt")
|
||||||
|
public void testAugmentedAssignmentNotAvailable() throws Exception {
|
||||||
|
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/augmentedAssignmentNotAvailable.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("binaryOperator.kt")
|
@TestMetadata("binaryOperator.kt")
|
||||||
public void testBinaryOperator() throws Exception {
|
public void testBinaryOperator() throws Exception {
|
||||||
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/binaryOperator.kt");
|
runTest("idea/testData/quickfix/replaceInfixOrOperatorCall/binaryOperator.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user