From a9ddc4da1ab4b09809f62d7ba8af71c8b6924d1c Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 5 Feb 2016 15:18:57 +0300 Subject: [PATCH] Change Signature: Warn about safe call receiver being transformed to value argument #KT-8744 Fixed --- .../KotlinChangeSignatureUsageProcessor.kt | 23 +++++++++++++++++++ .../ReceiverInSafeCallBefore.kt | 5 ++++ .../ReceiverInSafeCallMessages.txt | 1 + .../KotlinChangeSignatureTest.kt | 2 ++ 4 files changed, 31 insertions(+) create mode 100644 idea/testData/refactoring/changeSignature/ReceiverInSafeCallBefore.kt create mode 100644 idea/testData/refactoring/changeSignature/ReceiverInSafeCallMessages.txt diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt index 2dccc1c82f6..d3d29f54e0c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureUsageProcessor.kt @@ -584,6 +584,7 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor { if (function is KtCallableDeclaration && newReceiverInfo != originalReceiverInfo) { findReceiverIntroducingConflicts(result, function, newReceiverInfo) findInternalExplicitReceiverConflicts(refUsages.get(), result, originalReceiverInfo) + findReceiverToParameterInSafeCallsConflicts(refUsages.get(), result, info) findThisLabelConflicts(refUsages, result, info, function) } @@ -674,6 +675,28 @@ class KotlinChangeSignatureUsageProcessor : ChangeSignatureUsageProcessor { } } + private fun findReceiverToParameterInSafeCallsConflicts( + usages: Array, + result: MultiMap, + changeInfo: KotlinChangeInfo + ) { + val originalReceiverInfo = changeInfo.methodDescriptor.receiver + if (originalReceiverInfo == null || originalReceiverInfo !in changeInfo.getNonReceiverParameters()) return + + for (usageInfo in usages) { + if (!(usageInfo is KotlinFunctionCallUsage || usageInfo is KotlinPropertyCallUsage)) continue + + val callElement = usageInfo.element as? KtElement ?: continue + val qualifiedExpression = callElement.getQualifiedExpressionForSelector() + if (qualifiedExpression is KtSafeQualifiedExpression) { + result.putValue( + callElement, + "Receiver can't be safely transformed to value argument: ${CommonRefactoringUtil.htmlEmphasize(qualifiedExpression.text)}" + ) + } + } + } + private fun findReceiverIntroducingConflicts( result: MultiMap, callable: PsiElement, diff --git a/idea/testData/refactoring/changeSignature/ReceiverInSafeCallBefore.kt b/idea/testData/refactoring/changeSignature/ReceiverInSafeCallBefore.kt new file mode 100644 index 00000000000..e5e061416fd --- /dev/null +++ b/idea/testData/refactoring/changeSignature/ReceiverInSafeCallBefore.kt @@ -0,0 +1,5 @@ +interface A { + val parent: A? +} + +fun A.ext(): Int = 1 + (parent?.ext() ?: 0) \ No newline at end of file diff --git a/idea/testData/refactoring/changeSignature/ReceiverInSafeCallMessages.txt b/idea/testData/refactoring/changeSignature/ReceiverInSafeCallMessages.txt new file mode 100644 index 00000000000..36c74e9df60 --- /dev/null +++ b/idea/testData/refactoring/changeSignature/ReceiverInSafeCallMessages.txt @@ -0,0 +1 @@ +Receiver can't be safely transformed to value argument: parent?.ext() \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt index 2ae21081ed6..a5a085e49b1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/changeSignature/KotlinChangeSignatureTest.kt @@ -949,4 +949,6 @@ class KotlinChangeSignatureTest : KotlinCodeInsightTestCase() { receiverParameterInfo = null newParameters[0].name = "a" } + + fun testReceiverInSafeCall() = doTestConflict { receiverParameterInfo = null } } \ No newline at end of file