From e283dbb8f48af21c5772e9c2ad3fb9744fd86d34 Mon Sep 17 00:00:00 2001 From: Dmitry Jemerov Date: Thu, 27 Aug 2015 18:43:44 +0200 Subject: [PATCH] when renaming a companion object, filter out references to companion object via its containing class, which shouldn't be updated by the rename --- .../rename/RenameKotlinClassProcessor.kt | 21 +++++++++++++++++++ .../after/JavaUsage.java | 8 +++++++ .../after/toBeRenamed.kt | 11 ++++++++++ .../after/usage.kt | 8 +++++++ .../before/JavaUsage.java | 8 +++++++ .../before/toBeRenamed.kt | 11 ++++++++++ .../before/usage.kt | 8 +++++++ .../companionObject.test | 7 +++++++ .../rename/RenameTestGenerated.java | 6 ++++++ 9 files changed, 88 insertions(+) create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/JavaUsage.java create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/toBeRenamed.kt create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/usage.kt create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/JavaUsage.java create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/toBeRenamed.kt create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/usage.kt create mode 100644 idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/companionObject.test diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt index 8bf3824f10d..1245abc2369 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt @@ -18,14 +18,20 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.editor.Editor import com.intellij.psi.PsiElement +import com.intellij.psi.PsiReference import com.intellij.refactoring.RefactoringBundle import com.intellij.refactoring.util.CommonRefactoringUtil import org.jetbrains.kotlin.asJava.KotlinLightClass import org.jetbrains.kotlin.asJava.KotlinLightClassForExplicitDeclaration import org.jetbrains.kotlin.asJava.KotlinLightClassForPackage import org.jetbrains.kotlin.idea.JetBundle +import org.jetbrains.kotlin.idea.caches.resolve.analyze +import org.jetbrains.kotlin.idea.references.JetSimpleNameReference import org.jetbrains.kotlin.psi.JetClassOrObject import org.jetbrains.kotlin.psi.JetConstructor +import org.jetbrains.kotlin.psi.JetObjectDeclaration +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode public class RenameKotlinClassProcessor : RenameKotlinPsiProcessor() { override fun canProcessElement(element: PsiElement): Boolean { @@ -50,6 +56,21 @@ public class RenameKotlinClassProcessor : RenameKotlinPsiProcessor() { } } + override fun findReferences(element: PsiElement): Collection { + if (element is JetObjectDeclaration && element.isCompanion()) { + return super.findReferences(element).filter { !it.isCompanionObjectClassReference() } + } + return super.findReferences(element) + } + + private fun PsiReference.isCompanionObjectClassReference(): Boolean { + if (this !is JetSimpleNameReference) { + return false + } + val bindingContext = element.analyze(BodyResolveMode.PARTIAL) + return bindingContext[BindingContext.SHORT_REFERENCE_TO_COMPANION_OBJECT, element] != null + } + private fun getJetClassOrObject(element: PsiElement?, showErrors: Boolean, editor: Editor?): JetClassOrObject? = when (element) { is KotlinLightClass -> if (element is KotlinLightClassForExplicitDeclaration) { diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/JavaUsage.java b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/JavaUsage.java new file mode 100644 index 00000000000..70d5d6dc1e1 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/JavaUsage.java @@ -0,0 +1,8 @@ +class JavaUsage { + public static void main(String[] args) { + System.out.println(Foo.CONST); + Foo.s(); + Foo.Bar.f(); + Foo foo = new Foo(); // not usage of companion object + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/toBeRenamed.kt b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/toBeRenamed.kt new file mode 100644 index 00000000000..06743a34047 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/toBeRenamed.kt @@ -0,0 +1,11 @@ +class Foo { + companion object Bar { + fun f() { + } + + platformStatic fun s() { + } + + val CONST = 42 + } +} diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/usage.kt b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/usage.kt new file mode 100644 index 00000000000..48a837993b1 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/after/usage.kt @@ -0,0 +1,8 @@ +fun main(args: Array) { + // companion object usages + Foo.f() + val x = Foo + + Foo.Bar.f() + val xx = Foo.Bar +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/JavaUsage.java b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/JavaUsage.java new file mode 100644 index 00000000000..70d5d6dc1e1 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/JavaUsage.java @@ -0,0 +1,8 @@ +class JavaUsage { + public static void main(String[] args) { + System.out.println(Foo.CONST); + Foo.s(); + Foo.Bar.f(); + Foo foo = new Foo(); // not usage of companion object + } +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/toBeRenamed.kt b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/toBeRenamed.kt new file mode 100644 index 00000000000..5ea6079dd5a --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/toBeRenamed.kt @@ -0,0 +1,11 @@ +class Foo { + companion object Foo { + fun f() { + } + + platformStatic fun s() { + } + + val CONST = 42 + } +} diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/usage.kt b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/usage.kt new file mode 100644 index 00000000000..6925c3b0701 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/before/usage.kt @@ -0,0 +1,8 @@ +fun main(args: Array) { + // companion object usages + Foo.f() + val x = Foo + + Foo.Foo.f() + val xx = Foo.Foo +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/companionObject.test b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/companionObject.test new file mode 100644 index 00000000000..d1e7599cf74 --- /dev/null +++ b/idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/companionObject.test @@ -0,0 +1,7 @@ +{ + "type": "KOTLIN_CLASS", + "classId": "/Foo.Foo", + "oldName": "Foo", + "newName": "Bar", + "mainFile": "toBeRenamed.kt" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java index 6a1a0572f7d..c41a89afaa3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -101,6 +101,12 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("companionObjectWithNameMatchingClass/companionObject.test") + public void testCompanionObjectWithNameMatchingClass_CompanionObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/companionObjectWithNameMatchingClass/companionObject.test"); + doTest(fileName); + } + @TestMetadata("renameArgumentsWhenParameterRenamed/parameter.test") public void testRenameArgumentsWhenParameterRenamed_Parameter() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameArgumentsWhenParameterRenamed/parameter.test");