diff --git a/src/services/stringCompletions.ts b/src/services/stringCompletions.ts index 657f104418fa5..822d5c4177127 100644 --- a/src/services/stringCompletions.ts +++ b/src/services/stringCompletions.ts @@ -647,14 +647,14 @@ function getSupportedExtensionsForModuleResolution(compilerOptions: CompilerOpti */ function getBaseDirectoriesFromRootDirs(rootDirs: string[], basePath: string, scriptDirectory: string, ignoreCase: boolean): readonly string[] { // Make all paths absolute/normalized if they are not already - rootDirs = rootDirs.map(rootDirectory => normalizePath(isRootedDiskPath(rootDirectory) ? rootDirectory : combinePaths(basePath, rootDirectory))); + rootDirs = rootDirs.map(rootDirectory => ensureTrailingDirectorySeparator(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, 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)), scriptDirectory], + [...rootDirs.map(rootDirectory => combinePaths(rootDirectory, relativeDirectory)), scriptDirectory].map(baseDir => removeTrailingDirectorySeparator(baseDir)), equateStringsCaseSensitive, compareStringsCaseSensitive, ); diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImport5.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImport5.ts new file mode 100644 index 0000000000000..c6dde282ea22f --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralRelativeImport5.ts @@ -0,0 +1,37 @@ +/// + +// Should give correct completions for directories when invoked from within nested folders + +// @rootDirs: /repo/src1,/repo/src2/,/repo/generated1,/repo/generated2/ + +// @Filename: /dir/secret_file.ts +//// /*secret_file*/ + +// @Filename: /repo/src1/dir/test1.ts +//// import * as foo1 from ".//*import_as1*/ +//// import foo2 = require(".//*import_equals1*/ +//// var foo3 = require(".//*require1*/ + +// @Filename: /repo/src2/dir/test2.ts +//// import * as foo1 from ".//*import_as2*/ +//// import foo2 = require(".//*import_equals2*/ +//// var foo3 = require(".//*require2*/ + +// @Filename: /repo/generated1/dir/f1.ts +//// /*f1*/ + +// @Filename: /repo/generated2/dir/f2.ts +//// /*f2*/ + +verify.completions( + { + marker: ["import_as1", "import_equals1", "require1"], + unsorted: ["f1", "f2", "test2"], + isNewIdentifierLocation: true, + }, + { + marker: ["import_as2", "import_equals2", "require2"], + unsorted: ["f1", "f2", "test1"], + isNewIdentifierLocation: true, + } +); diff --git a/tests/cases/fourslash/completionForStringLiteralRelativeImport6.ts b/tests/cases/fourslash/completionForStringLiteralRelativeImport6.ts new file mode 100644 index 0000000000000..0cffe863eb7a1 --- /dev/null +++ b/tests/cases/fourslash/completionForStringLiteralRelativeImport6.ts @@ -0,0 +1,34 @@ +/// + +// Should give correct completions for rootDirs regardless of the slash at the end + +// @rootDirs: /repo/src1,/repo/src2/,/repo/generated1,/repo/generated2/ + +// @Filename: /repo/src1/test1.ts +//// import * as foo1 from "./dir//*import_as1*/ +//// import foo2 = require("./dir//*import_equals1*/ +//// var foo3 = require("./dir//*require1*/ + +// @Filename: /repo/src2/test2.ts +//// import * as foo1 from "./dir//*import_as2*/ +//// import foo2 = require("./dir//*import_equals2*/ +//// var foo3 = require("./dir//*require2*/ + +// @Filename: /repo/generated1/dir/f1.ts +//// /*f1*/ + +// @Filename: /repo/generated2/dir/f2.ts +//// /*f2*/ + +verify.completions( + { + marker: ["import_as1", "import_equals1", "require1"], + exact: ["f1", "f2"], + isNewIdentifierLocation: true, + }, + { + marker: ["import_as2", "import_equals2", "require2"], + exact: ["f1", "f2"], + isNewIdentifierLocation: true, + } +);