From 3461effd4772bb29254c0304b777d64d43cd06d7 Mon Sep 17 00:00:00 2001 From: Roman Golyshev Date: Fri, 14 Feb 2020 11:48:14 +0300 Subject: [PATCH] KT-33372 Remove renaming file reference to the contents of the file - There is still a hack with returning null from `getLastFileReference`, it is here to keep KT-25674 issue fixed - Overrides of `bindToElement` are removed, they caused renames of the file references to their contents - Code of `KotlinFilePathReferenceContributor.kt` is refactored - ^KT-33372 ^KT-32514 ^KT-36306 Fixed --- .../testData/handlers/basic/KT36306.kt | 5 ++ .../testData/handlers/basic/KT36306.kt.after | 5 ++ .../BasicCompletionHandlerTestGenerated.java | 5 ++ ...ceBasicCompletionHandlerTestGenerated.java | 5 ++ .../KotlinFilePathReferenceContributor.kt | 59 +++++++++---------- .../after/a/a/.gitkeep | 0 .../after/b/.gitkeep | 0 .../after/b/main.kt | 2 + .../before/a/a/.gitkeep | 0 .../before/a/a/main.kt | 2 + .../before/b/.gitkeep | 0 .../moveFileWithDotsAsFileReferences.test | 5 ++ .../after/main.kt | 6 ++ .../after/new_resource.txt | 1 + .../before/main.kt | 6 ++ .../before/resource.txt | 1 + .../renameReferencedResourceFile.test | 5 ++ .../refactoring/move/MoveTestGenerated.java | 5 ++ .../rename/RenameTestGenerated.java | 5 ++ 19 files changed, 86 insertions(+), 31 deletions(-) create mode 100644 idea/idea-completion/testData/handlers/basic/KT36306.kt create mode 100644 idea/idea-completion/testData/handlers/basic/KT36306.kt.after create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/a/a/.gitkeep create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/.gitkeep create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/.gitkeep create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/main.kt create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/b/.gitkeep create mode 100644 idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test create mode 100644 idea/testData/refactoring/rename/renameReferencedResourceFile/after/main.kt create mode 100644 idea/testData/refactoring/rename/renameReferencedResourceFile/after/new_resource.txt create mode 100644 idea/testData/refactoring/rename/renameReferencedResourceFile/before/main.kt create mode 100644 idea/testData/refactoring/rename/renameReferencedResourceFile/before/resource.txt create mode 100644 idea/testData/refactoring/rename/renameReferencedResourceFile/renameReferencedResourceFile.test diff --git a/idea/idea-completion/testData/handlers/basic/KT36306.kt b/idea/idea-completion/testData/handlers/basic/KT36306.kt new file mode 100644 index 00000000000..1eb6ea1703d --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/KT36306.kt @@ -0,0 +1,5 @@ +//INVOCATION_COUNT: 2 +fun main() { + "Integ" +} +//ELEMENT: Integer \ No newline at end of file diff --git a/idea/idea-completion/testData/handlers/basic/KT36306.kt.after b/idea/idea-completion/testData/handlers/basic/KT36306.kt.after new file mode 100644 index 00000000000..aba37ac4283 --- /dev/null +++ b/idea/idea-completion/testData/handlers/basic/KT36306.kt.after @@ -0,0 +1,5 @@ +//INVOCATION_COUNT: 2 +fun main() { + "java.lang.Integer" +} +//ELEMENT: Integer \ No newline at end of file diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java index 8eda240ed4e..f9f3359c784 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/handlers/BasicCompletionHandlerTestGenerated.java @@ -143,6 +143,11 @@ public class BasicCompletionHandlerTestGenerated extends AbstractBasicCompletion runTest("idea/idea-completion/testData/handlers/basic/KT23627.kt"); } + @TestMetadata("KT36306.kt") + public void testKT36306() throws Exception { + runTest("idea/idea-completion/testData/handlers/basic/KT36306.kt"); + } + @TestMetadata("NestedTypeArg.kt") public void testNestedTypeArg() throws Exception { runTest("idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt"); diff --git a/idea/performanceTests/test/org/jetbrains/kotlin/idea/perf/PerformanceBasicCompletionHandlerTestGenerated.java b/idea/performanceTests/test/org/jetbrains/kotlin/idea/perf/PerformanceBasicCompletionHandlerTestGenerated.java index adaf332f7ad..cff818af6b6 100644 --- a/idea/performanceTests/test/org/jetbrains/kotlin/idea/perf/PerformanceBasicCompletionHandlerTestGenerated.java +++ b/idea/performanceTests/test/org/jetbrains/kotlin/idea/perf/PerformanceBasicCompletionHandlerTestGenerated.java @@ -143,6 +143,11 @@ public class PerformanceBasicCompletionHandlerTestGenerated extends AbstractPerf runTest("idea/idea-completion/testData/handlers/basic/KT23627.kt"); } + @TestMetadata("KT36306.kt") + public void testKT36306() throws Exception { + runTest("idea/idea-completion/testData/handlers/basic/KT36306.kt"); + } + @TestMetadata("NestedTypeArg.kt") public void testNestedTypeArg() throws Exception { runTest("idea/idea-completion/testData/handlers/basic/NestedTypeArg.kt"); diff --git a/idea/src/org/jetbrains/kotlin/idea/references/KotlinFilePathReferenceContributor.kt b/idea/src/org/jetbrains/kotlin/idea/references/KotlinFilePathReferenceContributor.kt index 4385319d753..fd3afdcff57 100644 --- a/idea/src/org/jetbrains/kotlin/idea/references/KotlinFilePathReferenceContributor.kt +++ b/idea/src/org/jetbrains/kotlin/idea/references/KotlinFilePathReferenceContributor.kt @@ -37,43 +37,40 @@ class KotlinFilePathReferenceContributor : PsiReferenceContributor() { if (element !is KtStringTemplateExpression) return PsiReference.EMPTY_ARRAY if (!element.isPlain()) return PsiReference.EMPTY_ARRAY val refByElem = getReferencesByElement(element, element.plainContent, element.getContentRange().startOffset, true) - val res = refByElem - .map { - if (it is FileReference) { - object : FileReference(it.fileReferenceSet, it.rangeInElement, it.index, it.text) { - override fun getVariants(): Array { - return super.getVariants() - .map { - (it as? LookupElement)?.apply { - putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit) - } ?: it - } - .toTypedArray() - } - - // Note: this is a hack that prevents IDE from renaming paths in string literals when doing move. - // TODO: find another way of doing this (that may need re-implementing move files refactoring using .java move) - override fun getLastFileReference() = null - - override fun bindToElement(element: PsiElement): PsiElement { - return rename(element.text) - } - - override fun bindToElement(element: PsiElement, absolute: Boolean): PsiElement { - return rename(element.text) - } - } - } else it - } - .toTypedArray() - return res + return refByElem.map { if (it is FileReference) FixedFileReference(it) else it }.toTypedArray() } } override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) { registrar.registerReferenceProvider( PlatformPatterns.psiElement(KtStringTemplateExpression::class.java), - KotlinFilePathReferenceProvider + KotlinFilePathReferenceProvider, ) } } + +private class FixedFileReference(fileReference: FileReference) : FileReference(fileReference) { + override fun getVariants(): Array { + val variants = super.getVariants() + + variants.forEach { + if (it is LookupElement) { + it.putUserData(KotlinCompletionCharFilter.SUPPRESS_ITEM_SELECTION_BY_CHARS_ON_TYPING, Unit) + } + } + + return variants + } + + /** + * We have a bug that turns file references in code like `"."` and `".."` into `""` during file move because .kt files + * are moved by [org.jetbrains.kotlin.idea.refactoring.move.moveDeclarations.KotlinAwareMoveFilesOrDirectoriesProcessor], + * which is an extender of [com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor]. It uses + * this method to obtain the referenced file, and if it's null, it will not try to replace the reference to it. + * + * However, this is a hack, because there are probably some usages where this reference should not be null. + * + * TODO Try to resolve this issue again when IDEA-232942 is resolved (maybe this won't be an issue anymore) + */ + override fun getLastFileReference(): FileReference? = null +} diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/a/a/.gitkeep b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/a/a/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/.gitkeep b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/main.kt b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/main.kt new file mode 100644 index 00000000000..fc66a7d1e8d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/after/b/main.kt @@ -0,0 +1,2 @@ +val a = "." +val b = ".." diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/.gitkeep b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/main.kt b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/main.kt new file mode 100644 index 00000000000..fc66a7d1e8d --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/a/a/main.kt @@ -0,0 +1,2 @@ +val a = "." +val b = ".." diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/b/.gitkeep b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/before/b/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test new file mode 100644 index 00000000000..41a1fac7743 --- /dev/null +++ b/idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test @@ -0,0 +1,5 @@ +{ + "mainFile": "a/a/main.kt", + "type": "MOVE_FILES", + "targetDirectory": "b" +} diff --git a/idea/testData/refactoring/rename/renameReferencedResourceFile/after/main.kt b/idea/testData/refactoring/rename/renameReferencedResourceFile/after/main.kt new file mode 100644 index 00000000000..969850e8cac --- /dev/null +++ b/idea/testData/refactoring/rename/renameReferencedResourceFile/after/main.kt @@ -0,0 +1,6 @@ +fun take(a: String) {} + +fun usage() { + take("new_resource.txt") + take("new_resource.txt") +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameReferencedResourceFile/after/new_resource.txt b/idea/testData/refactoring/rename/renameReferencedResourceFile/after/new_resource.txt new file mode 100644 index 00000000000..3cb0fa2af2d --- /dev/null +++ b/idea/testData/refactoring/rename/renameReferencedResourceFile/after/new_resource.txt @@ -0,0 +1 @@ +resource content \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameReferencedResourceFile/before/main.kt b/idea/testData/refactoring/rename/renameReferencedResourceFile/before/main.kt new file mode 100644 index 00000000000..89676c6fe25 --- /dev/null +++ b/idea/testData/refactoring/rename/renameReferencedResourceFile/before/main.kt @@ -0,0 +1,6 @@ +fun take(a: String) {} + +fun usage() { + take("resource.txt") + take("./resource.txt") +} \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameReferencedResourceFile/before/resource.txt b/idea/testData/refactoring/rename/renameReferencedResourceFile/before/resource.txt new file mode 100644 index 00000000000..3cb0fa2af2d --- /dev/null +++ b/idea/testData/refactoring/rename/renameReferencedResourceFile/before/resource.txt @@ -0,0 +1 @@ +resource content \ No newline at end of file diff --git a/idea/testData/refactoring/rename/renameReferencedResourceFile/renameReferencedResourceFile.test b/idea/testData/refactoring/rename/renameReferencedResourceFile/renameReferencedResourceFile.test new file mode 100644 index 00000000000..bd2bd35c2f3 --- /dev/null +++ b/idea/testData/refactoring/rename/renameReferencedResourceFile/renameReferencedResourceFile.test @@ -0,0 +1,5 @@ +{ + "type": "FILE", + "file": "resource.txt", + "newName": "new_resource.txt" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java index ee43e7a322a..df5a49ad3d3 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/move/MoveTestGenerated.java @@ -263,6 +263,11 @@ public class MoveTestGenerated extends AbstractMoveTest { runTest("idea/testData/refactoring/move/kotlin/moveFile/moveFileToFile/moveFileToFile.test"); } + @TestMetadata("kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test") + public void testKotlin_moveFile_moveFileWithDotsAsFileReferences_MoveFileWithDotsAsFileReferences() throws Exception { + runTest("idea/testData/refactoring/move/kotlin/moveFile/moveFileWithDotsAsFileReferences/moveFileWithDotsAsFileReferences.test"); + } + @TestMetadata("kotlin/moveFile/moveFileWithoutDeclarations/moveFileWithoutDeclarations.test") public void testKotlin_moveFile_moveFileWithoutDeclarations_MoveFileWithoutDeclarations() throws Exception { runTest("idea/testData/refactoring/move/kotlin/moveFile/moveFileWithoutDeclarations/moveFileWithoutDeclarations.test"); 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 03602a3f023..6015f17bdb7 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/refactoring/rename/RenameTestGenerated.java @@ -1148,6 +1148,11 @@ public class RenameTestGenerated extends AbstractRenameTest { runTest("idea/testData/refactoring/rename/renamePropertyInEnumCompanionWithEntryConflict/renameKotlinPropertyInEnumCompanionWithEntryConflict.test"); } + @TestMetadata("renameReferencedResourceFile/renameReferencedResourceFile.test") + public void testRenameReferencedResourceFile_RenameReferencedResourceFile() throws Exception { + runTest("idea/testData/refactoring/rename/renameReferencedResourceFile/renameReferencedResourceFile.test"); + } + @TestMetadata("renameSet/set.test") public void testRenameSet_Set() throws Exception { runTest("idea/testData/refactoring/rename/renameSet/set.test");