when renaming a companion object, filter out references to companion object via its containing class, which shouldn't be updated by the rename

This commit is contained in:
Dmitry Jemerov
2015-08-27 18:43:44 +02:00
parent e99316d22e
commit e283dbb8f4
9 changed files with 88 additions and 0 deletions
@@ -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<PsiReference> {
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) {
@@ -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
}
}
@@ -0,0 +1,11 @@
class Foo {
companion object Bar {
fun f() {
}
platformStatic fun s() {
}
val CONST = 42
}
}
@@ -0,0 +1,8 @@
fun main(args: Array<String>) {
// companion object usages
Foo.f()
val x = Foo
Foo.Bar.f()
val xx = Foo.Bar
}
@@ -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
}
}
@@ -0,0 +1,11 @@
class Foo {
companion object Foo {
fun f() {
}
platformStatic fun s() {
}
val CONST = 42
}
}
@@ -0,0 +1,8 @@
fun main(args: Array<String>) {
// companion object usages
Foo.f()
val x = Foo
Foo.Foo.f()
val xx = Foo.Foo
}
@@ -0,0 +1,7 @@
{
"type": "KOTLIN_CLASS",
"classId": "/Foo.Foo",
"oldName": "Foo",
"newName": "Bar",
"mainFile": "toBeRenamed.kt"
}
@@ -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");