diff --git a/src/services/codefixes/importFixes.ts b/src/services/codefixes/importFixes.ts index 6775326100..86f64a79cf 100644 --- a/src/services/codefixes/importFixes.ts +++ b/src/services/codefixes/importFixes.ts @@ -194,7 +194,6 @@ namespace ts.codefix { function getCodeActionForNewImport(context: SymbolContext & { preferences: UserPreferences }, { moduleSpecifier, importKind }: NewImportInfo): CodeFixAction { const { sourceFile, symbolName, preferences } = context; - const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax); const moduleSpecifierWithoutQuotes = stripQuotes(moduleSpecifier); const quotedModuleSpecifier = makeStringLiteral(moduleSpecifierWithoutQuotes, getQuotePreference(sourceFile, preferences)); @@ -210,14 +209,7 @@ namespace ts.codefix { createIdentifier(symbolName), createExternalModuleReference(quotedModuleSpecifier)); - const changes = ChangeTracker.with(context, changeTracker => { - if (lastImportDeclaration) { - changeTracker.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl); - } - else { - changeTracker.insertNodeAtTopOfFile(sourceFile, importDecl, /*blankLineBetween*/ true); - } - }); + const changes = ChangeTracker.with(context, t => insertImport(t, sourceFile, importDecl)); // if this file doesn't have any import statements, insert an import statement and then insert a new line // between the only import statement and user code. Otherwise just insert the statement because chances diff --git a/src/services/refactors/moveToNewFile.ts b/src/services/refactors/moveToNewFile.ts index 0c6aaa61b6..f050e8fb17 100644 --- a/src/services/refactors/moveToNewFile.ts +++ b/src/services/refactors/moveToNewFile.ts @@ -121,7 +121,7 @@ namespace ts.refactor { const quotePreference = getQuotePreference(oldFile, preferences); const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference); if (importsFromNewFile) { - changes.insertNodeBefore(oldFile, oldFile.statements[0], importsFromNewFile, /*blankLineBetween*/ true); + insertImport(changes, oldFile, importsFromNewFile); } deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker); diff --git a/src/services/utilities.ts b/src/services/utilities.ts index 95c677ce28..9715d124d7 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1379,6 +1379,17 @@ namespace ts { return textSpanContainsPosition(span, node.getStart(file)) && node.getEnd() <= textSpanEnd(span); } + + /* @internal */ + export function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement): void { + const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax); + if (lastImportDeclaration) { + changes.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl); + } + else { + changes.insertNodeAtTopOfFile(sourceFile, importDecl, /*blankLineBetween*/ true); + } + } } // Display-part writer helpers diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 45e4a4b986..b2ec88acf7 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -10610,6 +10610,7 @@ declare namespace ts { some(pred: (node: Node) => boolean): boolean; } function getParentNodeInSpan(node: Node | undefined, file: SourceFile, span: TextSpan): Node | undefined; + function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement): void; } declare namespace ts { function isFirstDeclarationOfSymbolParameter(symbol: Symbol): boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3576a4e8f6..181f0d72d1 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -10790,6 +10790,7 @@ declare namespace ts { some(pred: (node: Node) => boolean): boolean; } function getParentNodeInSpan(node: Node | undefined, file: SourceFile, span: TextSpan): Node | undefined; + function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement): void; } declare namespace ts { function isFirstDeclarationOfSymbolParameter(symbol: Symbol): boolean; diff --git a/tests/cases/fourslash/moveToNewFile.ts b/tests/cases/fourslash/moveToNewFile.ts index 9175e37889..f07daa8e37 100644 --- a/tests/cases/fourslash/moveToNewFile.ts +++ b/tests/cases/fourslash/moveToNewFile.ts @@ -1,6 +1,8 @@ /// // @Filename: /a.ts +////// header comment +//// ////import './foo'; ////import { a, b, alreadyUnused } from './other'; ////const p = 0; @@ -10,10 +12,11 @@ verify.moveToNewFile({ newFileContents: { "/a.ts": -`import { y } from './y'; +`// header comment import './foo'; import { a, alreadyUnused } from './other'; +import { y } from './y'; export const p = 0; a; y;`, diff --git a/tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts b/tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts index 1e7b4347a8..a891e9b717 100644 --- a/tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts +++ b/tests/cases/fourslash/moveToNewFile_inferQuoteStyle.ts @@ -9,9 +9,8 @@ verify.moveToNewFile({ newFileContents: { "/a.ts": -`import { x } from './x'; - -import 'unrelated'; +`import 'unrelated'; +import { x } from './x'; x;`,