diff --git a/ChangeLog.md b/ChangeLog.md index 6e6db36cbb9..5318b1bce36 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -171,6 +171,9 @@ #### Refactorings +###### New features +- [`KT-7851`](https://youtrack.jetbrains.com/issue/KT-7851) Respect naming conventions in automatic variable rename + ###### Issues fixed - [`KT-9156`](https://youtrack.jetbrains.com/issue/KT-9156) Quote non-identifier names in Kotlin references - [`KT-9157`](https://youtrack.jetbrains.com/issue/KT-9157) Fixed in-place rename of Kotlin expression referring Java declaration diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticVariableRenamer.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticVariableRenamer.kt index a7ebaf6ca58..c4f30174a79 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticVariableRenamer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticVariableRenamer.kt @@ -21,6 +21,8 @@ import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiClass import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement +import com.intellij.psi.PsiVariable +import com.intellij.psi.codeStyle.JavaCodeStyleManager import com.intellij.psi.util.PsiTreeUtil import com.intellij.refactoring.JavaRefactoringSettings import com.intellij.refactoring.RefactoringBundle @@ -28,6 +30,7 @@ import com.intellij.refactoring.rename.naming.AutomaticRenamer import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory import com.intellij.usageView.UsageInfo import org.jetbrains.kotlin.asJava.toLightClass +import org.jetbrains.kotlin.asJava.toLightElements import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptor @@ -39,6 +42,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns import org.jetbrains.kotlin.resolve.lazy.NoDescriptorForDeclarationException import org.jetbrains.kotlin.resolve.source.PsiSourceElement import org.jetbrains.kotlin.types.KotlinType +import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull import java.util.* class AutomaticVariableRenamer( @@ -85,19 +89,37 @@ class AutomaticVariableRenamer( override fun entityName() = RefactoringBundle.message("entity.name.variable") override fun nameToCanonicalName(name: String, element: PsiNamedElement): String? { + if (element !is KtNamedDeclaration) return name + + val psiVariable = element.toLightElements().firstIsInstanceOrNull() + val propertyName = if (psiVariable != null) { + val codeStyleManager = JavaCodeStyleManager.getInstance(psiVariable.project) + codeStyleManager.variableNameToPropertyName(name, codeStyleManager.getVariableKind(psiVariable)) + } + else name + if (element in toUnpluralize) { - val singular = StringUtil.unpluralize(name) + val singular = StringUtil.unpluralize(propertyName) if (singular != null) return singular toUnpluralize.remove(element) } - return name + return propertyName } override fun canonicalNameToName(canonicalName: String, element: PsiNamedElement): String? { + if (element !is KtNamedDeclaration) return canonicalName + + val psiVariable = element.toLightElements().firstIsInstanceOrNull() + val varName = if (psiVariable != null) { + val codeStyleManager = JavaCodeStyleManager.getInstance(psiVariable.project) + codeStyleManager.propertyNameToVariableName(canonicalName, codeStyleManager.getVariableKind(psiVariable)) + } + else canonicalName + return if (element in toUnpluralize) - StringUtil.pluralize(canonicalName) + StringUtil.pluralize(varName) else - canonicalName + varName } companion object { diff --git a/idea/testData/refactoring/rename/automaticRenamer/after/main.kt b/idea/testData/refactoring/rename/automaticRenamer/after/main.kt index 16ac8766c59..165a7a1496e 100644 --- a/idea/testData/refactoring/rename/automaticRenamer/after/main.kt +++ b/idea/testData/refactoring/rename/automaticRenamer/after/main.kt @@ -1,10 +1,10 @@ open class Bar : Throwable() -val bar: Bar = Bar() -val bar1: Bar = Bar() +val BAR: Bar = Bar() +val BAR_1: Bar = Bar() -val bars: List = listOf() -val foos1: Array = array() +val BARs: List = listOf() +val FOOS_1: Array = array() fun main(args: Array) { val bar: Bar = Bar() diff --git a/idea/testData/refactoring/rename/automaticRenamerForJavaClass/after/usage.kt b/idea/testData/refactoring/rename/automaticRenamerForJavaClass/after/usage.kt index 36c030fc881..ce0416380a5 100644 --- a/idea/testData/refactoring/rename/automaticRenamerForJavaClass/after/usage.kt +++ b/idea/testData/refactoring/rename/automaticRenamerForJavaClass/after/usage.kt @@ -2,5 +2,5 @@ class BarImpl : Bar() object BarObj : Bar() -val bar: Bar = Bar() -val bars: Array = throw Error() \ No newline at end of file +val BAR: Bar = Bar() +val BARs: Array = throw Error() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/after/test.kt b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/after/test.kt new file mode 100644 index 00000000000..c8a53b4c8b3 --- /dev/null +++ b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/after/test.kt @@ -0,0 +1,13 @@ +package test + +class Bar { + +} + +val SOME_BAR: Bar = Bar() +val BAR: Bar = Bar() + +val SOME___BAR: Bar = Bar() +val BAR: Bar = Bar() + +val SOME_BAR: Bar = Bar() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/before/test.kt b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/before/test.kt new file mode 100644 index 00000000000..e86f9620bec --- /dev/null +++ b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/before/test.kt @@ -0,0 +1,13 @@ +package test + +class Foo { + +} + +val SOME_FOO: Foo = Foo() +val FOO: Foo = Foo() + +val some_foo: Foo = Foo() +val foo: Foo = Foo() + +val SomeFoo: Foo = Foo() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test new file mode 100644 index 00000000000..88b4ce89d63 --- /dev/null +++ b/idea/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test @@ -0,0 +1,6 @@ +{ + "type": "KOTLIN_CLASS", + "mainFile": "test.kt", + "classId": "test/Foo", + "newName": "Bar" +} \ 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 e19dd023d07..fd8f4290d51 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -125,6 +125,12 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test") + public void testRenameClassWithAutoVarConventions_RenameClassWithAutoVarConventions() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameClassWithAutoVarConventions/renameClassWithAutoVarConventions.test"); + doTest(fileName); + } + @TestMetadata("renameCompareTo/compareTo.test") public void testRenameCompareTo_CompareTo() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameCompareTo/compareTo.test");