Skip to content

Commit 895407f

Browse files
committed
Rename: Do not silently rename all parameters in function hierarchy
#KT-18325 Fixed
1 parent 31d21a1 commit 895407f

File tree

21 files changed

+311
-33
lines changed

21 files changed

+311
-33
lines changed

idea/src/META-INF/plugin.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@
519519
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticInheritorRenamerFactory"/>
520520
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticOverloadsRenamerFactory"/>
521521
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinAutomaticTestRenamerFactory"/>
522+
<automaticRenamerFactory implementation="org.jetbrains.kotlin.idea.refactoring.rename.AutomaticParameterRenamerFactory"/>
522523
<vetoRenameCondition implementation="org.jetbrains.kotlin.idea.refactoring.KotlinVetoRenameCondition"/>
523524
<renameInputValidator implementation="org.jetbrains.kotlin.idea.refactoring.rename.KotlinDeclarationRenameInputValidator"/>
524525
<rename.inplace.resolveSnapshotProvider
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2010-2017 JetBrains s.r.o.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.jetbrains.kotlin.idea.refactoring.rename
18+
19+
import com.intellij.psi.PsiElement
20+
import com.intellij.psi.PsiMethod
21+
import com.intellij.psi.PsiNamedElement
22+
import com.intellij.refactoring.JavaRefactoringSettings
23+
import com.intellij.refactoring.RefactoringBundle
24+
import com.intellij.refactoring.rename.naming.AutomaticRenamer
25+
import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory
26+
import com.intellij.usageView.UsageInfo
27+
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
28+
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
29+
import org.jetbrains.kotlin.idea.refactoring.canRefactor
30+
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
31+
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
32+
import org.jetbrains.kotlin.psi.KtCallableDeclaration
33+
import org.jetbrains.kotlin.psi.KtNamedFunction
34+
import org.jetbrains.kotlin.psi.KtParameter
35+
36+
class AutomaticParameterRenamer(element: KtParameter, newName: String) : AutomaticRenamer() {
37+
init {
38+
processHierarchy(element, newName)
39+
}
40+
41+
private fun processHierarchy(element: KtParameter, newName: String) {
42+
val function = element.ownerFunction ?: return
43+
for (overrider in HierarchySearchRequest(function, function.useScope).searchOverriders()) {
44+
val callable = overrider.namedUnwrappedElement ?: continue
45+
if (!callable.canRefactor()) continue
46+
val parameter: PsiNamedElement? =
47+
when (callable) {
48+
is KtCallableDeclaration -> callable.valueParameters.firstOrNull { it.name == element.name }
49+
is PsiMethod -> callable.parameterList.parameters.firstOrNull { it.name == element.name }
50+
else -> null
51+
}
52+
if (parameter == null) continue
53+
myElements += parameter
54+
}
55+
suggestAllNames(element.name, newName.quoteIfNeeded())
56+
}
57+
58+
override fun getDialogTitle() = "Rename Parameters"
59+
60+
override fun getDialogDescription() = "Rename parameter in hierarchy to:"
61+
62+
override fun entityName() = "Parameter"
63+
64+
override fun isSelectedByDefault() = true
65+
}
66+
67+
class AutomaticParameterRenamerFactory : AutomaticRenamerFactory {
68+
override fun isApplicable(element: PsiElement) = element is KtParameter && element.ownerFunction is KtNamedFunction
69+
70+
override fun getOptionName() = RefactoringBundle.message("rename.parameters.hierarchy")!!
71+
72+
override fun isEnabled() = JavaRefactoringSettings.getInstance().isRenameParameterInHierarchy
73+
74+
override fun setEnabled(enabled: Boolean) {
75+
JavaRefactoringSettings.getInstance().isRenameParameterInHierarchy = enabled
76+
}
77+
78+
override fun createRenamer(element: PsiElement, newName: String, usages: Collection<UsageInfo>): AutomaticRenamer {
79+
return AutomaticParameterRenamer(element as KtParameter, newName)
80+
}
81+
}

idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,12 @@
1717
package org.jetbrains.kotlin.idea.refactoring.rename
1818

1919
import com.intellij.psi.PsiElement
20-
import com.intellij.psi.PsiMethod
21-
import com.intellij.psi.PsiNamedElement
22-
import com.intellij.psi.search.SearchScope
2320
import com.intellij.refactoring.JavaRefactoringSettings
2421
import com.intellij.refactoring.listeners.RefactoringElementListener
2522
import com.intellij.usageView.UsageInfo
2623
import org.jetbrains.kotlin.asJava.namedUnwrappedElement
27-
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
2824
import org.jetbrains.kotlin.descriptors.VariableDescriptor
2925
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
30-
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
31-
import org.jetbrains.kotlin.idea.core.quoteIfNeeded
32-
import org.jetbrains.kotlin.idea.refactoring.canRefactor
33-
import org.jetbrains.kotlin.idea.refactoring.getAffectedCallables
34-
import org.jetbrains.kotlin.psi.KtCallableDeclaration
3526
import org.jetbrains.kotlin.psi.KtFunction
3627
import org.jetbrains.kotlin.psi.KtNamedDeclaration
3728
import org.jetbrains.kotlin.psi.KtParameter
@@ -63,26 +54,6 @@ class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() {
6354
result += collisions
6455
}
6556

66-
override fun prepareRenaming(element: PsiElement, newName: String?, allRenames: MutableMap<PsiElement, String>, scope: SearchScope) {
67-
super.prepareRenaming(element, newName, allRenames, scope)
68-
69-
if (element !is KtParameter || newName == null) return
70-
71-
val function = element.ownerFunction ?: return
72-
val originalDescriptor = function.resolveToDescriptor() as FunctionDescriptor
73-
val affectedCallables = getAffectedCallables(element.project, originalDescriptor.getDeepestSuperDeclarations())
74-
for (callable in affectedCallables) {
75-
if (!callable.canRefactor()) continue
76-
val parameter: PsiNamedElement? = when (callable) {
77-
is KtCallableDeclaration -> callable.valueParameters.firstOrNull { it.name == element.name }
78-
is PsiMethod -> callable.parameterList.parameters.firstOrNull { it.name == element.name }
79-
else -> null
80-
}
81-
if (parameter == null) continue
82-
allRenames[parameter] = newName.quoteIfNeeded()
83-
}
84-
}
85-
8657
override fun renameElement(element: PsiElement, newName: String?, usages: Array<out UsageInfo>, listener: RefactoringElementListener?) {
8758
super.renameElement(element, newName, usages, listener)
8859

idea/testData/refactoring/rename/automaticRenamerParameter/after/main.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package testing
22

33
interface Trait {
4-
open fun foo(aa: Int, b: String) {
4+
open fun foo(a: Int, b: String) {
55
}
66
}
77

88
open class Super {
9-
open fun foo(aa: Int, b: String) {
9+
open fun foo(a: Int, b: String) {
1010
}
1111
}
1212

idea/testData/refactoring/rename/automaticRenamerParameterInExtension/after/main.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package testing
22

33
interface Trait {
4-
open fun Int.foo(aa: Int, b: String) {
4+
open fun Int.foo(a: Int, b: String) {
55
}
66
}
77

88
open class Super {
9-
open fun Int.foo(aa: Int, b: String) {
9+
open fun Int.foo(a: Int, b: String) {
1010
}
1111
}
1212

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String s) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String s) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String s) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(s: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(s: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(x: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(s: String) { }
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String s) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String s) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String s) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(s: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(s: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(/*rename*/s: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(s: String) { }
15+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "MARKED_ELEMENT",
3+
"mainFile": "test.kt",
4+
"newName": "x"
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String s) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String s) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String x) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(s: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(x: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(s: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(x: String) { }
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String s) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String s) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String s) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(s: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(/*rename*/s: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(s: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(s: String) { }
15+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"type": "MARKED_ELEMENT",
3+
"mainFile": "test.kt",
4+
"newName": "x"
5+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String x) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String x) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String x) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(x: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(x: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(x: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(x: String) { }
15+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class J1 implements Foo {
2+
public void foo(String s) {
3+
4+
}
5+
}
6+
7+
class J2 extends J1 {
8+
public void foo(String s) {
9+
10+
}
11+
}
12+
13+
class J3 extends Foo1 {
14+
public void foo(String s) {
15+
16+
}
17+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
interface Foo {
2+
fun foo(/*rename*/s: String)
3+
}
4+
5+
open class Foo1 : Foo {
6+
override fun foo(s: String) { }
7+
}
8+
9+
class Foo2 : Foo {
10+
override fun foo(s: String) { }
11+
}
12+
13+
class Foo3 : Foo1() {
14+
override fun foo(s: String) { }
15+
}

0 commit comments

Comments
 (0)