Do not suggest "Replace infix with safe call" inside conditions or binary / unary expressions #KT-13328 Fixed

This commit is contained in:
Mikhail Glukhikh
2016-08-11 15:39:55 +03:00
parent 42969271ab
commit b53cb91e88
8 changed files with 84 additions and 3 deletions
@@ -19,12 +19,18 @@ package org.jetbrains.kotlin.idea.quickfix
import com.intellij.codeInsight.intention.IntentionAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
import com.intellij.psi.tree.TokenSet
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.idea.caches.resolve.analyze
import org.jetbrains.kotlin.idea.intentions.OperatorToFunctionIntention
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAssignmentByLHS
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
import org.jetbrains.kotlin.psi.psiUtil.parents
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.types.expressions.OperatorConventions
import org.jetbrains.kotlin.types.typeUtil.isBoolean
class ReplaceInfixOrOperatorCallFix(element: KtExpression) : KotlinQuickFixAction<KtExpression>(element) {
@@ -87,7 +93,11 @@ class ReplaceInfixOrOperatorCallFix(element: KtExpression) : KotlinQuickFixActio
return when (parent) {
is KtBinaryExpression -> {
if (parent.left == null || parent.right == null) null
else ReplaceInfixOrOperatorCallFix(parent)
else {
if (parent.operationToken in OperatorConventions.COMPARISON_OPERATIONS &&
parent.analyze()[BindingContext.EXPECTED_EXPRESSION_TYPE, parent]?.isBoolean() ?: false) null
else ReplaceInfixOrOperatorCallFix(parent)
}
}
is KtCallExpression -> {
if (parent.calleeExpression == null) null
@@ -2,6 +2,6 @@
// ERROR: Infix call corresponds to a dot-qualified call 'value?.compareTo(1).compareTo(0)' which is not allowed on a nullable receiver 'value?.compareTo(1)'. Use '?.'-qualified call instead
var foo: Int? = null
set(value) {
if(value <caret>< 1) {
if((value <caret>< 1) ?: false) {
}
}
@@ -2,6 +2,6 @@
// ERROR: Infix call corresponds to a dot-qualified call 'value?.compareTo(1).compareTo(0)' which is not allowed on a nullable receiver 'value?.compareTo(1)'. Use '?.'-qualified call instead
var foo: Int? = null
set(value) {
if(value?.compareTo(1) < 0) {
if((value?.compareTo(1) < 0) ?: false) {
}
}
@@ -0,0 +1,11 @@
// "Replace with safe (?.) call" "false"
// ACTION: Add non-null asserted (!!) call
// ACTION: Flip '<'
// ACTION: Replace overloaded operator with function call
// ERROR: Infix call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. Use '?.'-qualified call instead
class Wrapper(val x: Int)
fun test(w: Wrapper?) {
if (w?.x <caret>< 42) {}
}
@@ -0,0 +1,12 @@
// "Replace with safe (?.) call" "false"
// ACTION: Add non-null asserted (!!) call
// ACTION: Flip '>'
// ACTION: Replace overloaded operator with function call
// ACTION: Simplify boolean expression
// ERROR: Infix call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. Use '?.'-qualified call instead
class Wrapper(val x: Int)
fun test(w: Wrapper?) {
val t = 1 < 2 && w?.x <caret>> 42
}
@@ -0,0 +1,13 @@
// "Replace with safe (?.) call" "false"
// ACTION: Add non-null asserted (!!) call
// ACTION: Flip '<='
// ACTION: Replace overloaded operator with function call
// ERROR: Infix call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. Use '?.'-qualified call instead
class Wrapper(val x: Int)
fun test(w: Wrapper?) {
when {
w?.x <caret><= 42 -> {}
}
}
@@ -0,0 +1,11 @@
// "Replace with safe (?.) call" "false"
// ACTION: Add non-null asserted (!!) call
// ACTION: Flip '>='
// ACTION: Replace overloaded operator with function call
// ERROR: Infix call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. Use '?.'-qualified call instead
class Wrapper(val x: Int)
fun test(w: Wrapper?) {
while (w?.x <caret>>= 42) {}
}
@@ -6153,6 +6153,30 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest {
doTest(fileName);
}
@TestMetadata("unsafeComparisonInCondition.kt")
public void testUnsafeComparisonInCondition() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt");
doTest(fileName);
}
@TestMetadata("unsafeComparisonInLogic.kt")
public void testUnsafeComparisonInLogic() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt");
doTest(fileName);
}
@TestMetadata("unsafeComparisonInWhen.kt")
public void testUnsafeComparisonInWhen() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt");
doTest(fileName);
}
@TestMetadata("unsafeComparisonInWhile.kt")
public void testUnsafeComparisonInWhile() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt");
doTest(fileName);
}
@TestMetadata("unsafeGet.kt")
public void testUnsafeGet() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/nullables/unsafeInfixCall/unsafeGet.kt");