diff --git a/src/harness/harnessLanguageService.ts b/src/harness/harnessLanguageService.ts index 0e142debedcb0..1c85acfb80e3f 100644 --- a/src/harness/harnessLanguageService.ts +++ b/src/harness/harnessLanguageService.ts @@ -189,10 +189,7 @@ namespace Harness.LanguageService { getCancellationToken() { return this.cancellationToken; } getDirectories(path: string): string[] { const dir = this.virtualFileSystem.traversePath(path); - if (dir && dir.isDirectory()) { - return ts.map((dir).getDirectories(), (d) => ts.combinePaths(path, d.name)); - } - return []; + return dir && dir.isDirectory() ? dir.getDirectories().map(d => d.name) : []; } getCurrentDirectory(): string { return virtualFileSystemRoot; } getDefaultLibFileName(): string { return Harness.Compiler.defaultLibFileName; } diff --git a/src/services/completions.ts b/src/services/completions.ts index 60dfa8aaaa2c0..8a28ae88bb695 100644 --- a/src/services/completions.ts +++ b/src/services/completions.ts @@ -359,7 +359,7 @@ namespace ts.Completions { // import x = require("/*completion position*/"); // var y = require("/*completion position*/"); // export * from "/*completion position*/"; - return pathCompletionsInfo(PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node as StringLiteral, compilerOptions, host, typeChecker)); + return pathCompletionsInfo(PathCompletions.getStringLiteralCompletionsFromModuleNames(sourceFile, node, compilerOptions, host, typeChecker)); default: return fromContextualType(); diff --git a/src/services/pathCompletions.ts b/src/services/pathCompletions.ts index 8840919c32963..d27417ec521dd 100644 --- a/src/services/pathCompletions.ts +++ b/src/services/pathCompletions.ts @@ -6,7 +6,7 @@ namespace ts.Completions.PathCompletions { const scriptPath = node.getSourceFile().path; const scriptDirectory = getDirectoryPath(scriptPath); - const span = getDirectoryFragmentTextSpan((node).text, node.getStart(sourceFile) + 1); + const span = getDirectoryFragmentTextSpan(node.text, node.getStart(sourceFile) + 1); if (isPathRelativeToScript(literalValue) || isRootedDiskPath(literalValue)) { const extensions = getSupportedExtensions(compilerOptions); if (compilerOptions.rootDirs) { @@ -226,7 +226,8 @@ namespace ts.Completions.PathCompletions { const includeGlob = normalizedSuffix ? "**/*" : "./*"; const matches = tryReadDirectory(host, baseDirectory, fileExtensions, /*exclude*/ undefined, [includeGlob]); - const directories = tryGetDirectories(host, baseDirectory); + const directories = tryGetDirectories(host, baseDirectory).map(d => combinePaths(baseDirectory, d)); + // Trim away prefix and suffix return mapDefined(concatenate(matches, directories), match => { const normalizedMatch = normalizePath(match); @@ -476,14 +477,14 @@ namespace ts.Completions.PathCompletions { const nodeModulesDependencyKeys = ["dependencies", "devDependencies", "peerDependencies", "optionalDependencies"]; function tryGetDirectories(host: LanguageServiceHost, directoryName: string): string[] { - return tryIOAndConsumeErrors(host, host.getDirectories, directoryName); + return tryIOAndConsumeErrors(host, host.getDirectories, directoryName) || []; } - function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] | undefined { + function tryReadDirectory(host: LanguageServiceHost, path: string, extensions?: ReadonlyArray, exclude?: ReadonlyArray, include?: ReadonlyArray): string[] | undefined | undefined { return tryIOAndConsumeErrors(host, host.readDirectory, path, extensions, exclude, include); } - function tryReadFile(host: LanguageServiceHost, path: string): string { + function tryReadFile(host: LanguageServiceHost, path: string): string | undefined { return tryIOAndConsumeErrors(host, host.readFile, path); } diff --git a/src/services/types.ts b/src/services/types.ts index 4ebd4a3e76a1e..594484e1ea733 100644 --- a/src/services/types.ts +++ b/src/services/types.ts @@ -200,8 +200,8 @@ namespace ts { /* @internal */ hasChangedAutomaticTypeDirectiveNames?: boolean; /* - * getDirectories is also required for full import and type reference completions. Without it defined, certain - * completions will not be provided + * Required for full import and type reference completions. + * These should be unprefixed names. E.g. `getDirectories("/foo/bar")` should return `["a", "b"]`, not `["/foo/bar/a", "/foo/bar/b"]`. */ getDirectories?(directoryName: string): string[]; diff --git a/tests/cases/fourslash/completionsPaths_pathMapping.ts b/tests/cases/fourslash/completionsPaths_pathMapping.ts index 7a6283bce3a8c..80e0fa26d9fc9 100644 --- a/tests/cases/fourslash/completionsPaths_pathMapping.ts +++ b/tests/cases/fourslash/completionsPaths_pathMapping.ts @@ -20,8 +20,4 @@ ////} const [replacementSpan] = test.ranges(); -verify.completionsAt("", [ - { name: "a", replacementSpan }, - { name: "b", replacementSpan }, - { name: "dir", replacementSpan }, -]); +verify.completionsAt("", ["a", "b", "dir"].map(name => ({ name, replacementSpan })));