From 4d04fa9c08f538e32b5e45138e16d9f5e4db6b5d Mon Sep 17 00:00:00 2001 From: Andy Date: Wed, 7 Feb 2018 10:27:40 -0800 Subject: [PATCH] Fix bug in normalizeAndPreserveTrailingSlash: For "./", return "", not "/" (#21704) (#21726) * Fix bug in normalizeAndPreserveTrailingSlash: For "./", return "", not "/" (#21704) * Also check for '.\' --- src/harness/fourslash.ts | 2 +- src/services/pathCompletions.ts | 8 ++++++- ...mpletionsPaths_pathMapping_relativePath.ts | 23 +++++++++++++++++++ 3 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/completionsPaths_pathMapping_relativePath.ts diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index e01f8cb3566..85e07cf7afb 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -865,7 +865,7 @@ namespace FourSlash { ts.zipWith(actual, expected, (completion, expectedCompletion, index) => { const { name, insertText, replacementSpan } = typeof expectedCompletion === "string" ? { name: expectedCompletion, insertText: undefined, replacementSpan: undefined } : expectedCompletion; if (completion.name !== name) { - this.raiseError(`Expected completion at index ${index} to be ${expectedCompletion}, got ${completion.name}`); + this.raiseError(`Expected completion at index ${index} to be ${name}, got ${completion.name}`); } if (completion.insertText !== insertText) { this.raiseError(`Expected completion insert text at index ${index} to be ${insertText}, got ${completion.insertText}`); diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 32b7f94c88b..c87e26e47d8 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -455,7 +455,13 @@ namespace ts.Completions.PathCompletions { } function normalizeAndPreserveTrailingSlash(path: string) { - return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(normalizePath(path)) : normalizePath(path); + if (path === "./" || path === ".\\") { + // normalizePath turns "./" into "". "" + "/" would then be a rooted path instead of a relative one, so avoid this particular case. + // There is no problem for adding "/" to a non-empty string -- it's only a problem at the beginning. + return ""; + } + const norm = normalizePath(path); + return hasTrailingDirectorySeparator(path) ? ensureTrailingDirectorySeparator(norm) : norm; } /** diff --git a/tests/cases/fourslash/completionsPaths_pathMapping_relativePath.ts b/tests/cases/fourslash/completionsPaths_pathMapping_relativePath.ts new file mode 100644 index 00000000000..c24d3690298 --- /dev/null +++ b/tests/cases/fourslash/completionsPaths_pathMapping_relativePath.ts @@ -0,0 +1,23 @@ +/// + +// @Filename: /foo.ts +////not read + +// @Filename: /x/b.ts +////export const x = 0; + +// @Filename: /x/a.ts +////import { } from "foo/[|/**/|]"; + +// @Filename: /x/tsconfig.json +////{ +//// "compilerOptions": { +//// "baseUrl": ".", +//// "paths": { +//// "foo/*": ["./*"] +//// } +//// } +////} + +const [replacementSpan] = test.ranges(); +verify.completionsAt("", ["a", "b"].map(name => ({ name, replacementSpan })));