From 1986a5faa369b98ad7391cc447a9a2ef46cafed7 Mon Sep 17 00:00:00 2001 From: TypeScript Bot Date: Wed, 12 Feb 2020 14:49:54 -0800 Subject: [PATCH] =?UTF-8?q?=F0=9F=A4=96=20Cherry-pick=20PR=20#36751=20into?= =?UTF-8?q?=20release-3.8=20(#36757)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Component commits: ebbba5bd8f fix(36416): empty import path causes server crash Co-authored-by: Alexander T. --- src/services/textChanges.ts | 3 +- .../unusedImportDeclaration_withEmptyPath.ts | 12 +++++ .../unusedImportDeclaration_withEmptyPath1.ts | 22 ++++++++++ .../unusedImportDeclaration_withEmptyPath2.ts | 22 ++++++++++ .../unusedImportDeclaration_withEmptyPath3.ts | 23 ++++++++++ .../unusedImportDeclaration_withEmptyPath4.ts | 35 +++++++++++++++ .../unusedImportDeclaration_withEmptyPath5.ts | 44 +++++++++++++++++++ 7 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath.ts create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath1.ts create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath2.ts create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath3.ts create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath4.ts create mode 100644 tests/cases/fourslash/unusedImportDeclaration_withEmptyPath5.ts diff --git a/src/services/textChanges.ts b/src/services/textChanges.ts index be978b5a3342b..710cd10f89c54 100644 --- a/src/services/textChanges.ts +++ b/src/services/textChanges.ts @@ -1238,9 +1238,10 @@ namespace ts.textChanges { } case SyntaxKind.ImportDeclaration: + const isFirstImport = sourceFile.imports.length && node === first(sourceFile.imports).parent || node === find(sourceFile.statements, isImportDeclaration); deleteNode(changes, sourceFile, node, // For first import, leave header comment in place - node === sourceFile.imports[0].parent ? { leadingTriviaOption: LeadingTriviaOption.Exclude } : undefined); + isFirstImport ? { leadingTriviaOption: LeadingTriviaOption.Exclude } : undefined); break; case SyntaxKind.BindingElement: diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath.ts new file mode 100644 index 0000000000000..9c2e95a8085c1 --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath.ts @@ -0,0 +1,12 @@ +/// + +// @Filename: /a.ts +////// leading trivia +////import * as foo from ""; // trailing trivia + +verify.codeFix({ + description: "Remove import from ''", + newFileContent: +`// leading trivia + // trailing trivia`, +}); diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath1.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath1.ts new file mode 100644 index 0000000000000..5fadafcd210c9 --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath1.ts @@ -0,0 +1,22 @@ +/// + +// @Filename: /a.ts +////// leading trivia +////import * as foo from ""; +////import { b } from "./b"; +////import { c } from "./c"; + +// @Filename: /b.ts +////export const b = null; + +// @Filename: /c.ts +////export const c = null; + +verify.codeFix({ + index: 0, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import { b } from "./b"; +import { c } from "./c";`, +}); diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath2.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath2.ts new file mode 100644 index 0000000000000..03f812c943f7f --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath2.ts @@ -0,0 +1,22 @@ +/// + +// @Filename: /a.ts +////// leading trivia +////import { b } from "./b"; +////import * as foo from ""; +////import { c } from "./c"; + +// @Filename: /b.ts +////export const b = null; + +// @Filename: /c.ts +////export const c = null; + +verify.codeFix({ + index: 1, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import { b } from "./b"; +import { c } from "./c";`, +}); diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath3.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath3.ts new file mode 100644 index 0000000000000..430bb31b8727a --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath3.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /a.ts +////// leading trivia +////import { b } from "./b"; +////import { c } from "./c"; +////import * as foo from ""; + +// @Filename: /b.ts +////export const b = null; + +// @Filename: /c.ts +////export const c = null; + +verify.codeFix({ + index: 2, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import { b } from "./b"; +import { c } from "./c"; +`, +}); diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath4.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath4.ts new file mode 100644 index 0000000000000..8ea32f73d7acb --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath4.ts @@ -0,0 +1,35 @@ +/// + +// @Filename: /a.ts +////// leading trivia +////import * as a from ""; +////import * as b from ""; +////import * as c from ""; + +verify.codeFix({ + index: 0, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import * as b from ""; +import * as c from "";`, +}); + +verify.codeFix({ + index: 1, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import * as a from ""; +import * as c from "";`, +}); + +verify.codeFix({ + index: 2, + description: "Remove import from ''", + newFileContent: +`// leading trivia +import * as a from ""; +import * as b from ""; +` +}); diff --git a/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath5.ts b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath5.ts new file mode 100644 index 0000000000000..293ddecf428ee --- /dev/null +++ b/tests/cases/fourslash/unusedImportDeclaration_withEmptyPath5.ts @@ -0,0 +1,44 @@ +/// + +// @Filename: /main.ts +////// leading trivia +////import { a } from "./a"; +////import { b } from "./b"; +////import { c } from "./c"; + +// @Filename: /a.ts +////export const a = null; + +// @Filename: /b.ts +////export const b = null; + +// @Filename: /c.ts +////export const c = null; + +verify.codeFix({ + index: 0, + description: "Remove import from './a'", + newFileContent: +`// leading trivia +import { b } from "./b"; +import { c } from "./c";`, +}); + +verify.codeFix({ + index: 1, + description: "Remove import from './b'", + newFileContent: +`// leading trivia +import { a } from "./a"; +import { c } from "./c";`, +}); + +verify.codeFix({ + index: 2, + description: "Remove import from './c'", + newFileContent: +`// leading trivia +import { a } from "./a"; +import { b } from "./b"; +`, +});