From b059135c51ee93f8fb44dd70a2ca67674ff7a877 Mon Sep 17 00:00:00 2001 From: Andy Date: Thu, 15 Nov 2018 15:11:27 -0800 Subject: [PATCH] When adding relative completions with rootDirs, still add completions for regular relative imports (#28561) --- src/services/stringCompletions.ts | 19 ++++------ ...mpletionForStringLiteralRelativeImport4.ts | 35 +++++++++++++------ 2 files changed, 30 insertions(+), 24 deletions(-) diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 7e60edc03d7..9548397a22d 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -281,33 +281,26 @@ namespace ts.Completions.StringCompletions { * Takes a script path and returns paths for all potential folders that could be merged with its * containing folder via the "rootDirs" compiler option */ - function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptPath: string, ignoreCase: boolean): string[] { + function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptDirectory: string, ignoreCase: boolean): ReadonlyArray { // Make all paths absolute/normalized if they are not already rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); // Determine the path to the directory containing the script relative to the root directory it is contained within const relativeDirectory = firstDefined(rootDirs, rootDirectory => - containsPath(rootDirectory, scriptPath, basePath, ignoreCase) ? scriptPath.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217 + containsPath(rootDirectory, scriptDirectory, basePath, ignoreCase) ? scriptDirectory.substr(rootDirectory.length) : undefined)!; // TODO: GH#18217 // Now find a path for each potential directory that is to be merged with the one containing the script return deduplicate( - rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)), + [...rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)), scriptDirectory], equateStringsCaseSensitive, compareStringsCaseSensitive); } - function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptPath: string, extensionOptions: ExtensionOptions, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude?: string): NameAndKind[] { + function getCompletionEntriesForDirectoryFragmentWithRootDirs(rootDirs: string[], fragment: string, scriptDirectory: string, extensionOptions: ExtensionOptions, compilerOptions: CompilerOptions, host: LanguageServiceHost, exclude: string): ReadonlyArray { const basePath = compilerOptions.project || host.getCurrentDirectory(); const ignoreCase = !(host.useCaseSensitiveFileNames && host.useCaseSensitiveFileNames()); - const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptPath, ignoreCase); - - const result: NameAndKind[] = []; - - for (const baseDirectory of baseDirectories) { - getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude, result); - } - - return result; + const baseDirectories = getBaseDirectoriesFromRootDirs(rootDirs, basePath, scriptDirectory, ignoreCase); + return flatMap(baseDirectories, baseDirectory => getCompletionEntriesForDirectoryFragment(fragment, baseDirectory, extensionOptions, host, exclude)); } /** diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImport4.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImport4.ts index cacb3c19174..c2fff29333b 100644 --- a/tests/cases/fourslash/completionForStringLiteralRelativeImport4.ts +++ b/tests/cases/fourslash/completionForStringLiteralRelativeImport4.ts @@ -2,23 +2,29 @@ // Should give completions for directories that are merged via the rootDirs compiler option -// @rootDirs: tests/cases/fourslash/sub/src1,tests/cases/fourslash/src2 +// @rootDirs: /sub/src1,/src2 -// @Filename: src2/test0.ts +// @Filename: /src2/test0.ts //// import * as foo1 from "./mo/*import_as0*/ //// import foo2 = require("./mo/*import_equals0*/ //// var foo3 = require("./mo/*require0*/ -// @Filename: src2/module0.ts +// @Filename: /src2/inner/inner0.ts +////import * as s from ".//*inner*/"; + +// @Filename: /src2/inner/inner1.ts +////export const x = 0; + +// @Filename: /src2/module0.ts //// export var w = 0; -// @Filename: sub/src1/module1.ts +// @Filename: /sub/src1/module1.ts //// export var x = 0; -// @Filename: sub/src1/module2.ts +// @Filename: /sub/src1/module2.ts //// export var y = 0; -// @Filename: sub/src1/more/module3.ts +// @Filename: /sub/src1/more/module3.ts //// export var z = 0; @@ -37,8 +43,15 @@ // @Filename: e2.js //// -verify.completions({ - marker: test.markers(), - exact: ["module1", "module2", "more", "module0"], - isNewIdentifierLocation: true, -}); +verify.completions( + { + marker: ["import_as0", "import_equals0", "require0"], + exact: ["module1", "module2", "more", "module0", "inner"], + isNewIdentifierLocation: true, + }, + { + marker: "inner", + exact: "inner1", + isNewIdentifierLocation: true, + } +);