diff --git a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties
index f336f72c41a8..a1f4bf2de89c 100644
--- a/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties
+++ b/plugins/kotlin/base/resources/resources-en/messages/KotlinBundle.properties
@@ -1298,8 +1298,11 @@ rename.base.0=Rename base {0,choice,1#function|2#property|3#member|4#method|11#f
rename.declaration.title.0.implements.1.2.of.3={0} {1,choice,1#implements|2#overrides} {2} of {3}
rename.searching.for.all.overrides=Searching for all overrides
rename.searching.for.super.declaration=Searching for the deepest super declaration
-rename.file.name=Rename File Name
+title.rename.file.name=Rename File Name
+file.entity=File
+rename.file.name=Rename file name
rename.file.name.0=Rename File Name to ''{0}''
+title.rename.file.name.to=Rename File Name To:
wrap.with.coroutine.scope.fix.text=Wrap function body with 'coroutineScope { ... }'
wrap.with.coroutine.scope.fix.text2=Wrap call with 'coroutineScope { ... }'
wrap.with.coroutine.scope.fix.text3=Remove receiver \\& wrap with 'coroutineScope { ... }'
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/K1CommonRefactoringSettings.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/K1CommonRefactoringSettings.kt
index fcaa45125415..d4201815879a 100644
--- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/K1CommonRefactoringSettings.kt
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/K1CommonRefactoringSettings.kt
@@ -48,6 +48,9 @@ internal class K1CommonRefactoringSettings : KotlinCommonRefactoringSettingsBase
override var INTRODUCE_SPECIFY_TYPE_EXPLICITLY: Boolean
by delegateTo { it::INTRODUCE_SPECIFY_TYPE_EXPLICITLY }
+ override var renameFileNames: Boolean
+ by delegateTo { it::renameFileNames }
+
override var renameVariables: Boolean
by delegateTo { it::renameVariables }
diff --git a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSettings.kt b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSettings.kt
index 4e45a776b8d7..98a2d1802a9b 100644
--- a/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSettings.kt
+++ b/plugins/kotlin/idea/src/org/jetbrains/kotlin/idea/refactoring/KotlinRefactoringSettings.kt
@@ -85,6 +85,7 @@ class KotlinRefactoringSettings : PersistentStateComponent
+
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/KotlinCommonRefactoringSettings.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/KotlinCommonRefactoringSettings.kt
index cd2bdbb992a7..0693a66d36c9 100644
--- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/KotlinCommonRefactoringSettings.kt
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/KotlinCommonRefactoringSettings.kt
@@ -27,6 +27,11 @@ interface KotlinCommonRefactoringSettings {
var INTRODUCE_DECLARE_WITH_VAR: Boolean
var INTRODUCE_SPECIFY_TYPE_EXPLICITLY: Boolean
+ /**
+ * Indicates whether automatic file rename based on changed type name is suggested
+ */
+ var renameFileNames: Boolean
+
/**
* Indicates whether automatic variable rename based on changed type name is suggested
*/
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticFileRenamer.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticFileRenamer.kt
new file mode 100644
index 000000000000..3ca227a6c61b
--- /dev/null
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/AutomaticFileRenamer.kt
@@ -0,0 +1,60 @@
+// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.
+package org.jetbrains.kotlin.idea.refactoring.rename
+
+import com.intellij.openapi.util.NlsContexts.Button
+import com.intellij.openapi.util.NlsContexts.ColumnName
+import com.intellij.openapi.util.NlsContexts.DialogTitle
+import com.intellij.psi.PsiElement
+import com.intellij.refactoring.rename.naming.AutomaticRenamer
+import com.intellij.refactoring.rename.naming.AutomaticRenamerFactory
+import com.intellij.usageView.UsageInfo
+import org.jetbrains.kotlin.idea.KotlinFileType
+import org.jetbrains.kotlin.idea.base.resources.KotlinBundle
+import org.jetbrains.kotlin.idea.refactoring.KotlinCommonRefactoringSettings
+import org.jetbrains.kotlin.psi.KtFile
+import org.jetbrains.kotlin.psi.KtNamedDeclaration
+import org.jetbrains.kotlin.psi.KtNamedFunction
+import org.jetbrains.kotlin.psi.KtVariableDeclaration
+
+class AutomaticFileRenamer(
+ file: KtFile,
+ newFileName: String,
+) : AutomaticRenamer() {
+
+ init {
+ myElements.add(file)
+ suggestAllNames(file.name, "$newFileName.${file.virtualFile.extension ?: KotlinFileType.EXTENSION}")
+ }
+
+ override fun allowChangeSuggestedName(): Boolean = false
+
+ override fun getDialogTitle(): @DialogTitle String? = KotlinBundle.message("title.rename.file.name")
+
+ override fun getDialogDescription(): @Button String? = KotlinBundle.message("title.rename.file.name.to")
+
+ override fun entityName(): @ColumnName String? = KotlinBundle.message("file.entity")
+
+ override fun isSelectedByDefault(): Boolean = true
+}
+
+open class AutomaticFileRenamerFactory : AutomaticRenamerFactory {
+ override fun isApplicable(element: PsiElement): Boolean {
+ if (!(element is KtNamedFunction || element is KtVariableDeclaration)) return false
+ val file = element.containingFile as? KtFile ?: return false
+
+ val declaration = file.declarations.singleOrNull() as? KtNamedDeclaration ?: return false
+ return declaration.name == file.virtualFile.nameWithoutExtension && element == declaration
+ }
+
+ override fun createRenamer(element: PsiElement, newName: String, usages: Collection): AutomaticFileRenamer {
+ return AutomaticFileRenamer(element.containingFile as KtFile, newName)
+ }
+
+ override fun isEnabled() = KotlinCommonRefactoringSettings.getInstance().renameFileNames
+
+ override fun setEnabled(enabled: Boolean) {
+ KotlinCommonRefactoringSettings.getInstance().renameFileNames = enabled
+ }
+
+ override fun getOptionName(): String? = KotlinBundle.message("rename.file.name")
+}
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt
index 697cd18c6ca5..f92329bbbabe 100644
--- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFunctionProcessor.kt
@@ -5,9 +5,7 @@ package org.jetbrains.kotlin.idea.refactoring.rename
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.project.Project
-import com.intellij.openapi.ui.Messages
import com.intellij.openapi.util.Pass
-import com.intellij.openapi.util.registry.Registry
import com.intellij.psi.*
import com.intellij.psi.search.SearchScope
import com.intellij.refactoring.listeners.RefactoringElementListener
@@ -16,7 +14,6 @@ import com.intellij.refactoring.util.CommonRefactoringUtil
import com.intellij.refactoring.util.RefactoringUtil
import com.intellij.usageView.UsageInfo
import com.intellij.util.SmartList
-import org.jetbrains.annotations.ApiStatus
import org.jetbrains.kotlin.asJava.LightClassUtil
import org.jetbrains.kotlin.asJava.elements.KtLightElement
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
@@ -29,7 +26,6 @@ import org.jetbrains.kotlin.idea.refactoring.conflicts.checkRedeclarationConflic
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.idea.search.KotlinSearchUsagesSupport
import org.jetbrains.kotlin.idea.search.declarationsSearch.findDeepestSuperMethodsKotlinAware
-import org.jetbrains.kotlin.idea.util.application.isUnitTestMode
import org.jetbrains.kotlin.psi.*
class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
@@ -235,8 +231,6 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
}
}
renameRefactoringSupport.prepareForeignUsagesRenaming(element, newName, allRenames, scope)
-
- element.renameFileIfSingleDeclaration(originalName, newName, allRenames)
}
override fun renameElement(element: PsiElement, newName: String, usages: Array, listener: RefactoringElementListener?) {
@@ -289,35 +283,4 @@ class RenameKotlinFunctionProcessor : RenameKotlinPsiProcessor() {
return processFoundReferences(element, references)
}
-}
-
-@ApiStatus.Internal
-internal fun PsiElement.renameFileIfSingleDeclaration(
- originalName: String,
- newName: String,
- allRenames: MutableMap
-) {
- val file = containingFile as? KtFile ?: return
-
- if (file.declarations.singleOrNull() == this) {
- file.virtualFile?.let { virtualFile ->
- val nameWithoutExtensions = virtualFile.nameWithoutExtension
- if (nameWithoutExtensions == originalName) {
- if (!isUnitTestMode() && newName.isNotEmpty() && Messages.showYesNoDialog(
- project,
- KotlinBundle.message("rename.file.name.0", newName),
- KotlinBundle.message("rename.file.name"),
- Messages.getYesButton(),
- Messages.getCancelButton(),
- Messages.getQuestionIcon()
- ) == Messages.NO
- ) {
- return
- }
- val newFileName = newName + "." + virtualFile.extension
- allRenames[file] = newFileName
- RenamePsiElementProcessor.forElement(file).prepareRenaming(file, newFileName, allRenames)
- }
- }
- }
-}
+}
\ No newline at end of file
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt
index dce1a215816e..bf3fb0437e49 100644
--- a/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.common/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinPropertyProcessor.kt
@@ -250,10 +250,6 @@ class RenameKotlinPropertyProcessor : RenameKotlinPsiProcessor() {
}
renameRefactoringSupport.prepareForeignUsagesRenaming(element, newName, allRenames, scope)
-
- originalName?.let {
- element.renameFileIfSingleDeclaration(it, newName, allRenames)
- }
}
protected enum class UsageKind {
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2CommonRefactoringSettings.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2CommonRefactoringSettings.kt
index c0cda77a24bc..20fdb9c0ee94 100644
--- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2CommonRefactoringSettings.kt
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/K2CommonRefactoringSettings.kt
@@ -50,6 +50,9 @@ internal class K2CommonRefactoringSettings : KotlinCommonRefactoringSettingsBase
override var INTRODUCE_SPECIFY_TYPE_EXPLICITLY: Boolean
by delegateTo { it::INTRODUCE_SPECIFY_TYPE_EXPLICITLY }
+ override var renameFileNames: Boolean
+ by delegateTo { it::renameFileNames }
+
override var renameVariables: Boolean
by delegateTo { it::renameVariables }
diff --git a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/KotlinFirRefactoringsSettings.kt b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/KotlinFirRefactoringsSettings.kt
index 58cc5daa5e8c..ed744bc4264a 100644
--- a/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/KotlinFirRefactoringsSettings.kt
+++ b/plugins/kotlin/refactorings/kotlin.refactorings.k2/src/org/jetbrains/kotlin/idea/k2/refactoring/KotlinFirRefactoringsSettings.kt
@@ -17,6 +17,7 @@ class KotlinFirRefactoringsSettings : PersistentStateComponent