diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/PackagePartClassUtils.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/PackagePartClassUtils.kt
index 7d6609ca075..f75617574d4 100644
--- a/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/PackagePartClassUtils.kt
+++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/PackagePartClassUtils.kt
@@ -36,7 +36,7 @@ public object PackagePartClassUtils {
private val PART_CLASS_NAME_SUFFIX = "Kt"
- private @JvmStatic fun getPartClassName(str: String): String =
+ public @JvmStatic fun getPartClassName(str: String): String =
if (str.isEmpty())
"_$PART_CLASS_NAME_SUFFIX"
else
diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt
index 7de316b9d5c..e1699d73b99 100644
--- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt
+++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KotlinLightClassForFacade.kt
@@ -180,6 +180,8 @@ public class KotlinLightClassForFacade private constructor(
override fun getName() = facadeClassFqName.shortName().asString()
+ override fun setName(name: String): PsiElement? = this
+
override fun getQualifiedName() = facadeClassFqName.asString()
override fun isValid() = files.all { it.isValid() }
diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml
index 9e6defd3b98..1221c63d036 100644
--- a/idea/src/META-INF/plugin.xml
+++ b/idea/src/META-INF/plugin.xml
@@ -353,6 +353,9 @@
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt
index 3f1218500a1..e249cb86ba6 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinClassProcessor.kt
@@ -20,7 +20,9 @@ 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.listeners.RefactoringElementListener
import com.intellij.refactoring.util.CommonRefactoringUtil
+import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.asJava.KotlinLightClass
import org.jetbrains.kotlin.asJava.KotlinLightClassForExplicitDeclaration
import org.jetbrains.kotlin.asJava.KotlinLightClassForFacade
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt
new file mode 100644
index 00000000000..385794f7dc5
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2010-2015 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jetbrains.kotlin.idea.refactoring.rename
+
+import com.intellij.openapi.fileTypes.FileTypeManager
+import com.intellij.openapi.util.io.FileUtil
+import com.intellij.psi.JavaPsiFacade
+import com.intellij.psi.PsiElement
+import com.intellij.psi.search.SearchScope
+import com.intellij.refactoring.rename.RenamePsiFileProcessor
+import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
+import org.jetbrains.kotlin.idea.JetFileType
+import org.jetbrains.kotlin.idea.search.allScope
+import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils
+import org.jetbrains.kotlin.psi.JetFile
+
+class RenameKotlinFileProcessor() : RenamePsiFileProcessor() {
+ override fun canProcessElement(element: PsiElement) = element is JetFile
+
+ override fun prepareRenaming(element: PsiElement?,
+ newName: String,
+ allRenames: MutableMap,
+ scope: SearchScope) {
+ val jetFile = element as? JetFile ?: return
+ if (FileTypeManager.getInstance().getFileTypeByFileName(newName) != JetFileType.INSTANCE) {
+ return
+ }
+
+ val fileInfo = JvmFileClassUtil.getFileClassInfoNoResolve(jetFile)
+ if (!fileInfo.isWithJvmName) {
+ val facadeFqName = fileInfo.facadeClassFqName
+ val project = jetFile.project
+ val facadeClass = JavaPsiFacade.getInstance(project).findClass(facadeFqName.asString(), project.allScope())
+ if (facadeClass != null) {
+ allRenames[facadeClass] = PackagePartClassUtils.getPartClassName(FileUtil.getNameWithoutExtension(newName))
+ }
+ }
+ }
+}
diff --git a/idea/testData/refactoring/rename/renameKotlinFile/after/Bar.kt b/idea/testData/refactoring/rename/renameKotlinFile/after/Bar.kt
new file mode 100644
index 00000000000..664d7964f2a
--- /dev/null
+++ b/idea/testData/refactoring/rename/renameKotlinFile/after/Bar.kt
@@ -0,0 +1,3 @@
+package testing.rename
+
+var foo: String = "xyzzy"
diff --git a/idea/testData/refactoring/rename/renameKotlinFile/after/testing/JavaClient.java b/idea/testData/refactoring/rename/renameKotlinFile/after/testing/JavaClient.java
new file mode 100644
index 00000000000..ce1b7b7b8a4
--- /dev/null
+++ b/idea/testData/refactoring/rename/renameKotlinFile/after/testing/JavaClient.java
@@ -0,0 +1,10 @@
+package testing;
+
+import testing.rename.BarKt;
+
+class JavaClient {
+ public void foo() {
+ String old = BarKt.getFoo();
+ BarKt.setFoo(old + "new");
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/rename/renameKotlinFile/before/Foo.kt b/idea/testData/refactoring/rename/renameKotlinFile/before/Foo.kt
new file mode 100644
index 00000000000..664d7964f2a
--- /dev/null
+++ b/idea/testData/refactoring/rename/renameKotlinFile/before/Foo.kt
@@ -0,0 +1,3 @@
+package testing.rename
+
+var foo: String = "xyzzy"
diff --git a/idea/testData/refactoring/rename/renameKotlinFile/before/testing/JavaClient.java b/idea/testData/refactoring/rename/renameKotlinFile/before/testing/JavaClient.java
new file mode 100644
index 00000000000..cc3036c80d1
--- /dev/null
+++ b/idea/testData/refactoring/rename/renameKotlinFile/before/testing/JavaClient.java
@@ -0,0 +1,10 @@
+package testing;
+
+import testing.rename.FooKt;
+
+class JavaClient {
+ public void foo() {
+ String old = FooKt.getFoo();
+ FooKt.setFoo(old + "new");
+ }
+}
\ No newline at end of file
diff --git a/idea/testData/refactoring/rename/renameKotlinFile/renameFile.test b/idea/testData/refactoring/rename/renameKotlinFile/renameFile.test
new file mode 100644
index 00000000000..60a22ba0043
--- /dev/null
+++ b/idea/testData/refactoring/rename/renameKotlinFile/renameFile.test
@@ -0,0 +1,5 @@
+{
+ "type": "FILE",
+ "file": "Foo.kt",
+ "newName": "Bar.kt"
+}
\ No newline at end of file
diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt
index 88ff97f3f2f..dba97327e1c 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt
+++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt
@@ -65,7 +65,8 @@ private enum class RenameType {
KOTLIN_FUNCTION,
KOTLIN_PROPERTY,
KOTLIN_PACKAGE,
- MARKED_ELEMENT
+ MARKED_ELEMENT,
+ FILE
}
public abstract class AbstractRenameTest : KotlinMultiFileTestCase() {
@@ -100,6 +101,7 @@ public abstract class AbstractRenameTest : KotlinMultiFileTestCase() {
RenameType.KOTLIN_PROPERTY -> renameKotlinPropertyTest(renameObject, context)
RenameType.KOTLIN_PACKAGE -> renameKotlinPackageTest(renameObject, context)
RenameType.MARKED_ELEMENT -> renameMarkedElement(renameObject, context)
+ RenameType.FILE -> renameFile(renameObject, context)
}
if (hintDirective != null) {
@@ -230,6 +232,18 @@ public abstract class AbstractRenameTest : KotlinMultiFileTestCase() {
}
}
+ private fun renameFile(renameParamsObject: JsonObject, context: TestContext) {
+ val file = renameParamsObject.getString("file")
+ val newName = renameParamsObject.getString("newName")
+
+ doTestCommittingDocuments { rootDir, rootAfter ->
+ val mainFile = rootDir.findChild(file)!!
+ val psiFile = PsiManager.getInstance(context.project).findFile(mainFile)
+
+ runRenameProcessor(context, newName, psiFile, true, true)
+ }
+ }
+
private fun doRenameInKotlinClassOrPackage(
renameParamsObject: JsonObject, context: TestContext, findDescriptorToRename: (JetScope) -> DeclarationDescriptor
) {
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 4b766fe16b9..59a697fd064 100644
--- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java
+++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java
@@ -269,6 +269,12 @@ public class RenameTestGenerated extends AbstractRenameTest {
doTest(fileName);
}
+ @TestMetadata("renameKotlinFile/renameFile.test")
+ public void testRenameKotlinFile_RenameFile() throws Exception {
+ String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinFile/renameFile.test");
+ doTest(fileName);
+ }
+
@TestMetadata("renameKotlinFunctionInEnum/renameKotlinFunctionInEnum.test")
public void testRenameKotlinFunctionInEnum_RenameKotlinFunctionInEnum() throws Exception {
String fileName = JetTestUtils.navigationMetadata("idea/testData/refactoring/rename/renameKotlinFunctionInEnum/renameKotlinFunctionInEnum.test");