Support project root path for controlling config file searching depth (#15238)

* stops at projectRootPath when searching config file

* Add tests

* Update editorServices.ts

Remove extra `true &&`
This commit is contained in:
Zhengbo Li
2017-04-19 11:42:24 -07:00
committed by GitHub
parent 5819402bf6
commit e8fd1cf466
4 changed files with 44 additions and 11 deletions

View File

@@ -3493,6 +3493,30 @@ namespace ts.projectSystem {
});
});
describe("searching for config file", () => {
it("should stop at projectRootPath if given", () => {
const f1 = {
path: "/a/file1.ts",
content: ""
};
const configFile = {
path: "/tsconfig.json",
content: "{}"
};
const host = createServerHost([f1, configFile]);
const service = createProjectService(host);
service.openClientFile(f1.path, /*fileContent*/ undefined, /*scriptKind*/ undefined, "/a");
checkNumberOfConfiguredProjects(service, 0);
checkNumberOfInferredProjects(service, 1);
service.closeClientFile(f1.path);
service.openClientFile(f1.path);
checkNumberOfConfiguredProjects(service, 1);
checkNumberOfInferredProjects(service, 0);
});
});
describe("cancellationToken", () => {
it("is attached to request", () => {
const f1 = {

View File

@@ -787,12 +787,12 @@ namespace ts.server {
* we first detect if there is already a configured project created for it: if so, we re-read
* the tsconfig file content and update the project; otherwise we create a new one.
*/
private openOrUpdateConfiguredProjectForFile(fileName: NormalizedPath): OpenConfiguredProjectResult {
private openOrUpdateConfiguredProjectForFile(fileName: NormalizedPath, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
const searchPath = getDirectoryPath(fileName);
this.logger.info(`Search path: ${searchPath}`);
// check if this file is already included in one of external projects
const configFileName = this.findConfigFile(asNormalizedPath(searchPath));
const configFileName = this.findConfigFile(asNormalizedPath(searchPath), projectRootPath);
if (!configFileName) {
this.logger.info("No config files found.");
return {};
@@ -826,8 +826,8 @@ namespace ts.server {
// current directory (the directory in which tsc was invoked).
// The server must start searching from the directory containing
// the newly opened file.
private findConfigFile(searchPath: NormalizedPath): NormalizedPath {
while (true) {
private findConfigFile(searchPath: NormalizedPath, projectRootPath?: NormalizedPath): NormalizedPath {
while (!projectRootPath || searchPath.indexOf(projectRootPath) >= 0) {
const tsconfigFileName = asNormalizedPath(combinePaths(searchPath, "tsconfig.json"));
if (this.host.fileExists(tsconfigFileName)) {
return tsconfigFileName;
@@ -1326,17 +1326,17 @@ namespace ts.server {
* @param filename is absolute pathname
* @param fileContent is a known version of the file content that is more up to date than the one on disk
*/
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind): OpenConfiguredProjectResult {
return this.openClientFileWithNormalizedPath(toNormalizedPath(fileName), fileContent, scriptKind);
openClientFile(fileName: string, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: string): OpenConfiguredProjectResult {
return this.openClientFileWithNormalizedPath(toNormalizedPath(fileName), fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath ? toNormalizedPath(projectRootPath) : undefined);
}
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean): OpenConfiguredProjectResult {
openClientFileWithNormalizedPath(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, hasMixedContent?: boolean, projectRootPath?: NormalizedPath): OpenConfiguredProjectResult {
let configFileName: NormalizedPath;
let configFileErrors: Diagnostic[];
let project: ConfiguredProject | ExternalProject = this.findContainingExternalProject(fileName);
if (!project) {
({ configFileName, configFileErrors } = this.openOrUpdateConfiguredProjectForFile(fileName));
({ configFileName, configFileErrors } = this.openOrUpdateConfiguredProjectForFile(fileName, projectRootPath));
if (configFileName) {
project = this.findConfiguredProjectByProjectName(configFileName);
}

View File

@@ -1041,6 +1041,11 @@ namespace ts.server.protocol {
* "TS", "JS", "TSX", "JSX"
*/
scriptKindName?: ScriptKindName;
/**
* Used to limit the searching for project config file. If given the searching will stop at this
* root path; otherwise it will go all the way up to the dist root path.
*/
projectRootPath?: string;
}
export type ScriptKindName = "TS" | "JS" | "TSX" | "JSX";

View File

@@ -979,8 +979,8 @@ namespace ts.server {
* @param fileName is the name of the file to be opened
* @param fileContent is a version of the file content that is known to be more up to date than the one on disk
*/
private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind) {
const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind);
private openClientFile(fileName: NormalizedPath, fileContent?: string, scriptKind?: ScriptKind, projectRootPath?: NormalizedPath) {
const { configFileName, configFileErrors } = this.projectService.openClientFileWithNormalizedPath(fileName, fileContent, scriptKind, /*hasMixedContent*/ false, projectRootPath);
if (this.eventHandler) {
this.eventHandler({
eventName: "configFileDiag",
@@ -1659,7 +1659,11 @@ namespace ts.server {
return this.requiredResponse(this.getRenameInfo(request.arguments));
},
[CommandNames.Open]: (request: protocol.OpenRequest) => {
this.openClientFile(toNormalizedPath(request.arguments.file), request.arguments.fileContent, convertScriptKindName(request.arguments.scriptKindName));
this.openClientFile(
toNormalizedPath(request.arguments.file),
request.arguments.fileContent,
convertScriptKindName(request.arguments.scriptKindName),
request.arguments.projectRootPath ? toNormalizedPath(request.arguments.projectRootPath) : undefined);
return this.notRequired();
},
[CommandNames.Quickinfo]: (request: protocol.QuickInfoRequest) => {