From aaa873f2278d71bf09abfe51ad47d7507a7a315c Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 25 Apr 2016 12:30:35 +0300 Subject: [PATCH] Move: Convert implicit receiver to this when moving class member to companion object #KT-11483 Fixed --- ChangeLog.md | 1 + .../kotlin/idea/core/ShortenReferences.kt | 1 + .../MoveMemberToCompanionObjectIntention.kt | 37 ++++++++++++------- .../implicitDispatchReceiver.kt | 9 +++++ .../implicitDispatchReceiver.kt.after | 14 +++++++ .../intentions/IntentionTestGenerated.java | 6 +++ 6 files changed, 54 insertions(+), 14 deletions(-) create mode 100644 idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt create mode 100644 idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt.after diff --git a/ChangeLog.md b/ChangeLog.md index f0f85c2ac8d..74129f37cb1 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -38,6 +38,7 @@ Issues fixed: - [KT-11282](https://youtrack.jetbrains.com/issue/KT-11282) Delete interface reference from super-type list when applying Safe Delete to Java interface - [KT-11967](https://youtrack.jetbrains.com/issue/KT-11967) Fix Find Usages/Rename for parameter references in XML files - [KT-11482](https://youtrack.jetbrains.com/issue/KT-11482) Fixed exception in "Move to companion object" intention +- [KT-11483](https://youtrack.jetbrains.com/issue/KT-11483) Pass implicit receiver as argument when moving member function to companion object #### Debugger diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt index c953c09f0a3..1bd4e5fcbb3 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/ShortenReferences.kt @@ -57,6 +57,7 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT ) { companion object { val DEFAULT = Options() + val ALL_ENABLED = Options(true, true) } } diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt index 097f71569cd..a2e617a8325 100644 --- a/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt +++ b/idea/src/org/jetbrains/kotlin/idea/intentions/MoveMemberToCompanionObjectIntention.kt @@ -57,6 +57,7 @@ import org.jetbrains.kotlin.idea.core.ShortenReferences import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.* @@ -115,7 +116,7 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention { val qualifier = refElement.qualifier @@ -127,15 +128,15 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention { - val call = refElement.parent as? KtCallExpression - val receiver = call?.getQualifiedExpressionForSelector()?.receiverExpression - if (call != null && receiver != null) { - val psiFactory = KtPsiFactory(refElement) - val argumentList = call.valueArgumentList - ?: call.addAfter(psiFactory.createCallArguments("()"), call.typeArgumentList ?: refElement) as KtValueArgumentList - argumentList.addArgumentBefore(psiFactory.createArgument(receiver), - argumentList.arguments.firstOrNull()) - } + val call = refElement.parent as? KtCallExpression ?: return + val psiFactory = KtPsiFactory(refElement) + val argumentList = call.valueArgumentList + ?: call.addAfter(psiFactory.createCallArguments("()"), call.typeArgumentList ?: refElement) as KtValueArgumentList + + val receiver = call.getQualifiedExpressionForSelector()?.receiverExpression + val receiverArg = receiver?.let { psiFactory.createArgument(it) } + ?: psiFactory.createArgument(psiFactory.createExpression("this@${classFqName.asString()}")) + argumentList.addArgumentBefore(receiverArg, argumentList.arguments.firstOrNull()) } } } @@ -190,6 +191,8 @@ class MoveMemberToCompanionObjectIntention : SelfTargetingRangeIntention { usage.callExpression .let { it.replaced(ktPsiFactory.createExpressionByPattern("$0.$1", ktCompanionRef, it)) } - .let { elementsToShorten += (it as KtQualifiedExpression).receiverExpression } + .let { + val qualifiedCall = it as KtQualifiedExpression + elementsToShorten += qualifiedCall.receiverExpression + if (hasInstanceArg) { + elementsToShorten += (qualifiedCall.selectorExpression as KtCallExpression).valueArguments.first() + } + } } } } - ShortenReferences.DEFAULT.process(elementsToShorten) + ShortenReferences { ShortenReferences.Options.ALL_ENABLED }.process(elementsToShorten) runTemplateForInstanceParam(newDeclaration, nameSuggestions, editor) } diff --git a/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt b/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt new file mode 100644 index 00000000000..f79b85ddc1f --- /dev/null +++ b/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt @@ -0,0 +1,9 @@ +fun println(a: Any) {} + +class InsertThis { + val v1 = 1 + fun f() { + println(v1) + } + fun use() { f() } +} \ No newline at end of file diff --git a/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt.after b/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt.after new file mode 100644 index 00000000000..f124cad216c --- /dev/null +++ b/idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt.after @@ -0,0 +1,14 @@ +fun println(a: Any) {} + +class InsertThis { + val v1 = 1 + fun use() { + Companion.f(this) + } + + companion object { + fun f(insertThis: InsertThis) { + println(insertThis.v1) + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java index 336f12c92ac..60dfe9785f1 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/intentions/IntentionTestGenerated.java @@ -6886,6 +6886,12 @@ public class IntentionTestGenerated extends AbstractIntentionTest { doTest(fileName); } + @TestMetadata("implicitDispatchReceiver.kt") + public void testImplicitDispatchReceiver() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveToCompanion/implicitDispatchReceiver.kt"); + doTest(fileName); + } + @TestMetadata("inInnerClass.kt") public void testInInnerClass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/intentions/moveToCompanion/inInnerClass.kt");