From 33c73dba2e08c92aafe7c7c6169a34358b70e192 Mon Sep 17 00:00:00 2001 From: Andy Hanson Date: Tue, 20 Mar 2018 15:24:37 -0700 Subject: [PATCH] organizeImports: Preserve comments of deleted ImportDeclarations --- src/harness/unittests/organizeImports.ts | 1 + src/services/organizeImports.ts | 19 ++++++++++++++----- .../reference/organizeImports/Unused_Some.ts | 2 ++ 3 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/harness/unittests/organizeImports.ts b/src/harness/unittests/organizeImports.ts index de4a4722d67dc..73ead441562ef 100644 --- a/src/harness/unittests/organizeImports.ts +++ b/src/harness/unittests/organizeImports.ts @@ -217,6 +217,7 @@ F2(); { path: "/test.ts", content: ` +/** Comment */ import { F1, F2 } from "lib"; import * as NS from "lib"; import D from "lib"; diff --git a/src/services/organizeImports.ts b/src/services/organizeImports.ts index f6489fce6d208..81f8049bc50e9 100644 --- a/src/services/organizeImports.ts +++ b/src/services/organizeImports.ts @@ -34,21 +34,23 @@ namespace ts.OrganizeImports { return; } + const deletedImportDeclarations = createMap(); + const oldImportGroups = group(oldImportDecls, importDecl => getExternalModuleName(importDecl.moduleSpecifier)); const sortedImportGroups = stableSort(oldImportGroups, (group1, group2) => compareModuleSpecifiers(group1[0].moduleSpecifier, group2[0].moduleSpecifier)); const newImportDecls = flatMap(sortedImportGroups, importGroup => getExternalModuleName(importGroup[0].moduleSpecifier) - ? coalesceImports(removeUnusedImports(importGroup, sourceFile, program)) + ? coalesceImports(removeUnusedImports(importGroup, sourceFile, program, deletedImportDeclarations)) : importGroup); // Delete or replace the first import. if (newImportDecls.length === 0) { - changeTracker.deleteNode(sourceFile, oldImportDecls[0]); + removeOldImport(newImportDecls[0]); } else { // Note: Delete the surrounding trivia because it will have been retained in newImportDecls. changeTracker.replaceNodeWithNodes(sourceFile, oldImportDecls[0], newImportDecls, { - useNonAdjustedStartPosition: false, + useNonAdjustedStartPosition: deletedImportDeclarations.has(String(getNodeId(oldImportDecls[0]))), useNonAdjustedEndPosition: false, suffix: getNewLineOrDefaultFromHost(host, formatContext.options), }); @@ -56,7 +58,11 @@ namespace ts.OrganizeImports { // Delete any subsequent imports. for (let i = 1; i < oldImportDecls.length; i++) { - changeTracker.deleteNode(sourceFile, oldImportDecls[i]); + removeOldImport(oldImportDecls[i]); + } + + function removeOldImport(oldImport: ImportDeclaration): void { + changeTracker.deleteNode(sourceFile, oldImport, { useNonAdjustedStartPosition: deletedImportDeclarations.has(String(getNodeId(oldImport))) }); } } } @@ -66,7 +72,7 @@ namespace ts.OrganizeImports { return body && !isIdentifier(body) && (isModuleBlock(body) ? body : getModuleBlock(body)); } - function removeUnusedImports(oldImports: ReadonlyArray, sourceFile: SourceFile, program: Program) { + function removeUnusedImports(oldImports: ReadonlyArray, sourceFile: SourceFile, program: Program, deletedImportDeclarations: Map) { const typeChecker = program.getTypeChecker(); const jsxNamespace = typeChecker.getJsxNamespace(); const jsxContext = sourceFile.languageVariant === LanguageVariant.JSX && program.getCompilerOptions().jsx; @@ -110,6 +116,9 @@ namespace ts.OrganizeImports { if (name || namedBindings) { usedImports.push(updateImportDeclarationAndClause(importDecl, name, namedBindings)); } + else { + deletedImportDeclarations.set(String(getNodeId(importDecl)), true); + } } return usedImports; diff --git a/tests/baselines/reference/organizeImports/Unused_Some.ts b/tests/baselines/reference/organizeImports/Unused_Some.ts index 2f0aaa6d49991..9347d722add2d 100644 --- a/tests/baselines/reference/organizeImports/Unused_Some.ts +++ b/tests/baselines/reference/organizeImports/Unused_Some.ts @@ -1,5 +1,6 @@ // ==ORIGINAL== +/** Comment */ import { F1, F2 } from "lib"; import * as NS from "lib"; import D from "lib"; @@ -8,6 +9,7 @@ D(); // ==ORGANIZED== +/** Comment */ import D from "lib"; D();