diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index 023a34c05663f..131cb029c6537 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -384,8 +384,8 @@ namespace ts.textChanges { } } - public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false): void { - this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, {}), newNode, this.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)); + public insertNodeBefore(sourceFile: SourceFile, before: Node, newNode: Node, blankLineBetween = false, options: ConfigurableStartEnd = {}): void { + this.insertNodeAt(sourceFile, getAdjustedStartPosition(sourceFile, before, options), newNode, this.getOptionsForInsertNodeBefore(before, newNode, blankLineBetween)); } public insertModifierBefore(sourceFile: SourceFile, modifier: SyntaxKind, before: Node): void { diff --git a/src/services/utilities.ts b/src/services/utilities.ts index baa70bf1df84f..1daf9a1305a6f 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -1913,7 +1913,10 @@ namespace ts { for (const newImport of sortedNewImports) { const insertionIndex = OrganizeImports.getImportDeclarationInsertionIndex(existingImportStatements, newImport); if (insertionIndex === 0) { - changes.insertNodeBefore(sourceFile, existingImportStatements[0], newImport, /*blankLineBetween*/ false); + // If the first import is top-of-file, insert after the leading comment which is likely the header. + const options = existingImportStatements[0] === sourceFile.statements[0] ? + { leadingTriviaOption: textChanges.LeadingTriviaOption.Exclude } : {}; + changes.insertNodeBefore(sourceFile, existingImportStatements[0], newImport, /*blankLineBetween*/ false, options); } else { const prevImport = existingImportStatements[insertionIndex - 1]; diff --git a/tests/cases/fourslash/importNameCodeFix_HeaderComment1.ts b/tests/cases/fourslash/importNameCodeFix_HeaderComment1.ts new file mode 100644 index 0000000000000..d3263217b2faa --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_HeaderComment1.ts @@ -0,0 +1,26 @@ +/// + +// @Filename: /a.ts +////export const foo = 0; + +// @Filename: /b.ts +////export const bar = 0; + +// @Filename: /c.ts +/////*-------------------- +//// * Copyright Header +//// *--------------------*/ +//// +////import { bar } from "./b"; +////foo; + +goTo.file("/c.ts"); +verify.importFixAtPosition([ +`/*-------------------- + * Copyright Header + *--------------------*/ + +import { foo } from "./a"; +import { bar } from "./b"; +foo;`, +]); diff --git a/tests/cases/fourslash/importNameCodeFix_HeaderComment2.ts b/tests/cases/fourslash/importNameCodeFix_HeaderComment2.ts new file mode 100644 index 0000000000000..994d770ff24c5 --- /dev/null +++ b/tests/cases/fourslash/importNameCodeFix_HeaderComment2.ts @@ -0,0 +1,32 @@ +/// + +// @Filename: /a.ts +////export const foo = 0; + +// @Filename: /b.ts +////export const bar = 0; + +// @Filename: /c.ts +/////*-------------------- +//// * Copyright Header +//// *--------------------*/ +//// +////const afterHeader = 1; +//// +////// non-header comment +////import { bar } from "./b"; +////foo; + +goTo.file("/c.ts"); +verify.importFixAtPosition([ +`/*-------------------- + * Copyright Header + *--------------------*/ + +const afterHeader = 1; + +import { foo } from "./a"; +// non-header comment +import { bar } from "./b"; +foo;`, +]);