diff --git a/src/compiler/commandLineParser.ts b/src/compiler/commandLineParser.ts index f5cb2990a593a..26b8641e2d753 100644 --- a/src/compiler/commandLineParser.ts +++ b/src/compiler/commandLineParser.ts @@ -882,6 +882,13 @@ namespace ts { category: Diagnostics.Advanced_Options, description: Diagnostics.Disable_solution_searching_for_this_project }, + { + name: "disableReferencedProjectLoad", + type: "boolean", + isTSConfigOnly: true, + category: Diagnostics.Advanced_Options, + description: Diagnostics.Disable_loading_referenced_projects + }, { name: "noImplicitUseStrict", type: "boolean", diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 5110ff2be8b72..d0d66f0f959b8 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -4469,6 +4469,10 @@ "category": "Error", "code": 6234 }, + "Disable loading referenced projects.": { + "category": "Message", + "code": 6235 + }, "Projects to reference": { "category": "Message", diff --git a/src/compiler/types.ts b/src/compiler/types.ts index 8f9445cd951e7..0db378efd7b36 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5671,6 +5671,7 @@ namespace ts { disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; disableSolutionSearching?: boolean; + disableReferencedProjectLoad?: boolean; downlevelIteration?: boolean; emitBOM?: boolean; emitDecoratorMetadata?: boolean; diff --git a/src/server/editorServices.ts b/src/server/editorServices.ts index a97d049f45bd8..669194b4e8981 100644 --- a/src/server/editorServices.ts +++ b/src/server/editorServices.ts @@ -432,34 +432,55 @@ namespace ts.server { /*@internal*/ export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, - cb: (child: ConfiguredProject, configFileName: NormalizedPath) => T | undefined, - projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.Find | ProjectReferenceProjectLoadKind.FindCreate + cb: (child: ConfiguredProject) => T | undefined, + projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.Find | ProjectReferenceProjectLoadKind.FindCreate, ): T | undefined; /*@internal*/ export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, - cb: (child: ConfiguredProject, configFileName: NormalizedPath) => T | undefined, - projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind.FindCreateLoad, + cb: (child: ConfiguredProject) => T | undefined, + projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind, reason: string ): T | undefined; export function forEachResolvedProjectReferenceProject( project: ConfiguredProject, - cb: (child: ConfiguredProject, configFileName: NormalizedPath) => T | undefined, + cb: (child: ConfiguredProject) => T | undefined, projectReferenceProjectLoadKind: ProjectReferenceProjectLoadKind, reason?: string ): T | undefined { - return forEachResolvedProjectReference(project, ref => { - if (!ref) return undefined; - const configFileName = toNormalizedPath(ref.sourceFile.fileName); - const child = project.projectService.findConfiguredProjectByProjectName(configFileName) || ( - projectReferenceProjectLoadKind === ProjectReferenceProjectLoadKind.FindCreate ? - project.projectService.createConfiguredProject(configFileName) : - projectReferenceProjectLoadKind === ProjectReferenceProjectLoadKind.FindCreateLoad ? - project.projectService.createAndLoadConfiguredProject(configFileName, reason!) : - undefined - ); - return child && cb(child, configFileName); - }); + let seenResolvedRefs: ESMap | undefined; + return worker(project.getCurrentProgram()?.getResolvedProjectReferences(), project.getCompilerOptions()); + + function worker(resolvedProjectReferences: readonly (ResolvedProjectReference | undefined)[] | undefined, parentOptions: CompilerOptions): T | undefined { + const loadKind = parentOptions.disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : projectReferenceProjectLoadKind; + return forEach(resolvedProjectReferences, ref => { + if (!ref) return undefined; + + const configFileName = toNormalizedPath(ref.sourceFile.fileName); + const canonicalPath = project.projectService.toCanonicalFileName(configFileName); + const seenValue = seenResolvedRefs?.get(canonicalPath); + if (seenValue !== undefined && seenValue >= loadKind) { + return undefined; + } + const child = project.projectService.findConfiguredProjectByProjectName(configFileName) || ( + loadKind === ProjectReferenceProjectLoadKind.Find ? + undefined : + loadKind === ProjectReferenceProjectLoadKind.FindCreate ? + project.projectService.createConfiguredProject(configFileName) : + loadKind === ProjectReferenceProjectLoadKind.FindCreateLoad ? + project.projectService.createAndLoadConfiguredProject(configFileName, reason!) : + Debug.assertNever(loadKind) + ); + + const result = child && cb(child); + if (result) { + return result; + } + + (seenResolvedRefs || (seenResolvedRefs = new Map())).set(canonicalPath, loadKind); + return worker(ref.references, ref.commandLine.options); + }); + } } /*@internal*/ @@ -2773,6 +2794,12 @@ namespace ts.server { */ private reloadConfiguredProjectForFiles(openFiles: ESMap, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean, reason: string) { const updatedProjects = new Map(); + const reloadChildProject = (child: ConfiguredProject) => { + if (!updatedProjects.has(child.canonicalConfigFilePath)) { + updatedProjects.set(child.canonicalConfigFilePath, true); + this.reloadConfiguredProject(child, reason); + } + }; // try to reload config file for all open files openFiles.forEach((openFileValue, path) => { // Filter out the files that need to be ignored @@ -2801,17 +2828,22 @@ namespace ts.server { this.reloadConfiguredProject(project, reason); // If this is solution, reload the project till the reloaded project contains the script info directly if (!project.containsScriptInfo(info) && project.isSolution()) { - forEachResolvedProjectReferenceProject( + const referencedProject = forEachResolvedProjectReferenceProject( project, child => { - if (!updatedProjects.has(child.canonicalConfigFilePath)) { - updatedProjects.set(child.canonicalConfigFilePath, true); - this.reloadConfiguredProject(child, reason); - } + reloadChildProject(child); return projectContainsInfoDirectly(child, info); }, ProjectReferenceProjectLoadKind.FindCreate ); + if (referencedProject) { + // Reload the project's tree that is already present + forEachResolvedProjectReferenceProject( + project, + reloadChildProject, + ProjectReferenceProjectLoadKind.Find + ); + } } } } @@ -2913,7 +2945,7 @@ namespace ts.server { const info = this.getScriptInfo(fileName); return info && projectContainsInfoDirectly(child, info) ? child : undefined; }, - ProjectReferenceProjectLoadKind.FindCreateLoad, + configuredProject.getCompilerOptions().disableReferencedProjectLoad ? ProjectReferenceProjectLoadKind.Find : ProjectReferenceProjectLoadKind.FindCreateLoad, `Creating project referenced in solution ${configuredProject.projectName} to find possible configured project for original file: ${originalFileInfo.fileName}${location !== originalLocation ? " for location: " + location.fileName : ""}` ); if (!configuredProject) return undefined; @@ -2965,8 +2997,9 @@ namespace ts.server { let configFileName: NormalizedPath | undefined; let configFileErrors: readonly Diagnostic[] | undefined; let project: ConfiguredProject | ExternalProject | undefined = this.findExternalProjectContainingOpenScriptInfo(info); - let defaultConfigProject: ConfiguredProject | undefined; let retainProjects: ConfiguredProject[] | ConfiguredProject | undefined; + let projectForConfigFileDiag: ConfiguredProject | undefined; + let defaultConfigProjectIsCreated = false; if (this.syntaxOnly) { // Invalidate resolutions in the file since this file is now open info.containingProjects.forEach(project => { @@ -2981,30 +3014,22 @@ namespace ts.server { project = this.findConfiguredProjectByProjectName(configFileName); if (!project) { project = this.createLoadAndUpdateConfiguredProject(configFileName, `Creating possible configured project for ${info.fileName} to open`); - // Send the event only if the project got created as part of this open request and info is part of the project - if (!project.containsScriptInfo(info)) { - // Since the file isnt part of configured project, do not send config file info - configFileName = undefined; - } - else { - configFileErrors = project.getAllProjectErrors(); - this.sendConfigFileDiagEvent(project, info.fileName); - } + defaultConfigProjectIsCreated = true; } else { // Ensure project is ready to check if it contains opened script info updateProjectIfDirty(project); } - defaultConfigProject = project; - retainProjects = defaultConfigProject; + projectForConfigFileDiag = project.containsScriptInfo(info) ? project : undefined; + retainProjects = project; // If this configured project doesnt contain script info but // it is solution with project references, try those project references - if (!project.containsScriptInfo(info) && project.isSolution()) { + if (project.isSolution()) { forEachResolvedProjectReferenceProject( project, - (child, childConfigFileName) => { + child => { updateProjectIfDirty(child); // Retain these projects if (!isArray(retainProjects)) { @@ -3016,20 +3041,35 @@ namespace ts.server { // If script info belongs to this child project, use this as default config project if (projectContainsInfoDirectly(child, info)) { - configFileName = childConfigFileName; - configFileErrors = child.getAllProjectErrors(); - this.sendConfigFileDiagEvent(child, info.fileName); + projectForConfigFileDiag = child; return child; } + + // If this project uses the script info (even through project reference), if default project is not found, use this for configFileDiag + if (!projectForConfigFileDiag && child.containsScriptInfo(info)) { + projectForConfigFileDiag = child; + } }, ProjectReferenceProjectLoadKind.FindCreateLoad, `Creating project referenced in solution ${project.projectName} to find possible configured project for ${info.fileName} to open` ); } + + // Send the event only if the project got created as part of this open request and info is part of the project + if (projectForConfigFileDiag) { + configFileName = projectForConfigFileDiag.getConfigFilePath(); + if (projectForConfigFileDiag !== project || defaultConfigProjectIsCreated) { + configFileErrors = projectForConfigFileDiag.getAllProjectErrors(); + this.sendConfigFileDiagEvent(projectForConfigFileDiag, info.fileName); + } + } else { - // Create ancestor configured project - this.createAncestorProjects(info, defaultConfigProject || project); + // Since the file isnt part of configured project, do not send config file info + configFileName = undefined; } + + // Create ancestor configured project + this.createAncestorProjects(info, project); } } diff --git a/src/server/project.ts b/src/server/project.ts index 413616f5667fa..f87b67505c213 100644 --- a/src/server/project.ts +++ b/src/server/project.ts @@ -2264,9 +2264,16 @@ namespace ts.server { // The project is referenced only if open files impacted by this project are present in this project return forEachEntry( configFileExistenceInfo.openFilesImpactedByConfigFile, - (_value, infoPath) => isSolution ? - !!this.getDefaultChildProjectFromSolution(this.projectService.getScriptInfoForPath(infoPath)!) : - this.containsScriptInfo(this.projectService.getScriptInfoForPath(infoPath)!) + (_value, infoPath) => { + const info = this.projectService.getScriptInfoForPath(infoPath)!; + return isSolution ? + !!forEachResolvedProjectReferenceProject( + this, + child => child.containsScriptInfo(info), + ProjectReferenceProjectLoadKind.Find + ) : + this.containsScriptInfo(info); + } ) || false; } diff --git a/src/testRunner/unittests/tsserver/helpers.ts b/src/testRunner/unittests/tsserver/helpers.ts index c79eee0b4227d..5ce4ed734fd68 100644 --- a/src/testRunner/unittests/tsserver/helpers.ts +++ b/src/testRunner/unittests/tsserver/helpers.ts @@ -449,11 +449,11 @@ namespace ts.projectSystem { } export function checkProjectActualFiles(project: server.Project, expectedFiles: readonly string[]) { - checkArray(`${server.ProjectKind[project.projectKind]} project, actual files`, project.getFileNames(), expectedFiles); + checkArray(`${server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}:: actual files`, project.getFileNames(), expectedFiles); } export function checkProjectRootFiles(project: server.Project, expectedFiles: readonly string[]) { - checkArray(`${server.ProjectKind[project.projectKind]} project, rootFileNames`, project.getRootFiles(), expectedFiles); + checkArray(`${server.ProjectKind[project.projectKind]} project: ${project.getProjectName()}::, rootFileNames`, project.getRootFiles(), expectedFiles); } export function mapCombinedPathsInAncestor(dir: string, path2: string, mapAncestor: (ancestor: string) => boolean) { diff --git a/src/testRunner/unittests/tsserver/projectReferences.ts b/src/testRunner/unittests/tsserver/projectReferences.ts index 8da081d82c1bf..c8629a743be6a 100644 --- a/src/testRunner/unittests/tsserver/projectReferences.ts +++ b/src/testRunner/unittests/tsserver/projectReferences.ts @@ -1825,11 +1825,14 @@ bar(); }); describe("when default project is solution project", () => { - interface VerifySolutionScenario { + interface Setup { + solutionOptions?: CompilerOptions; configRefs: string[]; additionalFiles: readonly File[]; - additionalProjects: readonly { projectName: string, files: readonly string[] }[]; expectedOpenEvents: protocol.Event[]; + } + interface VerifySolutionScenario extends Setup { + additionalProjects: readonly { projectName: string, files: readonly string[] }[]; expectedReloadEvents: protocol.Event[]; expectedReferences: protocol.ReferencesResponseBody; expectedReferencesFromDtsProject: protocol.ReferencesResponseBody; @@ -1877,11 +1880,8 @@ foo;` }; const tsconfigSrcPath = `${tscWatch.projectRoot}/tsconfig-src.json`; const tsconfigPath = `${tscWatch.projectRoot}/tsconfig.json`; - function verifySolutionScenario({ - configRefs, additionalFiles, additionalProjects, - expectedOpenEvents, expectedReloadEvents, - expectedReferences, expectedReferencesFromDtsProject - }: VerifySolutionScenario) { + const dummyFilePath = "/dummy/dummy.ts"; + function setup({ solutionOptions, configRefs, additionalFiles, expectedOpenEvents }: Setup) { const tsconfigSrc: File = { path: tsconfigSrcPath, content: JSON.stringify({ @@ -1896,12 +1896,13 @@ foo;` const tsconfig: File = { path: tsconfigPath, content: JSON.stringify({ + ... (solutionOptions ? { compilerOptions: solutionOptions } : {}), references: configRefs.map(path => ({ path })), files: [] }) }; const dummyFile: File = { - path: "/dummy/dummy.ts", + path: dummyFilePath, content: "let a = 10;" }; const host = createServerHost([ @@ -1913,8 +1914,17 @@ foo;` const session = createSession(host, { canUseEvents: true }); const service = session.getProjectService(); service.openClientFile(main.path); - verifyProjects(/*includeConfigured*/ true, /*includeDummy*/ false); checkEvents(session, expectedOpenEvents); + return { session, service, host, tsconfigSrc, tsconfig }; + } + + function verifySolutionScenario(input: VerifySolutionScenario) { + const { session, service, host, tsconfigSrc, tsconfig } = setup(input); + const { + additionalProjects, expectedReloadEvents, + expectedReferences, expectedReferencesFromDtsProject + } = input; + verifyProjects(/*includeConfigured*/ true, /*includeDummy*/ false); const info = service.getScriptInfoForPath(main.path as Path)!; const project = service.configuredProjects.get(tsconfigSrc.path)!; assert.equal(info.getDefaultProject(), project); @@ -1924,17 +1934,17 @@ foo;` verifyGetErrRequestNoErrors({ session, host, files: [main] }); // Verify collection of script infos - service.openClientFile(dummyFile.path); + service.openClientFile(dummyFilePath); verifyProjects(/*includeConfigured*/ true, /*includeDummy*/ true); service.closeClientFile(main.path); - service.closeClientFile(dummyFile.path); - service.openClientFile(dummyFile.path); + service.closeClientFile(dummyFilePath); + service.openClientFile(dummyFilePath); verifyProjects(/*includeConfigured*/ false, /*includeDummy*/ true); service.openClientFile(main.path); - service.closeClientFile(dummyFile.path); - service.openClientFile(dummyFile.path); + service.closeClientFile(dummyFilePath); + service.openClientFile(dummyFilePath); verifyProjects(/*includeConfigured*/ true, /*includeDummy*/ true); // Verify Reload projects @@ -1951,7 +1961,7 @@ foo;` assert.deepEqual(response, expectedReferences); service.closeClientFile(main.path); - service.closeClientFile(dummyFile.path); + service.closeClientFile(dummyFilePath); // Verify when declaration map references the file service.openClientFile(fileResolvingToMainDts.path); @@ -1976,7 +1986,7 @@ foo;` checkProjectActualFiles(service.configuredProjects.get(projectName)!, files)); } if (includeDummy) { - checkProjectActualFiles(service.inferredProjects[0], [dummyFile.path, libFile.path]); + checkProjectActualFiles(service.inferredProjects[0], [dummyFilePath, libFile.path]); } } } @@ -2061,14 +2071,15 @@ foo;` ]; } - function getIndirectProject(postfix: string) { + function getIndirectProject(postfix: string, optionsToExtend?: CompilerOptions) { const tsconfigIndirect: File = { path: `${tscWatch.projectRoot}/tsconfig-indirect${postfix}.json`, content: JSON.stringify({ compilerOptions: { composite: true, outDir: "./target/", - baseUrl: "./src/" + baseUrl: "./src/", + ...optionsToExtend }, files: [`./indirect${postfix}/main.ts`], references: [{ path: "./tsconfig-src.json" }] @@ -2081,6 +2092,66 @@ foo;` return { tsconfigIndirect, indirect }; } + interface VerifyProjects { + configuredProjects: readonly { projectName: string, files: readonly string[] }[]; + inferredProjects: readonly (readonly string[])[]; + } + + interface VerifyDisableReferencedProjectLoad extends Setup { + expectedProjectsOnOpen: VerifyProjects; + expectedProjectsOnDummyOpen?: VerifyProjects; + expectedProjectsOnReload?: VerifyProjects; + expectedDefaultProject: (service: server.ProjectService) => server.Project; + expectedDefaultConfiguredProject: (service: server.ProjectService) => server.ConfiguredProject | undefined; + expectedReloadEvents: protocol.Event[]; + } + + function verifyDisableReferencedProjectLoad(input: VerifyDisableReferencedProjectLoad) { + const { session, service } = setup(input); + const { expectedProjectsOnOpen, expectedDefaultProject, expectedDefaultConfiguredProject, expectedReloadEvents } = input; + const expectedProjectsOnOnlyDummy: VerifyProjects = { + configuredProjects: emptyArray, + inferredProjects: [ + [dummyFilePath, libFile.path], + ] + }; + const expectedProjectsOnDummyOpen = input.expectedProjectsOnDummyOpen || { + configuredProjects: expectedProjectsOnOpen.configuredProjects, + inferredProjects: expectedProjectsOnOnlyDummy.inferredProjects, + }; + const expectedProjectsOnReload = input.expectedProjectsOnReload || expectedProjectsOnDummyOpen; + + verifyProjects(expectedProjectsOnOpen); + const info = service.getScriptInfoForPath(main.path as Path)!; + assert.equal(info.getDefaultProject(), expectedDefaultProject(service)); + assert.equal(service.findDefaultConfiguredProject(info), expectedDefaultConfiguredProject(service)); + + // Verify collection of script infos + service.openClientFile(dummyFilePath); + verifyProjects(expectedProjectsOnDummyOpen); + + service.closeClientFile(main.path); + service.closeClientFile(dummyFilePath); + service.openClientFile(dummyFilePath); + verifyProjects(expectedProjectsOnOnlyDummy); + + service.openClientFile(main.path); + + // Verify Reload projects + session.clearMessages(); + service.reloadProjects(); + checkEvents(session, expectedReloadEvents); + verifyProjects(expectedProjectsOnReload); + + function verifyProjects(expected: VerifyProjects) { + checkNumberOfProjects(service, { configuredProjects: expected.configuredProjects.length, inferredProjects: expected.inferredProjects.length }); + expected.configuredProjects.forEach(({ projectName, files }) => + checkProjectActualFiles(service.configuredProjects.get(projectName)!, files)); + expected.inferredProjects.forEach((files, index) => + checkProjectActualFiles(service.inferredProjects[index], files)); + } + } + it("when project is directly referenced by solution", () => { const expectedReferences = expectedReferencesResponse(); verifySolutionScenario({ @@ -2150,6 +2221,105 @@ foo;` } }); }); + + it("disables looking into the child project if disableReferencedProjectLoad is set", () => { + const expectedProjectsOnOpen: VerifyProjects = { + configuredProjects: [ + { projectName: tsconfigPath, files: [tsconfigPath] }, + ], + inferredProjects: [ + [main.path, libFile.path], + ] + }; + verifyDisableReferencedProjectLoad({ + solutionOptions: { disableReferencedProjectLoad: true }, + configRefs: ["./tsconfig-src.json"], + additionalFiles: emptyArray, + expectedOpenEvents: [ + ...expectedSolutionLoadAndTelemetry(), + configFileDiagEvent(main.path, tsconfigPath, []) + ], + expectedDefaultProject: service => service.inferredProjects[0], + expectedDefaultConfiguredProject: returnUndefined, + expectedProjectsOnOpen, + expectedProjectsOnDummyOpen: { + configuredProjects: emptyArray, + inferredProjects: [ + ...expectedProjectsOnOpen.inferredProjects, + [dummyFilePath, libFile.path], + ] + }, + expectedProjectsOnReload: { + configuredProjects: expectedProjectsOnOpen.configuredProjects, + inferredProjects: [ + [dummyFilePath, libFile.path], + ...expectedProjectsOnOpen.inferredProjects, + ] + }, + expectedReloadEvents: expectedReloadEvent(tsconfigPath) + }); + }); + + it("disables looking into the child project if disableReferencedProjectLoad is set in indirect project", () => { + const { tsconfigIndirect, indirect } = getIndirectProject("1", { disableReferencedProjectLoad: true }); + const expectedProjectsOnOpen: VerifyProjects = { + configuredProjects: [ + { projectName: tsconfigPath, files: [tsconfigPath] }, + { projectName: tsconfigIndirect.path, files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] }, + ], + inferredProjects: emptyArray + }; + verifyDisableReferencedProjectLoad({ + configRefs: ["./tsconfig-indirect1.json"], + additionalFiles: [tsconfigIndirect, indirect], + expectedOpenEvents: [ + ...expectedSolutionLoadAndTelemetry(), + ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), + configFileDiagEvent(main.path, tsconfigIndirect.path, []) + ], + expectedDefaultProject: service => service.configuredProjects.get(tsconfigIndirect.path)!, + expectedDefaultConfiguredProject: returnUndefined, + expectedProjectsOnOpen, + expectedReloadEvents: [ + ...expectedReloadEvent(tsconfigPath), + ...expectedReloadEvent(tsconfigIndirect.path), + ] + }); + }); + + it("disables looking into the child project if disableReferencedProjectLoad is set in first indirect project but not in another one", () => { + const { tsconfigIndirect, indirect } = getIndirectProject("1", { disableReferencedProjectLoad: true }); + const { tsconfigIndirect: tsconfigIndirect2, indirect: indirect2 } = getIndirectProject("2"); + const expectedProjectsOnOpen: VerifyProjects = { + configuredProjects: [ + { projectName: tsconfigPath, files: [tsconfigPath] }, + { projectName: tsconfigIndirect.path, files: [tsconfigIndirect.path, main.path, helper.path, indirect.path, libFile.path] }, + { projectName: tsconfigIndirect2.path, files: [tsconfigIndirect2.path, main.path, helper.path, indirect2.path, libFile.path] }, + { projectName: tsconfigSrcPath, files: [tsconfigSrcPath, main.path, helper.path, libFile.path] }, + ], + inferredProjects: emptyArray + }; + verifyDisableReferencedProjectLoad({ + configRefs: ["./tsconfig-indirect1.json", "./tsconfig-indirect2.json"], + additionalFiles: [tsconfigIndirect, indirect, tsconfigIndirect2, indirect2], + expectedOpenEvents: [ + ...expectedSolutionLoadAndTelemetry(), + ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect.path), + ...expectedProjectReferenceLoadAndTelemetry(tsconfigIndirect2.path), + ...expectedProjectReferenceLoadAndTelemetry(tsconfigSrcPath), + configFileDiagEvent(main.path, tsconfigSrcPath, []) + ], + expectedDefaultProject: service => service.configuredProjects.get(tsconfigSrcPath)!, + expectedDefaultConfiguredProject: service => service.configuredProjects.get(tsconfigSrcPath)!, + expectedProjectsOnOpen, + expectedReloadEvents: [ + ...expectedReloadEvent(tsconfigPath), + ...expectedReloadEvent(tsconfigIndirect.path), + ...expectedReloadEvent(tsconfigSrcPath), + ...expectedReloadEvent(tsconfigIndirect2.path), + ] + }); + }); }); describe("auto import with referenced project", () => { diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 8442b93e4f686..7989218091bee 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2762,6 +2762,7 @@ declare namespace ts { disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; disableSolutionSearching?: boolean; + disableReferencedProjectLoad?: boolean; downlevelIteration?: boolean; emitBOM?: boolean; emitDecoratorMetadata?: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index 3f7f682342456..76296ad0927b8 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2762,6 +2762,7 @@ declare namespace ts { disableSizeLimit?: boolean; disableSourceOfProjectReferenceRedirect?: boolean; disableSolutionSearching?: boolean; + disableReferencedProjectLoad?: boolean; downlevelIteration?: boolean; emitBOM?: boolean; emitDecoratorMetadata?: boolean; diff --git a/tests/baselines/reference/showConfig/Shows tsconfig for single option/disableReferencedProjectLoad/tsconfig.json b/tests/baselines/reference/showConfig/Shows tsconfig for single option/disableReferencedProjectLoad/tsconfig.json new file mode 100644 index 0000000000000..bae4ab86838bf --- /dev/null +++ b/tests/baselines/reference/showConfig/Shows tsconfig for single option/disableReferencedProjectLoad/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "disableReferencedProjectLoad": true + } +}