diff --git a/ChangeLog.md b/ChangeLog.md index ccca7b5ecd3..05cf4414228 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -267,6 +267,7 @@ Using 'this' as function argument in constructor of non-final class - [`KT-13174`](https://youtrack.jetbrains.com/issue/KT-13174) Move: Warn about accessibility conflicts due to moving to unrelated module - [`KT-13175`](https://youtrack.jetbrains.com/issue/KT-13175) Move: Warn about accessibility conflicts when moving entire file - [`KT-13240`](https://youtrack.jetbrains.com/issue/KT-13240) Rename: Do not report shadowing conflict if redeclaration is detected +- [`KT-13253`](https://youtrack.jetbrains.com/issue/KT-13253) Rename: Report conflicts for constructor parameters ##### New features diff --git a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt index 2e09a10acb8..546997c25d1 100644 --- a/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/findUsages/KotlinElementDescriptionProvider.kt @@ -54,6 +54,7 @@ class KotlinElementDescriptionProvider : ElementDescriptionProvider { is KtClass -> if (targetElement.isInterface()) "interface" else "class" is KtObjectDeclaration -> "object" is KtNamedFunction -> "function" + is KtFunctionLiteral -> "lambda" is KtPrimaryConstructor, is KtSecondaryConstructor -> "constructor" is KtProperty -> if (targetElement.isLocal) "variable" else "property" is KtTypeParameter -> "type parameter" diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt index 46e3672afa8..e5ec68bd61f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinParameterProcessor.kt @@ -31,13 +31,13 @@ import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations import org.jetbrains.kotlin.idea.refactoring.canRefactor import org.jetbrains.kotlin.idea.refactoring.getAffectedCallables import org.jetbrains.kotlin.psi.KtCallableDeclaration +import org.jetbrains.kotlin.psi.KtFunction import org.jetbrains.kotlin.psi.KtNamedDeclaration -import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.KtParameter import org.jetbrains.kotlin.utils.SmartList class RenameKotlinParameterProcessor : RenameKotlinPsiProcessor() { - override fun canProcessElement(element: PsiElement) = element is KtParameter && element.ownerFunction is KtNamedFunction + override fun canProcessElement(element: PsiElement) = element is KtParameter && element.ownerFunction is KtFunction override fun isToSearchInComments(psiElement: PsiElement) = JavaRefactoringSettings.getInstance().RENAME_SEARCH_IN_COMMENTS_FOR_VARIABLE diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameConflictUtils.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameConflictUtils.kt index 25a1ee09645..de5234a7d54 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameConflictUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/renameConflictUtils.kt @@ -64,7 +64,11 @@ import java.util.* internal fun ResolvedCall<*>.noReceivers() = dispatchReceiver == null && extensionReceiver == null -internal fun PsiNamedElement.renderDescription() = "${UsageViewUtil.getType(this)} '$name'".trim() +internal fun PsiNamedElement.renderDescription(): String { + val type = UsageViewUtil.getType(this) + if (name == null || name!!.startsWith("<")) return type + return "$type '$name'".trim() +} internal fun PsiElement.representativeContainer(): PsiNamedElement? = when (this) { diff --git a/idea/testData/refactoring/rename/lambdaParameterRedeclaration/before/test.kt b/idea/testData/refactoring/rename/lambdaParameterRedeclaration/before/test.kt new file mode 100644 index 00000000000..9b50cf7f37a --- /dev/null +++ b/idea/testData/refactoring/rename/lambdaParameterRedeclaration/before/test.kt @@ -0,0 +1,7 @@ +package test + +fun foo(f: (Int, Int) -> Int) = f(1, 2) + +fun test() { + foo { /*rename*/a, b -> a + b } +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test b/idea/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test new file mode 100644 index 00000000000..4e3058e7068 --- /dev/null +++ b/idea/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test @@ -0,0 +1,7 @@ +{ + "type": "MARKED_ELEMENT", + "mainFile": "test.kt", + "newName": "b", + "withRuntime": "true", + "hint": "Parameter 'b' is already declared in lambda" +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/before/test.kt b/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/before/test.kt new file mode 100644 index 00000000000..3891798b7c4 --- /dev/null +++ b/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/before/test.kt @@ -0,0 +1,3 @@ +package test + +class A(/*rename*/cpa: Int, cpb: Int) \ No newline at end of file diff --git a/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test b/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test new file mode 100644 index 00000000000..c2bd090a8b3 --- /dev/null +++ b/idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test @@ -0,0 +1,7 @@ +{ + "type": "MARKED_ELEMENT", + "mainFile": "test.kt", + "newName": "cpb", + "withRuntime": "true", + "hint": "Parameter 'cpb' is already declared in class 'A'" +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/before/test.kt b/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/before/test.kt new file mode 100644 index 00000000000..ed975d5df4e --- /dev/null +++ b/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/before/test.kt @@ -0,0 +1,5 @@ +package test + +class A { + constructor(/*rename*/cpa: Int, cpb: Int) +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test b/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test new file mode 100644 index 00000000000..df86e64b390 --- /dev/null +++ b/idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test @@ -0,0 +1,7 @@ +{ + "type": "MARKED_ELEMENT", + "mainFile": "test.kt", + "newName": "cpb", + "withRuntime": "true", + "hint": "Parameter 'cpb' is already declared in constructor 'A'" +} \ 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 60483393267..ddc4ed7a0d4 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -185,6 +185,12 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("lambdaParameterRedeclaration/lambdaParameterRedeclaration.test") + public void testLambdaParameterRedeclaration_LambdaParameterRedeclaration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test"); + doTest(fileName); + } + @TestMetadata("memberFunctionRedeclaration/memberFunctionRedeclaration.test") public void testMemberFunctionRedeclaration_MemberFunctionRedeclaration() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/memberFunctionRedeclaration/memberFunctionRedeclaration.test"); @@ -239,6 +245,12 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test") + public void testPrimaryConstructorParameterRedeclaration_PrimaryConstructorParameterRedeclaration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/primaryConstructorParameterRedeclaration/primaryConstructorParameterRedeclaration.test"); + doTest(fileName); + } + @TestMetadata("propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test") public void testPropertyAccidentalOverrideSubclass_PropertyAccidentalOverrideSubclass() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/propertyAccidentalOverrideSubclass/propertyAccidentalOverrideSubclass.test"); @@ -995,6 +1007,12 @@ public class RenameTestGenerated extends AbstractRenameTest { doTest(fileName); } + @TestMetadata("secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test") + public void testSecondaryCnstructorParameterRedeclaration_SecondaryConstructorParameterRedeclaration() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/secondaryCnstructorParameterRedeclaration/secondaryConstructorParameterRedeclaration.test"); + doTest(fileName); + } + @TestMetadata("syntheticPropertyUsages1/renameGetMethod.test") public void testSyntheticPropertyUsages1_RenameGetMethod() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/syntheticPropertyUsages1/renameGetMethod.test");