From aeac2ea384c30f6e18f7a762f856323f92e6c69e Mon Sep 17 00:00:00 2001 From: Mikhail Zarechenskiy Date: Mon, 19 Jun 2017 04:06:05 +0300 Subject: [PATCH] Fix 'add not-null asserted call' quick fix for operation `in` #KT-18529 Fixed --- .../kotlin/idea/quickfix/ExclExclCallFixes.kt | 12 +++++++----- .../ifThenToDoubleBang/conditionNotBinaryExpr.kt | 2 +- .../branched/ifThenToElvis/conditionNotBinaryExpr.kt | 2 +- .../replaceCallWithBinaryOperator/safeCompareTo.kt | 2 +- .../testData/quickfix/addExclExclCall/operationIn.kt | 6 ++++++ .../quickfix/addExclExclCall/operationIn.kt.after | 6 ++++++ .../nullables/unsafeInfixCall/noComparison.kt | 2 +- .../unsafeInfixCall/unsafeComparisonInCondition.kt | 2 +- .../unsafeInfixCall/unsafeComparisonInLogic.kt | 2 +- .../unsafeInfixCall/unsafeComparisonInWhen.kt | 2 +- .../unsafeInfixCall/unsafeComparisonInWhile.kt | 2 +- .../kotlin/idea/quickfix/QuickFixTestGenerated.java | 6 ++++++ 12 files changed, 33 insertions(+), 13 deletions(-) create mode 100644 idea/testData/quickfix/addExclExclCall/operationIn.kt create mode 100644 idea/testData/quickfix/addExclExclCall/operationIn.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt index 3767007a3d3..18bbf9b64c7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ExclExclCallFixes.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2015 JetBrains s.r.o. + * Copyright 2010-2017 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,14 +33,13 @@ import org.jetbrains.kotlin.idea.caches.resolve.analyze import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* +import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall +import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.isValidOperator -import org.jetbrains.kotlin.psi.KtPsiFactory -import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall -import org.jetbrains.kotlin.resolve.calls.resolvedCallUtil.getImplicitReceiverValue abstract class ExclExclCallFix(psiElement: PsiElement) : KotlinQuickFixAction(psiElement) { @@ -117,7 +116,10 @@ class AddExclExclCallFix(psiElement: PsiElement, val checkImplicitReceivers: Boo val parent = psiElement.parent when (parent) { is KtUnaryExpression -> parent.baseExpression.expressionForCall() - is KtBinaryExpression -> parent.left.expressionForCall() + is KtBinaryExpression -> { + val receiver = if (KtPsiUtil.isInOrNotInOperation(parent)) parent.right else parent.left + receiver.expressionForCall() + } else -> null } } diff --git a/idea/testData/intentions/branched/ifThenToDoubleBang/conditionNotBinaryExpr.kt b/idea/testData/intentions/branched/ifThenToDoubleBang/conditionNotBinaryExpr.kt index 797718fce2a..83f78d085a2 100644 --- a/idea/testData/intentions/branched/ifThenToDoubleBang/conditionNotBinaryExpr.kt +++ b/idea/testData/intentions/branched/ifThenToDoubleBang/conditionNotBinaryExpr.kt @@ -2,7 +2,7 @@ // IS_APPLICABLE: false // ERROR: Type mismatch: inferred type is Int but Boolean was expected // ERROR: Type mismatch: inferred type is Int but Boolean was expected -// ERROR: Infix call corresponds to a dot-qualified call 'foo.times(10)' which is not allowed on a nullable receiver 'foo'. Use '?.'-qualified call instead +// ERROR: Operator call corresponds to a dot-qualified call 'foo.times(10)' which is not allowed on a nullable receiver 'foo'. fun String?.times(a: Int): Boolean = a == 0 diff --git a/idea/testData/intentions/branched/ifThenToElvis/conditionNotBinaryExpr.kt b/idea/testData/intentions/branched/ifThenToElvis/conditionNotBinaryExpr.kt index 9ca51c3bf07..83c3f524995 100644 --- a/idea/testData/intentions/branched/ifThenToElvis/conditionNotBinaryExpr.kt +++ b/idea/testData/intentions/branched/ifThenToElvis/conditionNotBinaryExpr.kt @@ -1,7 +1,7 @@ // IS_APPLICABLE: false // ERROR: Type mismatch: inferred type is Int but Boolean was expected // ERROR: Type mismatch: inferred type is Int but Boolean was expected -// ERROR: Infix call corresponds to a dot-qualified call 'foo.times(10)' which is not allowed on a nullable receiver 'foo'. Use '?.'-qualified call instead +// ERROR: Operator call corresponds to a dot-qualified call 'foo.times(10)' which is not allowed on a nullable receiver 'foo'. fun main(args: Array) { val foo: Int? = 4 diff --git a/idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/safeCompareTo.kt b/idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/safeCompareTo.kt index 41591deefa7..31d9e26eaef 100644 --- a/idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/safeCompareTo.kt +++ b/idea/testData/intentions/conventionNameCalls/replaceCallWithBinaryOperator/safeCompareTo.kt @@ -1,5 +1,5 @@ // IS_APPLICABLE: false -// ERROR: Infix call corresponds to a dot-qualified call 'nullable?.compareTo(1).compareTo(0)' which is not allowed on a nullable receiver 'nullable?.compareTo(1)'. Use '?.'-qualified call instead +// ERROR: Operator call corresponds to a dot-qualified call 'nullable?.compareTo(1).compareTo(0)' which is not allowed on a nullable receiver 'nullable?.compareTo(1)'. val nullable: Int? = null val x = nullable?.compareTo(1) >= 0 \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationIn.kt b/idea/testData/quickfix/addExclExclCall/operationIn.kt new file mode 100644 index 00000000000..c9d98be033b --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationIn.kt @@ -0,0 +1,6 @@ +// "Add non-null asserted (!!) call" "true" +// WITH_RUNTIME + +fun foo(a: List?) { + "x" in a +} \ No newline at end of file diff --git a/idea/testData/quickfix/addExclExclCall/operationIn.kt.after b/idea/testData/quickfix/addExclExclCall/operationIn.kt.after new file mode 100644 index 00000000000..e814dbebf1d --- /dev/null +++ b/idea/testData/quickfix/addExclExclCall/operationIn.kt.after @@ -0,0 +1,6 @@ +// "Add non-null asserted (!!) call" "true" +// WITH_RUNTIME + +fun foo(a: List?) { + "x" in a!! +} \ No newline at end of file diff --git a/idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt b/idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt index c57b87477b9..cb009caa6b9 100644 --- a/idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt +++ b/idea/testData/quickfix/nullables/unsafeInfixCall/noComparison.kt @@ -1,5 +1,5 @@ // "Replace with safe (?.) call" "false" -// ERROR: Infix call corresponds to a dot-qualified call 'p1.compareTo(p2)' which is not allowed on a nullable receiver 'p1'. Use '?.'-qualified call instead +// ERROR: Operator call corresponds to a dot-qualified call 'p1.compareTo(p2)' which is not allowed on a nullable receiver 'p1'. // ACTION: Add non-null asserted (!!) call // ACTION: Flip '>' // ACTION: Replace overloaded operator with function call diff --git a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt index 2714895ba42..73a26b535c6 100644 --- a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt +++ b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInCondition.kt @@ -2,7 +2,7 @@ // 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 +// ERROR: Operator call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. class Wrapper(val x: Int) diff --git a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt index 1d9be5fa60a..c8762aee2ee 100644 --- a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt +++ b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInLogic.kt @@ -3,7 +3,7 @@ // 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 +// ERROR: Operator call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. class Wrapper(val x: Int) diff --git a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt index 09c13cca28f..4039834c10f 100644 --- a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt +++ b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhen.kt @@ -2,7 +2,7 @@ // 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 +// ERROR: Operator call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. class Wrapper(val x: Int) diff --git a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt index 7177842cc77..ab6aa7b5d78 100644 --- a/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt +++ b/idea/testData/quickfix/nullables/unsafeInfixCall/unsafeComparisonInWhile.kt @@ -2,7 +2,7 @@ // 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 +// ERROR: Operator call corresponds to a dot-qualified call 'w?.x.compareTo(42)' which is not allowed on a nullable receiver 'w?.x'. class Wrapper(val x: Int) diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 984de2855e2..3fb85a245e4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -265,6 +265,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addExclExclCall/normal2.kt"); doTest(fileName); } + + @TestMetadata("operationIn.kt") + public void testOperationIn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/quickfix/addExclExclCall/operationIn.kt"); + doTest(fileName); + } } @TestMetadata("idea/testData/quickfix/addGenericUpperBound")