diff --git a/ChangeLog.md b/ChangeLog.md index c437bd5472a..8765fc451bc 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -194,6 +194,7 @@ These artifacts include extensions for the types available in the latter JDKs, s - [`KT-13474`](https://youtrack.jetbrains.com/issue/KT-13474) Fix performance of typing super call lambda - Show "Variables and values captured in a closure" highlighting only for usages - [`KT-13838`](https://youtrack.jetbrains.com/issue/KT-13838) Add file name to the presentation of private top-level declaration (Go to symbol, etc.) +- [`KT-14096`](https://youtrack.jetbrains.com/issue/KT-14096) Rename: When renaming Kotlin file outside of source root do not rename its namesake in a source root #### Intention actions, inspections and quickfixes diff --git a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinMultiFileTestCase.kt b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinMultiFileTestCase.kt index a6f3c635156..71c4b85c7a3 100644 --- a/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinMultiFileTestCase.kt +++ b/idea/idea-test-framework/src/org/jetbrains/kotlin/idea/test/KotlinMultiFileTestCase.kt @@ -16,16 +16,46 @@ package org.jetbrains.kotlin.idea.test +import com.intellij.ide.highlighter.ModuleFileType +import com.intellij.openapi.module.StdModuleTypes +import com.intellij.openapi.vfs.VfsUtilCore +import com.intellij.openapi.vfs.VirtualFile +import com.intellij.openapi.vfs.VirtualFileVisitor import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess import com.intellij.refactoring.MultiFileTestCase +import com.intellij.testFramework.PsiTestUtil import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File abstract class KotlinMultiFileTestCase : MultiFileTestCase() { + protected var isMultiModule = false + override fun setUp() { super.setUp() VfsRootAccess.allowRootAccess(KotlinTestUtils.getHomeDirectory()) } + override fun prepareProject(rootDir: VirtualFile) { + if (isMultiModule) { + VfsUtilCore.visitChildrenRecursively( + rootDir, + object : VirtualFileVisitor() { + override fun visitFile(file: VirtualFile): Boolean { + if (!file.isDirectory && file.name.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) { + createModule(File(file.path), StdModuleTypes.JAVA) + return false + } + + return true + } + } + ) + } + else { + PsiTestUtil.addSourceContentToRoots(myModule, rootDir) + } + } + override fun tearDown() { VfsRootAccess.disallowRootAccess(KotlinTestUtils.getHomeDirectory()) super.tearDown() diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt index 92c5a59d1a8..789e5ae4143 100644 --- a/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/rename/RenameKotlinFileProcessor.kt @@ -17,18 +17,20 @@ package org.jetbrains.kotlin.idea.refactoring.rename import com.intellij.openapi.fileTypes.FileTypeManager +import com.intellij.openapi.module.ModuleUtilCore import com.intellij.psi.JavaPsiFacade import com.intellij.psi.PsiElement +import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.search.SearchScope import com.intellij.refactoring.rename.RenamePsiFileProcessor import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.idea.KotlinFileType -import org.jetbrains.kotlin.idea.search.allScope +import org.jetbrains.kotlin.idea.util.ProjectRootsUtil import org.jetbrains.kotlin.load.kotlin.PackagePartClassUtils import org.jetbrains.kotlin.psi.KtFile class RenameKotlinFileProcessor() : RenamePsiFileProcessor() { - override fun canProcessElement(element: PsiElement) = element is KtFile + override fun canProcessElement(element: PsiElement) = element is KtFile && ProjectRootsUtil.isInProjectSource(element) override fun prepareRenaming(element: PsiElement?, newName: String, @@ -39,11 +41,13 @@ class RenameKotlinFileProcessor() : RenamePsiFileProcessor() { return } + val module = ModuleUtilCore.findModuleForPsiElement(element) ?: return + val fileInfo = JvmFileClassUtil.getFileClassInfoNoResolve(jetFile) if (!fileInfo.withJvmName) { val facadeFqName = fileInfo.facadeClassFqName val project = jetFile.project - val facadeClass = JavaPsiFacade.getInstance(project).findClass(facadeFqName.asString(), project.allScope()) + val facadeClass = JavaPsiFacade.getInstance(project).findClass(facadeFqName.asString(), GlobalSearchScope.moduleScope(module)) if (facadeClass != null) { allRenames[facadeClass] = PackagePartClassUtils.getFilePartShortName(newName) } diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml new file mode 100644 index 00000000000..c90834f2d60 --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/A.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt new file mode 100644 index 00000000000..8272349b10a --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/notSrc/test2.kt @@ -0,0 +1,3 @@ +package foo + +fun test() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt new file mode 100644 index 00000000000..8272349b10a --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/after/A/src/foo/test.kt @@ -0,0 +1,3 @@ +package foo + +fun test() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml new file mode 100644 index 00000000000..c90834f2d60 --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/A.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt new file mode 100644 index 00000000000..8272349b10a --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/notSrc/test.kt @@ -0,0 +1,3 @@ +package foo + +fun test() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt new file mode 100644 index 00000000000..8272349b10a --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/before/A/src/foo/test.kt @@ -0,0 +1,3 @@ +package foo + +fun test() \ No newline at end of file diff --git a/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test new file mode 100644 index 00000000000..b3ad0b6b224 --- /dev/null +++ b/idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test @@ -0,0 +1,6 @@ +{ + "type": "FILE", + "file": "A/notSrc/test.kt", + "newName": "test2.kt", + "isMultiModule": "true" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt index 9900b2f1b34..5ea39264828 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/AbstractMoveTest.kt @@ -19,15 +19,11 @@ package org.jetbrains.kotlin.idea.refactoring.move import com.google.gson.JsonObject import com.google.gson.JsonParser import com.intellij.codeInsight.TargetElementUtilBase -import com.intellij.ide.highlighter.ModuleFileType import com.intellij.openapi.editor.EditorFactory import com.intellij.openapi.fileEditor.FileDocumentManager -import com.intellij.openapi.module.StdModuleTypes import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.vfs.VfsUtil -import com.intellij.openapi.vfs.VfsUtilCore import com.intellij.openapi.vfs.VirtualFile -import com.intellij.openapi.vfs.VirtualFileVisitor import com.intellij.psi.* import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException import com.intellij.refactoring.PackageWrapper @@ -40,7 +36,6 @@ import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectori import com.intellij.refactoring.move.moveInner.MoveInnerProcessor import com.intellij.refactoring.move.moveMembers.MockMoveMembersOptions import com.intellij.refactoring.move.moveMembers.MoveMembersProcessor -import com.intellij.testFramework.PsiTestUtil import com.intellij.util.ActionRunner import org.jetbrains.kotlin.idea.jsonUtils.getNullableString import org.jetbrains.kotlin.idea.jsonUtils.getString @@ -64,8 +59,6 @@ import org.jetbrains.kotlin.test.KotlinTestUtils import java.io.File abstract class AbstractMoveTest : KotlinMultiFileTestCase() { - private var isMultiModule = false - protected fun doTest(path: String) { val config = JsonParser().parse(FileUtil.loadFile(File(path), true)) as JsonObject @@ -120,27 +113,6 @@ abstract class AbstractMoveTest : KotlinMultiFileTestCase() { getTestDirName(true)) } - override fun prepareProject(rootDir: VirtualFile) { - if (isMultiModule) { - VfsUtilCore.visitChildrenRecursively( - rootDir, - object : VirtualFileVisitor() { - override fun visitFile(file: VirtualFile): Boolean { - if (!file.isDirectory && file.name.endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) { - createModule(File(file.path), StdModuleTypes.JAVA) - return false - } - - return true - } - } - ) - } - else { - PsiTestUtil.addSourceContentToRoots(myModule, rootDir) - } - } - protected fun getTestDirName(lowercaseFirstLetter : Boolean) : String { val testName = getTestName(lowercaseFirstLetter) return testName.substring(0, testName.lastIndexOf('_')).replace('_', '/') 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 51df7906fee..1258f912567 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/AbstractRenameTest.kt @@ -100,6 +100,8 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { ConfigLibraryUtil.configureKotlinRuntimeAndSdk(myModule, PluginTestCaseBase.mockJdk()) } + isMultiModule = renameObject["isMultiModule"]?.asBoolean ?: false + val libraryInfos = renameObject.getAsJsonArray("libraries")?.map { it.asString!! } ?: emptyList() ConfigLibraryUtil.configureLibraries(myModule, PlatformTestUtil.getCommunityPath(), libraryInfos) @@ -281,7 +283,7 @@ abstract class AbstractRenameTest : KotlinMultiFileTestCase() { val newName = renameParamsObject.getString("newName") doTestCommittingDocuments { rootDir, rootAfter -> - val mainFile = rootDir.findChild(file)!! + val mainFile = rootDir.findFileByRelativePath(file)!! val psiFile = PsiManager.getInstance(context.project).findFile(mainFile) runRenameProcessor(context, newName, psiFile, renameParamsObject, true, true) 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 6a5e1f3fc76..c3dc56515fd 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("fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test") + public void testFileNotUnderSourceRootWithNamesakeUnderSourceRoot_FileNotUnderSourceRootWithNamesakeUnderSourceRoot() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/fileNotUnderSourceRootWithNamesakeUnderSourceRoot/fileNotUnderSourceRootWithNamesakeUnderSourceRoot.test"); + doTest(fileName); + } + @TestMetadata("lambdaParameterRedeclaration/lambdaParameterRedeclaration.test") public void testLambdaParameterRedeclaration_LambdaParameterRedeclaration() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("idea/testData/refactoring/rename/lambdaParameterRedeclaration/lambdaParameterRedeclaration.test");