Merge pull request #22072 from Microsoft/configFileWithIncorrectProjectRoot

Search till root just like tsc when the projectRootPath specified doesnt contain the info.path
This commit is contained in:
Sheetal Nandi
2018-05-04 12:23:56 -07:00
committed by GitHub
2 changed files with 90 additions and 5 deletions

View File

@@ -4074,11 +4074,11 @@ namespace ts.projectSystem {
// Open file1 -> configFile
verifyConfigFileName(file1, "/a", configFile);
verifyConfigFileName(file1, "/a/b", configFile);
verifyConfigFileName(file1, "/a/B", useCaseSensitiveFileNames ? undefined : configFile);
verifyConfigFileName(file1, "/a/B", 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 ? configFile2 : configFile);
verifyConfigFileName(file2, "/a/B", useCaseSensitiveFileNames ? undefined : configFile);
function verifyConfigFileName(file: FileOrFolder, projectRoot: string, expectedConfigFile: FileOrFolder | undefined) {
@@ -5607,6 +5607,88 @@ namespace ts.projectSystem {
checkWatchedDirectories(host, [], /*recursive*/ false);
checkWatchedDirectories(host, getTypeRootsFromLocation(projectDir), /*recursive*/ true);
});
describe("when the opened file is not from project root", () => {
const projectRoot = "/a/b/projects/project";
const file: FileOrFolder = {
path: `${projectRoot}/src/index.ts`,
content: "let y = 10"
};
const tsconfig: FileOrFolder = {
path: `${projectRoot}/tsconfig.json`,
content: "{}"
};
const files = [file, libFile];
const filesWithConfig = files.concat(tsconfig);
const dirOfFile = getDirectoryPath(file.path);
function openClientFile(files: FileOrFolder[]) {
const host = createServerHost(files);
const projectService = createProjectService(host);
projectService.openClientFile(file.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a/b/projects/proj");
return { host, projectService };
}
function verifyConfiguredProject(host: TestServerHost, projectService: TestProjectService, orphanInferredProject?: boolean) {
projectService.checkNumberOfProjects({ configuredProjects: 1, inferredProjects: orphanInferredProject ? 1 : 0 });
const project = projectService.configuredProjects.get(tsconfig.path);
assert.isDefined(project);
if (orphanInferredProject) {
const inferredProject = projectService.inferredProjects[0];
assert.isTrue(inferredProject.isOrphan());
}
checkProjectActualFiles(project, [file.path, libFile.path, tsconfig.path]);
checkWatchedFiles(host, [libFile.path, tsconfig.path]);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectories(host, (orphanInferredProject ? [projectRoot, `${dirOfFile}/node_modules/@types`] : [projectRoot]).concat(getTypeRootsFromLocation(projectRoot)), /*recursive*/ true);
}
function verifyInferredProject(host: TestServerHost, projectService: TestProjectService) {
projectService.checkNumberOfProjects({ inferredProjects: 1 });
const project = projectService.inferredProjects[0];
assert.isDefined(project);
const filesToWatch = [libFile.path];
forEachAncestorDirectory(dirOfFile, ancestor => {
filesToWatch.push(combinePaths(ancestor, "tsconfig.json"));
filesToWatch.push(combinePaths(ancestor, "jsconfig.json"));
});
checkProjectActualFiles(project, [file.path, libFile.path]);
checkWatchedFiles(host, filesToWatch);
checkWatchedDirectories(host, emptyArray, /*recursive*/ false);
checkWatchedDirectories(host, getTypeRootsFromLocation(dirOfFile), /*recursive*/ true);
}
it("tsconfig for the file exists", () => {
const { host, projectService } = openClientFile(filesWithConfig);
verifyConfiguredProject(host, projectService);
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
verifyInferredProject(host, projectService);
host.reloadFS(filesWithConfig);
host.runQueuedTimeoutCallbacks();
verifyConfiguredProject(host, projectService, /*orphanInferredProject*/ true);
});
it("tsconfig for the file does not exist", () => {
const { host, projectService } = openClientFile(files);
verifyInferredProject(host, projectService);
host.reloadFS(filesWithConfig);
host.runQueuedTimeoutCallbacks();
verifyConfiguredProject(host, projectService, /*orphanInferredProject*/ true);
host.reloadFS(files);
host.runQueuedTimeoutCallbacks();
verifyInferredProject(host, projectService);
});
});
});
describe("tsserverProjectSystem cancellationToken", () => {

View File

@@ -1197,8 +1197,11 @@ namespace ts.server {
const projectRootPath = this.openFiles.get(info.path);
let searchPath = asNormalizedPath(getDirectoryPath(info.fileName));
const isSearchPathInProjectRoot = () => containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames);
while (!projectRootPath || containsPath(projectRootPath, searchPath, this.currentDirectory, !this.host.useCaseSensitiveFileNames)) {
// If projectRootPath doesnt contain info.path, then do normal search for config file
const anySearchPathOk = !projectRootPath || !isSearchPathInProjectRoot();
do {
const canonicalSearchPath = normalizedPathToPath(searchPath, this.currentDirectory, this.toCanonicalFileName);
const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json"));
let result = action(tsconfigFileName, combinePaths(canonicalSearchPath, "tsconfig.json"));
@@ -1217,7 +1220,7 @@ namespace ts.server {
break;
}
searchPath = parentPath;
}
} while (anySearchPathOk || isSearchPathInProjectRoot());
return undefined;
}
@@ -1235,7 +1238,7 @@ namespace ts.server {
this.logger.info(`Search path: ${getDirectoryPath(info.fileName)}`);
const configFileName = this.forEachConfigFileLocation(info,
(configFileName, canonicalConfigFilePath) =>
this.configFileExists(configFileName, canonicalConfigFilePath, info),
this.configFileExists(configFileName, canonicalConfigFilePath, info)
);
if (configFileName) {
this.logger.info(`For info: ${info.fileName} :: Config file name: ${configFileName}`);