Skip to content

Commit bfff115

Browse files
authored
fix(35069): insert blank line after last new import (microsoft#36531)
1 parent 4c378c0 commit bfff115

File tree

5 files changed

+39
-9
lines changed

5 files changed

+39
-9
lines changed

src/services/codefixes/importFixes.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ namespace ts.codefix {
3232
// Keys are import clause node IDs.
3333
const addToExisting = createMap<{ readonly importClause: ImportClause, defaultImport: string | undefined; readonly namedImports: string[], canUseTypeOnlyImport: boolean }>();
3434
const newImports = createMap<Mutable<ImportsCollection>>();
35+
let lastModuleSpecifier: string | undefined;
3536

3637
eachDiagnostic(context, errorCodes, diag => {
3738
const info = getFixesInfo(context, diag.code, diag.start);
@@ -67,6 +68,7 @@ namespace ts.codefix {
6768
let entry = newImports.get(moduleSpecifier);
6869
if (!entry) {
6970
newImports.set(moduleSpecifier, entry = { defaultImport: undefined, namedImports: [], namespaceLikeImport: undefined });
71+
lastModuleSpecifier = moduleSpecifier;
7072
}
7173
switch (importKind) {
7274
case ImportKind.Default:
@@ -101,7 +103,7 @@ namespace ts.codefix {
101103
doAddExistingFix(changes, sourceFile, importClause, defaultImport, namedImports, canUseTypeOnlyImport);
102104
});
103105
newImports.forEach((imports, moduleSpecifier) => {
104-
addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, imports);
106+
addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, imports, /*blankLineBetween*/ lastModuleSpecifier === moduleSpecifier);
105107
});
106108
}));
107109
},
@@ -547,7 +549,7 @@ namespace ts.codefix {
547549
const { importKind, moduleSpecifier } = fix;
548550
addNewImports(changes, sourceFile, moduleSpecifier, quotePreference, importKind === ImportKind.Default ? { defaultImport: symbolName, namedImports: emptyArray, namespaceLikeImport: undefined }
549551
: importKind === ImportKind.Named ? { defaultImport: undefined, namedImports: [symbolName], namespaceLikeImport: undefined }
550-
: { defaultImport: undefined, namedImports: emptyArray, namespaceLikeImport: { importKind, name: symbolName } });
552+
: { defaultImport: undefined, namedImports: emptyArray, namespaceLikeImport: { importKind, name: symbolName } }, /*blankLineBetween*/ true);
551553
return [importKind === ImportKind.Default ? Diagnostics.Import_default_0_from_module_1 : Diagnostics.Import_0_from_module_1, symbolName, moduleSpecifier];
552554
}
553555
default:
@@ -608,21 +610,21 @@ namespace ts.codefix {
608610
readonly name: string;
609611
} | undefined;
610612
}
611-
function addNewImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, moduleSpecifier: string, quotePreference: QuotePreference, { defaultImport, namedImports, namespaceLikeImport }: ImportsCollection): void {
613+
function addNewImports(changes: textChanges.ChangeTracker, sourceFile: SourceFile, moduleSpecifier: string, quotePreference: QuotePreference, { defaultImport, namedImports, namespaceLikeImport }: ImportsCollection, blankLineBetween: boolean): void {
612614
const quotedModuleSpecifier = makeStringLiteral(moduleSpecifier, quotePreference);
613615
if (defaultImport !== undefined || namedImports.length) {
614616
insertImport(changes, sourceFile,
615617
makeImport(
616618
defaultImport === undefined ? undefined : createIdentifier(defaultImport),
617-
namedImports.map(n => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(n))), moduleSpecifier, quotePreference));
619+
namedImports.map(n => createImportSpecifier(/*propertyName*/ undefined, createIdentifier(n))), moduleSpecifier, quotePreference), /*blankLineBetween*/ blankLineBetween);
618620
}
619621
if (namespaceLikeImport) {
620622
insertImport(
621623
changes,
622624
sourceFile,
623625
namespaceLikeImport.importKind === ImportKind.Equals ? createImportEqualsDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createIdentifier(namespaceLikeImport.name), createExternalModuleReference(quotedModuleSpecifier)) :
624626
namespaceLikeImport.importKind === ImportKind.ConstEquals ? createConstEqualsRequireDeclaration(namespaceLikeImport.name, quotedModuleSpecifier) :
625-
createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(/*name*/ undefined, createNamespaceImport(createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier));
627+
createImportDeclaration(/*decorators*/ undefined, /*modifiers*/ undefined, createImportClause(/*name*/ undefined, createNamespaceImport(createIdentifier(namespaceLikeImport.name))), quotedModuleSpecifier), /*blankLineBetween*/ blankLineBetween);
626628
}
627629
}
628630

src/services/refactors/moveToNewFile.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ namespace ts.refactor {
121121
const quotePreference = getQuotePreference(oldFile, preferences);
122122
const importsFromNewFile = createOldFileImportsFromNewFile(usage.oldFileImportsFromNewFile, newModuleName, useEs6ModuleSyntax, quotePreference);
123123
if (importsFromNewFile) {
124-
insertImport(changes, oldFile, importsFromNewFile);
124+
insertImport(changes, oldFile, importsFromNewFile, /*blankLineBetween*/ true);
125125
}
126126

127127
deleteUnusedOldImports(oldFile, toMove.all, changes, usage.unusedImportsFromOldFile, checker);

src/services/utilities.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1488,13 +1488,13 @@ namespace ts {
14881488
return node.modifiers && find(node.modifiers, m => m.kind === kind);
14891489
}
14901490

1491-
export function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement): void {
1491+
export function insertImport(changes: textChanges.ChangeTracker, sourceFile: SourceFile, importDecl: Statement, blankLineBetween: boolean): void {
14921492
const lastImportDeclaration = findLast(sourceFile.statements, isAnyImportSyntax);
14931493
if (lastImportDeclaration) {
14941494
changes.insertNodeAfter(sourceFile, lastImportDeclaration, importDecl);
14951495
}
14961496
else {
1497-
changes.insertNodeAtTopOfFile(sourceFile, importDecl, /*blankLineBetween*/ true);
1497+
changes.insertNodeAtTopOfFile(sourceFile, importDecl, blankLineBetween);
14981498
}
14991499
}
15001500

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/// <reference path="fourslash.ts" />
2+
3+
// @Filename: /a.ts
4+
////export const a: number;
5+
6+
// @Filename: /b.ts
7+
////export const b: number;
8+
9+
// @Filename: /c.ts
10+
////export const c: number;
11+
12+
// @Filename: /main.ts
13+
////a;
14+
////b;
15+
////c;
16+
17+
goTo.file("/main.ts");
18+
verify.codeFixAll({
19+
fixId: "fixMissingImport",
20+
fixAllDescription: "Add all missing imports",
21+
newFileContent:
22+
`import { a } from "./a";
23+
import { b } from "./b";
24+
import { c } from "./c";
25+
26+
a;
27+
b;
28+
c;`,
29+
});

tests/cases/fourslash/importNameCodeFix_types_classic.ts

-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ verify.codeFixAll({
1818
fixAllDescription: "Add all missing imports",
1919
newFileContent:
2020
`import { xyz } from "foo";
21-
2221
import { qrs } from "./node_modules/bar/index";
2322
2423
xyz;

0 commit comments

Comments
 (0)