mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-05-11 16:38:46 -05:00
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:
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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) => {
|
||||
|
||||
Reference in New Issue
Block a user