From b0d82bef7d2e042c717d615ad3ad15c6f1502ade Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 19 Feb 2015 18:47:46 +0300 Subject: [PATCH 1/4] Tested KT-2718 Package names that match Kotlin keywords should be escaped properly --- idea/testData/addImport/KeywordNames.dependency.kt | 3 +++ idea/testData/addImport/KeywordNames.kt | 3 +++ idea/testData/addImport/KeywordNames.kt.after | 5 +++++ .../editor/optimizeImports/KeywordNames.dependency.kt | 3 +++ idea/testData/editor/optimizeImports/KeywordNames.kt | 3 +++ idea/testData/editor/optimizeImports/KeywordNames.kt.after | 3 +++ .../jetbrains/kotlin/addImport/AddImportTestGenerated.java | 6 ++++++ .../kotlin/idea/imports/OptimizeImportsTestGenerated.java | 6 ++++++ 8 files changed, 32 insertions(+) create mode 100644 idea/testData/addImport/KeywordNames.dependency.kt create mode 100644 idea/testData/addImport/KeywordNames.kt create mode 100644 idea/testData/addImport/KeywordNames.kt.after create mode 100644 idea/testData/editor/optimizeImports/KeywordNames.dependency.kt create mode 100644 idea/testData/editor/optimizeImports/KeywordNames.kt create mode 100644 idea/testData/editor/optimizeImports/KeywordNames.kt.after diff --git a/idea/testData/addImport/KeywordNames.dependency.kt b/idea/testData/addImport/KeywordNames.dependency.kt new file mode 100644 index 00000000000..7c6afc30d4e --- /dev/null +++ b/idea/testData/addImport/KeywordNames.dependency.kt @@ -0,0 +1,3 @@ +package foo.`val` + +class `var` \ No newline at end of file diff --git a/idea/testData/addImport/KeywordNames.kt b/idea/testData/addImport/KeywordNames.kt new file mode 100644 index 00000000000..fccd0666d19 --- /dev/null +++ b/idea/testData/addImport/KeywordNames.kt @@ -0,0 +1,3 @@ +// IMPORT: class: foo.val.var +// NAME_COUNT_TO_USE_STAR_IMPORT: 10 +package p diff --git a/idea/testData/addImport/KeywordNames.kt.after b/idea/testData/addImport/KeywordNames.kt.after new file mode 100644 index 00000000000..a8441ccee94 --- /dev/null +++ b/idea/testData/addImport/KeywordNames.kt.after @@ -0,0 +1,5 @@ +// IMPORT: class: foo.val.var +// NAME_COUNT_TO_USE_STAR_IMPORT: 10 +package p + +import foo.`val`.`var` diff --git a/idea/testData/editor/optimizeImports/KeywordNames.dependency.kt b/idea/testData/editor/optimizeImports/KeywordNames.dependency.kt new file mode 100644 index 00000000000..7c6afc30d4e --- /dev/null +++ b/idea/testData/editor/optimizeImports/KeywordNames.dependency.kt @@ -0,0 +1,3 @@ +package foo.`val` + +class `var` \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/KeywordNames.kt b/idea/testData/editor/optimizeImports/KeywordNames.kt new file mode 100644 index 00000000000..0dbb26e6b90 --- /dev/null +++ b/idea/testData/editor/optimizeImports/KeywordNames.kt @@ -0,0 +1,3 @@ +import foo.`val`.* + +var v: `var`? = null \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/KeywordNames.kt.after b/idea/testData/editor/optimizeImports/KeywordNames.kt.after new file mode 100644 index 00000000000..0d76a16fb13 --- /dev/null +++ b/idea/testData/editor/optimizeImports/KeywordNames.kt.after @@ -0,0 +1,3 @@ +import foo.`val`.`var` + +var v: `var`? = null \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java b/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java index 3c6e85d619f..dc3dc3b35ff 100644 --- a/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/addImport/AddImportTestGenerated.java @@ -186,6 +186,12 @@ public class AddImportTestGenerated extends AbstractAddImportTest { doTest(fileName); } + @TestMetadata("KeywordNames.kt") + public void testKeywordNames() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/KeywordNames.kt"); + doTest(fileName); + } + @TestMetadata("NameCountForStarNotReached.kt") public void testNameCountForStarNotReached() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/addImport/NameCountForStarNotReached.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java index 8945a048f70..0477fb4ef5b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java @@ -111,6 +111,12 @@ public class OptimizeImportsTestGenerated extends AbstractOptimizeImportsTest { doTest(fileName); } + @TestMetadata("KeywordNames.kt") + public void testKeywordNames() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/KeywordNames.kt"); + doTest(fileName); + } + @TestMetadata("KotlinPackage.kt") public void testKotlinPackage() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/KotlinPackage.kt"); From 862d391da67d29ed0b5f578decf279eeffee3534 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Thu, 19 Feb 2015 19:40:11 +0300 Subject: [PATCH 2/4] KT-6834 Optimize Imports: do not modify file if import list had not change #KT-6834 Fixed --- .../jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt | 3 ++- .../editor/optimizeImports/DoNotTouchIfNoChanges.kt | 5 +++++ .../editor/optimizeImports/DoNotTouchIfNoChanges.kt.after | 5 +++++ .../kotlin/idea/imports/OptimizeImportsTestGenerated.java | 6 ++++++ 4 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt create mode 100644 idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt index 1d80ee33be1..1b06c1f2fe8 100644 --- a/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/imports/KotlinImportOptimizer.kt @@ -151,7 +151,8 @@ public class KotlinImportOptimizer() : ImportOptimizer { val sortedImportsToGenerate = importsToGenerate.sortBy(importInsertHelper.importSortComparator) - //TODO: do not touch file if everything is already correct? + // check if no changes to imports required + if (oldImports.size() == sortedImportsToGenerate.size() && oldImports.map { it.getImportPath() } == sortedImportsToGenerate) return ApplicationManager.getApplication()!!.runWriteAction(Runnable { val importList = file.getImportList()!! diff --git a/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt b/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt new file mode 100644 index 00000000000..3e616668460 --- /dev/null +++ b/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt @@ -0,0 +1,5 @@ +import java.util.ArrayList +// some comment +import java.util.HashSet + +val v: HashSet> \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt.after b/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt.after new file mode 100644 index 00000000000..3e616668460 --- /dev/null +++ b/idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt.after @@ -0,0 +1,5 @@ +import java.util.ArrayList +// some comment +import java.util.HashSet + +val v: HashSet> \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java index 0477fb4ef5b..d95a798d519 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/imports/OptimizeImportsTestGenerated.java @@ -81,6 +81,12 @@ public class OptimizeImportsTestGenerated extends AbstractOptimizeImportsTest { doTest(fileName); } + @TestMetadata("DoNotTouchIfNoChanges.kt") + public void testDoNotTouchIfNoChanges() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/DoNotTouchIfNoChanges.kt"); + doTest(fileName); + } + @TestMetadata("DuplicatedImports.kt") public void testDuplicatedImports() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/editor/optimizeImports/DuplicatedImports.kt"); From 5b4afa140bf8293d57ef63e92a39f5b66d299b96 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Mon, 2 Mar 2015 21:04:39 +0300 Subject: [PATCH 3/4] Fixed bug in reference shortening related on on the fly import optimization --- .../src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt | 5 ++++- idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt | 5 +++++ .../shortenRefs/imports/ImportsOnTheFlyBug.kt.after | 5 +++++ .../kotlin/shortenRefs/ShortenRefsTestGenerated.java | 6 ++++++ 4 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt create mode 100644 idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt.after diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt index b57a68b9710..a2a63d9168a 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/util/ShortenReferences.kt @@ -159,6 +159,10 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. for (descriptor in descriptorsToImport) { assert(descriptor !in failedToImportDescriptors) + if (importInserter.optimizeImports()) { + anyChange = true + } + val result = importInserter.addImport(descriptor) if (result != ImportInsertHelper.ImportDescriptorResult.ALREADY_IMPORTED) { anyChange = true @@ -456,7 +460,6 @@ public class ShortenReferences(val options: (JetElement) -> Options = { Options. private val helper = ImportInsertHelper.getInstance(file.getProject()) fun addImport(target: DeclarationDescriptor): ImportInsertHelper.ImportDescriptorResult { - optimizeImports() return helper.importDescriptor(file, target) } diff --git a/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt b/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt new file mode 100644 index 00000000000..49111aeb08d --- /dev/null +++ b/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt @@ -0,0 +1,5 @@ +// OPTIMIZE_IMPORTS: true +// NAME_COUNT_TO_USE_STAR_IMPORT: 1 +import java.util.HashMap + +val v: HashMapjava.util.Date> \ No newline at end of file diff --git a/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt.after b/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt.after new file mode 100644 index 00000000000..1c598ceb80f --- /dev/null +++ b/idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt.after @@ -0,0 +1,5 @@ +// OPTIMIZE_IMPORTS: true +// NAME_COUNT_TO_USE_STAR_IMPORT: 1 +import java.util.* + +val v: HashMap \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java b/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java index 3abd873ad37..992432ca371 100644 --- a/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/shortenRefs/ShortenRefsTestGenerated.java @@ -186,6 +186,12 @@ public class ShortenRefsTestGenerated extends AbstractShortenRefsTest { doTest(fileName); } + @TestMetadata("ImportsOnTheFlyBug.kt") + public void testImportsOnTheFlyBug() throws Exception { + String fileName = JetTestUtils.navigationMetadata("idea/testData/shortenRefs/imports/ImportsOnTheFlyBug.kt"); + doTest(fileName); + } + @TestMetadata("leaveQualifiedConstructor.kt") public void testLeaveQualifiedConstructor() throws Exception { String fileName = JetTestUtils.navigationMetadata("idea/testData/shortenRefs/imports/leaveQualifiedConstructor.kt"); From 33bc234f45b0d48f1c95a89f6e488baa34998c83 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Tue, 3 Mar 2015 13:35:06 +0300 Subject: [PATCH 4/4] More clear code --- .../kotlin/idea/util/ImportInsertHelperImpl.kt | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt index 0574a497c8a..9820d694c9b 100644 --- a/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt +++ b/idea/src/org/jetbrains/kotlin/idea/util/ImportInsertHelperImpl.kt @@ -331,14 +331,14 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert } } - private fun detectNeededImports(importedDescriptors: Collection): Set { - if (importedDescriptors.isEmpty()) return setOf() + private fun detectNeededImports(importedClasses: Collection): Set { + if (importedClasses.isEmpty()) return setOf() - val descriptorsToCheck = importedDescriptors.map { it.getName() to it }.toMap().toLinkedMap() - val result = LinkedHashSet() + val classesToCheck = importedClasses.map { it.getName() to it }.toMap().toLinkedMap() + val result = LinkedHashSet() file.accept(object : JetVisitorVoid() { override fun visitElement(element: PsiElement) { - if (descriptorsToCheck.isEmpty()) return + if (classesToCheck.isEmpty()) return element.acceptChildren(this) } @@ -352,11 +352,11 @@ public class ImportInsertHelperImpl(private val project: Project) : ImportInsert if (JetPsiUtil.isSelectorInQualified(expression)) return val refName = expression.getReferencedNameAsName() - val descriptor = descriptorsToCheck[refName] + val descriptor = classesToCheck[refName] if (descriptor != null) { val targetFqName = targetFqName(expression) if (targetFqName != null && targetFqName == DescriptorUtils.getFqNameSafe(descriptor)) { - descriptorsToCheck.remove(refName) + classesToCheck.remove(refName) result.add(descriptor) } }