Add disableReferencedProjectLoad to stop loading child projects to allow users to disable loading large solutions (#39593)

* Use disableReferencedProjectLoad to stop loading child projects to allow users to disable loading large solutions
Fixes #39144

* Handle indirect references

* PR feedback
This commit is contained in:
Sheetal Nandi 2020-07-21 14:24:15 -07:00 committed by GitHub
parent 5484687384
commit e92afacc44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 302 additions and 66 deletions

View File

@ -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",

View File

@ -4469,6 +4469,10 @@
"category": "Error",
"code": 6234
},
"Disable loading referenced projects.": {
"category": "Message",
"code": 6235
},
"Projects to reference": {
"category": "Message",

View File

@ -5671,6 +5671,7 @@ namespace ts {
disableSizeLimit?: boolean;
disableSourceOfProjectReferenceRedirect?: boolean;
disableSolutionSearching?: boolean;
disableReferencedProjectLoad?: boolean;
downlevelIteration?: boolean;
emitBOM?: boolean;
emitDecoratorMetadata?: boolean;

View File

@ -432,34 +432,55 @@ namespace ts.server {
/*@internal*/
export function forEachResolvedProjectReferenceProject<T>(
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<T>(
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<T>(
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<string, ProjectReferenceProjectLoadKind> | 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<T>(openFiles: ESMap<Path, T>, delayReload: boolean, shouldReloadProjectFor: (openFileValue: T) => boolean, reason: string) {
const updatedProjects = new Map<string, true>();
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`
);
}
else {
// Create ancestor configured project
this.createAncestorProjects(info, defaultConfigProject || project);
// 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 {
// Since the file isnt part of configured project, do not send config file info
configFileName = undefined;
}
// Create ancestor configured project
this.createAncestorProjects(info, project);
}
}

View File

@ -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;
}

View File

@ -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) {

View File

@ -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", () => {

View File

@ -2762,6 +2762,7 @@ declare namespace ts {
disableSizeLimit?: boolean;
disableSourceOfProjectReferenceRedirect?: boolean;
disableSolutionSearching?: boolean;
disableReferencedProjectLoad?: boolean;
downlevelIteration?: boolean;
emitBOM?: boolean;
emitDecoratorMetadata?: boolean;

View File

@ -2762,6 +2762,7 @@ declare namespace ts {
disableSizeLimit?: boolean;
disableSourceOfProjectReferenceRedirect?: boolean;
disableSolutionSearching?: boolean;
disableReferencedProjectLoad?: boolean;
downlevelIteration?: boolean;
emitBOM?: boolean;
emitDecoratorMetadata?: boolean;

View File

@ -0,0 +1,5 @@
{
"compilerOptions": {
"disableReferencedProjectLoad": true
}
}