diff --git a/src/harness/unittests/tsserverProjectSystem.ts b/src/harness/unittests/tsserverProjectSystem.ts index 24d450beeb8..531a4bebf4f 100644 --- a/src/harness/unittests/tsserverProjectSystem.ts +++ b/src/harness/unittests/tsserverProjectSystem.ts @@ -1283,5 +1283,26 @@ namespace ts { projectService.ensureInferredProjectsUpToDate_TestOnly(); checkNumberOfProjects(projectService, { inferredProjects: 2 }); }); + + it("project settings for inferred projects", () => { + const file1 = { + path: "/a/b/app.ts", + content: `import {x} from "mod"` + }; + const modFile = { + path: "/a/mod.ts", + content: "export let x: number" + }; + const host = createServerHost([file1, modFile]); + const projectService = new server.ProjectService(host, nullLogger, nullCancellationToken, /*useSingleInferredProject*/ false); + + projectService.openClientFile(file1.path); + projectService.openClientFile(modFile.path); + + checkNumberOfProjects(projectService, { inferredProjects: 2 }); + + projectService.setCompilerOptionsForInferredProjects({ moduleResolution: ModuleResolutionKind.Classic }); + checkNumberOfProjects(projectService, { inferredProjects: 1 }); + }); }); } \ No newline at end of file diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index a11ad2bccd4..3281161969d 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -140,6 +140,7 @@ namespace ts.server { */ readonly openFiles: ScriptInfo[] = []; + private compilerOptionsForInferredProjects: CompilerOptions; private readonly directoryWatchers: DirectoryWatchers; private readonly throttledOperations: ThrottledOperations; @@ -176,6 +177,14 @@ namespace ts.server { this.ensureInferredProjectsUpToDate(); } + setCompilerOptionsForInferredProjects(compilerOptions: CompilerOptions): void { + this.compilerOptionsForInferredProjects = compilerOptions; + for (const proj of this.inferredProjects) { + proj.setCompilerOptions(compilerOptions); + } + this.updateProjectGraphs(this.inferredProjects); + } + stopWatchingDirectory(directory: string) { this.directoryWatchers.stopWatchingDirectory(directory); } @@ -809,7 +818,7 @@ namespace ts.server { const useExistingProject = this.useSingleInferredProject && this.inferredProjects.length; const project = useExistingProject ? this.inferredProjects[0] - : new InferredProject(this, this.documentRegistry, /*languageServiceEnabled*/ true); + : new InferredProject(this, this.documentRegistry, /*languageServiceEnabled*/ true, this.compilerOptionsForInferredProjects); project.addRoot(root); diff --git a/src/server/project.ts b/src/server/project.ts index aba4e4dc41c..0eb3f8d1c73 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -267,6 +267,9 @@ namespace ts.server { setCompilerOptions(compilerOptions: CompilerOptions) { if (compilerOptions) { + if (this.projectKind === ProjectKind.Inferred) { + compilerOptions.allowJs = true; + } compilerOptions.allowNonTsExtensions = true; this.compilerOptions = compilerOptions; this.lsHost.setCompilationSettings(compilerOptions); @@ -351,13 +354,13 @@ namespace ts.server { // Used to keep track of what directories are watched for this project directoriesWatchedForTsconfig: string[] = []; - constructor(projectService: ProjectService, documentRegistry: ts.DocumentRegistry, languageServiceEnabled: boolean) { + constructor(projectService: ProjectService, documentRegistry: ts.DocumentRegistry, languageServiceEnabled: boolean, compilerOptions: CompilerOptions) { super(ProjectKind.Inferred, projectService, documentRegistry, /*files*/ undefined, languageServiceEnabled, - /*compilerOptions*/ undefined); + compilerOptions); this.inferredProjectName = makeInferredProjectName(InferredProject.NextId); InferredProject.NextId++; diff --git a/src/server/protocol.d.ts b/src/server/protocol.d.ts index 3bef3e600eb..0106bcb2af7 100644 --- a/src/server/protocol.d.ts +++ b/src/server/protocol.d.ts @@ -698,6 +698,14 @@ declare namespace ts.server.protocol { closedFiles?: string[]; } + export interface SetCompilerOptionsForInferredProjectsArgs { + options: CompilerOptions; + } + + export interface SetCompilerOptionsForInferredProjectsRequest extends Request { + arguments: SetCompilerOptionsForInferredProjectsArgs; + } + /** * Exit request; value of command field is "exit". Ask the server process * to exit. diff --git a/src/server/session.ts b/src/server/session.ts index c1faaaff6d6..172f8fc93af 100644 --- a/src/server/session.ts +++ b/src/server/session.ts @@ -143,6 +143,7 @@ namespace ts.server { export const CompilerOptionsDiagnosticsFull = "compilerOptionsDiagnostics-full"; export const NameOrDottedNameSpan = "nameOrDottedNameSpan"; export const BreakpointStatement = "breakpointStatement"; + export const CompilerOptionsForInferredProjects = "compilerOptionsForInferredProjects"; } namespace Errors { @@ -502,6 +503,10 @@ namespace ts.server { } } + private setCompilerOptionsForInferredProjects(args: protocol.SetCompilerOptionsForInferredProjectsArgs): void { + this.projectService.setCompilerOptionsForInferredProjects(args.options); + } + private getProjectInfo(args: protocol.ProjectInfoRequestArgs): protocol.ProjectInfo { return this.getProjectInfoWorker(args.file, args.projectFileName, args.needFileNameList); } @@ -1433,6 +1438,9 @@ namespace ts.server { [CommandNames.DocumentHighlightsFull]: (request: protocol.DocumentHighlightsRequest) => { return this.requiredResponse(this.getDocumentHighlights(request.arguments, /*simplifiedResult*/ false)); }, + [CommandNames.CompilerOptionsForInferredProjects]: (request: protocol.SetCompilerOptionsForInferredProjectsRequest) => { + return this.requiredResponse(this.setCompilerOptionsForInferredProjects(request.arguments)); + }, [CommandNames.ProjectInfo]: (request: protocol.ProjectInfoRequest) => { return this.requiredResponse(this.getProjectInfo(request.arguments)); },