From deed981715dcce5d10b3cbfa1701794672212be3 Mon Sep 17 00:00:00 2001 From: Sheetal Nandi Date: Wed, 11 Oct 2017 12:27:21 -0700 Subject: [PATCH] Handle case sensitivity when looking up config file for Script info Fixes #17726 --- .../unittests/tsserverProjectSystem.ts | 46 +++++++++++++++++++ src/server/editorServices.ts | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 2d761ae33c2..f7d082128cd 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -2917,6 +2917,52 @@ namespace ts.projectSystem { function checkSnapLength(snap: IScriptSnapshot, expectedLength: number) { assert.equal(snap.getLength(), expectedLength, "Incorrect snapshot size"); } + + function verifyOpenFileWorks(useCaseSensitiveFileNames: boolean) { + const file1: FileOrFolder = { + path: "/a/b/src/app.ts", + content: "let x = 10;" + }; + const file2: FileOrFolder = { + path: "/a/B/lib/module2.ts", + content: "let z = 10;" + }; + const configFile: FileOrFolder = { + path: "/a/b/tsconfig.json", + content: "" + }; + const configFile2: FileOrFolder = { + path: "/a/tsconfig.json", + content: "" + }; + const host = createServerHost([file1, file2, configFile, configFile2], { + useCaseSensitiveFileNames + }); + const service = createProjectService(host); + + // Open file1 -> configFile + verifyConfigFileName(file1, "/a", configFile); + verifyConfigFileName(file1, "/a/b", configFile); + verifyConfigFileName(file1, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); + + // Open file2 use root "/a/b" + verifyConfigFileName(file2, "/a", useCaseSensitiveFileNames ? configFile2 : configFile); + verifyConfigFileName(file2, "/a/b", useCaseSensitiveFileNames ? undefined : configFile); + verifyConfigFileName(file2, "/a/B", useCaseSensitiveFileNames ? undefined : configFile); + + function verifyConfigFileName(file: FileOrFolder, projectRoot: string, expectedConfigFile: FileOrFolder | undefined) { + const { configFileName } = service.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, projectRoot); + assert.equal(configFileName, expectedConfigFile && expectedConfigFile.path); + service.closeClientFile(file.path); + } + } + it("works when project root is used with case-sensitive system", () => { + verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ true); + }); + + it("works when project root is used with case-insensitive system", () => { + verifyOpenFileWorks(/*useCaseSensitiveFileNames*/ false); + }); }); describe("Language service", () => { diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index 173fd86afe4..379a5fbfe7e 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -1218,7 +1218,7 @@ namespace ts.server { projectRootPath?: NormalizedPath) { let searchPath = asNormalizedPath(getDirectoryPath(info.fileName)); - while (!projectRootPath || stringContains(searchPath, projectRootPath)) { + while (!projectRootPath || containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames)) { const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName); const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json")); let result = action(tsconfigFileName, combinePaths(canonicalSearchPath, "tsconfig.json"));