Skip to content

Commit ac2e122

Browse files
authored
Make builder not depend on information from dts emit about really needed modules (#57800)
1 parent 37fa47e commit ac2e122

File tree

440 files changed

+2448
-6699
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

440 files changed

+2448
-6699
lines changed

src/compiler/builder.ts

Lines changed: 8 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ import {
5858
isNumber,
5959
isString,
6060
map,
61-
mapDefined,
6261
maybeBind,
6362
noop,
6463
notImplemented,
@@ -73,6 +72,7 @@ import {
7372
returnUndefined,
7473
sameMap,
7574
SemanticDiagnosticsBuilderProgram,
75+
SignatureInfo,
7676
skipTypeChecking,
7777
SourceFile,
7878
sourceFileMayBeEmitted,
@@ -242,8 +242,6 @@ export interface BuilderProgramState extends BuilderState, ReusableBuilderProgra
242242
* Already seen emitted files
243243
*/
244244
seenEmittedFiles: Map<Path, BuilderFileEmit> | undefined;
245-
/** Stores list of files that change signature during emit - test only */
246-
filesChangingSignature?: Set<Path>;
247245
}
248246

249247
/** @internal */
@@ -633,7 +631,6 @@ function getNextAffectedFile(
633631
state.currentChangedFilePath = undefined;
634632
// Commit the changes in file signature
635633
state.oldSignatures?.clear();
636-
state.oldExportedModulesMap?.clear();
637634
state.affectedFiles = undefined;
638635
}
639636

@@ -845,7 +842,7 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
845842
) {
846843
// If there was change in signature (dts output) for the changed file,
847844
// then only we need to handle pending file emit
848-
if (!state.exportedModulesMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) return;
845+
if (!state.referencedMap || !state.changedFilesSet.has(affectedFile.resolvedPath)) return;
849846
if (!isChangedSignature(state, affectedFile.resolvedPath)) return;
850847

851848
// Since isolated modules dont change js files, files affected by change in signature is itself
@@ -869,9 +866,8 @@ function handleDtsMayChangeOfReferencingExportOfAffectedFile(
869866
}
870867

871868
const seenFileAndExportsOfFile = new Set<string>();
872-
// Go through exported modules from cache first
873-
// If exported modules has path, all files referencing file exported from are affected
874-
state.exportedModulesMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath => {
869+
// Go through files that reference affected file and handle dts emit and semantic diagnostics for them and their references
870+
state.referencedMap.getKeys(affectedFile.resolvedPath)?.forEach(exportedFromPath => {
875871
if (handleDtsMayChangeOfGlobalScope(state, exportedFromPath, cancellationToken, host)) return true;
876872
const references = state.referencedMap!.getKeys(exportedFromPath);
877873
return references && forEachKey(references, filePath =>
@@ -901,23 +897,12 @@ function handleDtsMayChangeOfFileAndExportsOfFile(
901897
if (handleDtsMayChangeOfGlobalScope(state, filePath, cancellationToken, host)) return true;
902898
handleDtsMayChangeOf(state, filePath, cancellationToken, host);
903899

904-
// If exported modules has path, all files referencing file exported from are affected
905-
state.exportedModulesMap!.getKeys(filePath)?.forEach(exportedFromPath =>
906-
handleDtsMayChangeOfFileAndExportsOfFile(
907-
state,
908-
exportedFromPath,
909-
seenFileAndExportsOfFile,
910-
cancellationToken,
911-
host,
912-
)
913-
);
914-
915-
// Remove diagnostics of files that import this file (without going to exports of referencing files)
900+
// Remove the diagnostics of files that import this file and handle all its exports too
916901
state.referencedMap!.getKeys(filePath)?.forEach(referencingFilePath =>
917-
!seenFileAndExportsOfFile.has(referencingFilePath) && // Not already removed diagnostic file
918-
handleDtsMayChangeOf( // Dont add to seen since this is not yet done with the export removal
902+
handleDtsMayChangeOfFileAndExportsOfFile(
919903
state,
920904
referencingFilePath,
905+
seenFileAndExportsOfFile,
921906
cancellationToken,
922907
host,
923908
)
@@ -1012,7 +997,6 @@ export interface ProgramMultiFileEmitBuildInfo {
1012997
options: CompilerOptions | undefined;
1013998
fileIdsList: readonly (readonly ProgramBuildInfoFileId[])[] | undefined;
1014999
referencedMap: ProgramBuildInfoReferencedMap | undefined;
1015-
exportedModulesMap: ProgramBuildInfoReferencedMap | undefined;
10161000
semanticDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
10171001
emitDiagnosticsPerFile: ProgramBuildInfoDiagnostic[] | undefined;
10181002
affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
@@ -1139,17 +1123,6 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
11391123
]);
11401124
}
11411125

1142-
let exportedModulesMap: ProgramBuildInfoReferencedMap | undefined;
1143-
if (state.exportedModulesMap) {
1144-
exportedModulesMap = mapDefined(arrayFrom(state.exportedModulesMap.keys()).sort(compareStringsCaseSensitive), key => {
1145-
const oldValue = state.oldExportedModulesMap?.get(key);
1146-
// Not in temporary cache, use existing value
1147-
if (oldValue === undefined) return [toFileId(key), toFileIdListId(state.exportedModulesMap!.getValues(key)!)];
1148-
if (oldValue) return [toFileId(key), toFileIdListId(oldValue)];
1149-
return undefined;
1150-
});
1151-
}
1152-
11531126
const semanticDiagnosticsPerFile = convertToProgramBuildInfoDiagnostics(state.semanticDiagnosticsPerFile);
11541127
let affectedFilesPendingEmit: ProgramBuilderInfoFilePendingEmit[] | undefined;
11551128
if (state.affectedFilesPendingEmit?.size) {
@@ -1185,7 +1158,6 @@ function getBuildInfo(state: BuilderProgramState): BuildInfo {
11851158
options: convertToProgramBuildInfoCompilerOptions(state.compilerOptions),
11861159
fileIdsList,
11871160
referencedMap,
1188-
exportedModulesMap,
11891161
semanticDiagnosticsPerFile,
11901162
emitDiagnosticsPerFile,
11911163
affectedFilesPendingEmit,
@@ -1602,8 +1574,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
16021574
// With d.ts diagnostics they are also part of the signature so emitSignature will be different from it since its just hash of d.ts
16031575
if (!data?.diagnostics?.length) emitSignature = signature;
16041576
if (signature !== file.version) { // Update it
1605-
if (host.storeFilesChangingSignatureDuringEmit) (state.filesChangingSignature ??= new Set()).add(file.resolvedPath);
1606-
if (state.exportedModulesMap) BuilderState.updateExportedModules(state, file, file.exportedModulesFromDeclarationEmit);
1577+
if (host.storeSignatureInfo) (state.signatureInfo ??= new Map()).set(file.resolvedPath, SignatureInfo.StoredSignatureAtEmit);
16071578
if (state.affectedFiles) {
16081579
// Keep old signature so we know what to undo if cancellation happens
16091580
const existing = state.oldSignatures?.get(file.resolvedPath);
@@ -1613,7 +1584,6 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
16131584
else {
16141585
// These are directly committed
16151586
info.signature = signature;
1616-
state.oldExportedModulesMap?.clear();
16171587
}
16181588
}
16191589
}
@@ -1862,7 +1832,6 @@ export function createBuilderProgramUsingProgramBuildInfo(buildInfo: BuildInfo,
18621832
fileInfos,
18631833
compilerOptions: program.options ? convertToOptionsWithAbsolutePaths(program.options, toAbsolutePath) : {},
18641834
referencedMap: toManyToManyPathMap(program.referencedMap),
1865-
exportedModulesMap: toManyToManyPathMap(program.exportedModulesMap),
18661835
semanticDiagnosticsPerFile: toPerFileDiagnostics(program.semanticDiagnosticsPerFile),
18671836
emitDiagnosticsPerFile: toPerFileDiagnostics(program.emitDiagnosticsPerFile),
18681837
hasReusableDiagnostic: true,

src/compiler/builderPublic.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ export interface BuilderProgramHost {
3131
*/
3232
writeFile?: WriteFileCallback;
3333
/**
34-
* Store the list of files that update signature during the emit
34+
* Store information about the signature
3535
*
3636
* @internal
3737
*/
38-
storeFilesChangingSignatureDuringEmit?: boolean;
38+
storeSignatureInfo?: boolean;
3939
}
4040

4141
/** @internal */
42-
export type HostForComputeHash = Pick<BuilderProgramHost, "createHash">;
42+
export type HostForComputeHash = Pick<BuilderProgramHost, "createHash" | "storeSignatureInfo">;
4343

4444
/**
4545
* Builder to manage the program state changes

src/compiler/builderState.ts

Lines changed: 11 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
Debug,
77
EmitOutput,
88
emptyArray,
9-
ExportedModulesFromDeclarationEmit,
109
GetCanonicalFileName,
1110
getDirectoryPath,
1211
getIsolatedModules,
@@ -52,6 +51,12 @@ export function getFileEmitOutput(
5251
}
5352
}
5453
/** @internal */
54+
export enum SignatureInfo {
55+
ComputedDts,
56+
StoredSignatureAtEmit,
57+
UsedVersion,
58+
}
59+
/** @internal */
5560
export interface BuilderState {
5661
/**
5762
* Information of the file eg. its version, signature etc
@@ -63,14 +68,6 @@ export interface BuilderState {
6368
* Thus non undefined value indicates, module emit
6469
*/
6570
readonly referencedMap?: BuilderState.ReadonlyManyToManyPathMap | undefined;
66-
/**
67-
* Contains the map of exported modules ReferencedSet=exported module files from the file if module emit is enabled
68-
* Otherwise undefined
69-
*
70-
* This is equivalent to referencedMap, but for the emitted .d.ts file.
71-
*/
72-
readonly exportedModulesMap?: BuilderState.ManyToManyPathMap | undefined;
73-
7471
/**
7572
* true if file version is used as signature
7673
* This helps in delaying the calculation of the d.ts hash as version for the file till reasonable time
@@ -86,10 +83,6 @@ export interface BuilderState {
8683
* Stores signatures before before the update till affected file is committed
8784
*/
8885
oldSignatures?: Map<Path, string | false>;
89-
/**
90-
* Stores exportedModulesMap before the update till affected file is committed
91-
*/
92-
oldExportedModulesMap?: Map<Path, ReadonlySet<Path> | false>;
9386
/**
9487
* Cache of all files excluding default library file for the current program
9588
*/
@@ -98,6 +91,8 @@ export interface BuilderState {
9891
* Cache of all the file names
9992
*/
10093
allFileNames?: readonly string[];
94+
/** Information about the signature computation - test only */
95+
signatureInfo?: Map<Path, SignatureInfo>;
10196
}
10297
/** @internal */
10398
export namespace BuilderState {
@@ -306,7 +301,6 @@ export namespace BuilderState {
306301
const isOutFile = options.outFile;
307302
const referencedMap = options.module !== ModuleKind.None && !isOutFile ?
308303
createManyToManyPathMap() : undefined;
309-
const exportedModulesMap = referencedMap ? createManyToManyPathMap() : undefined;
310304
const useOldState = canReuseOldState(referencedMap, oldState);
311305

312306
// Ensure source files have parent pointers set
@@ -324,16 +318,6 @@ export namespace BuilderState {
324318
if (newReferences) {
325319
referencedMap.set(sourceFile.resolvedPath, newReferences);
326320
}
327-
// Copy old visible to outside files map
328-
if (useOldState) {
329-
const oldUncommittedExportedModules = oldState!.oldExportedModulesMap?.get(sourceFile.resolvedPath);
330-
const exportedModules = oldUncommittedExportedModules === undefined ?
331-
oldState!.exportedModulesMap!.getValues(sourceFile.resolvedPath) :
332-
oldUncommittedExportedModules || undefined;
333-
if (exportedModules) {
334-
exportedModulesMap!.set(sourceFile.resolvedPath, exportedModules);
335-
}
336-
}
337321
}
338322
fileInfos.set(sourceFile.resolvedPath, {
339323
version,
@@ -347,7 +331,6 @@ export namespace BuilderState {
347331
return {
348332
fileInfos,
349333
referencedMap,
350-
exportedModulesMap,
351334
useFileVersionAsSignature: !disableUseFileVersionAsSignature && !useOldState,
352335
};
353336
}
@@ -378,7 +361,6 @@ export namespace BuilderState {
378361
host,
379362
);
380363
state.oldSignatures?.clear();
381-
state.oldExportedModulesMap?.clear();
382364
return result;
383365
}
384366

@@ -453,60 +435,22 @@ export namespace BuilderState {
453435
const prevSignature = info.signature;
454436
let latestSignature: string | undefined;
455437
if (!sourceFile.isDeclarationFile && !useFileVersionAsSignature) {
456-
computeDtsSignature(programOfThisState, sourceFile, cancellationToken, host, (signature, sourceFiles) => {
438+
computeDtsSignature(programOfThisState, sourceFile, cancellationToken, host, signature => {
457439
latestSignature = signature;
458-
if (latestSignature !== prevSignature) {
459-
updateExportedModules(state, sourceFile, sourceFiles[0].exportedModulesFromDeclarationEmit);
460-
}
440+
if (host.storeSignatureInfo) (state.signatureInfo ??= new Map()).set(sourceFile.resolvedPath, SignatureInfo.ComputedDts);
461441
});
462442
}
463443
// Default is to use file version as signature
464444
if (latestSignature === undefined) {
465445
latestSignature = sourceFile.version;
466-
if (state.exportedModulesMap && latestSignature !== prevSignature) {
467-
(state.oldExportedModulesMap ||= new Map()).set(sourceFile.resolvedPath, state.exportedModulesMap.getValues(sourceFile.resolvedPath) || false);
468-
// All the references in this file are exported
469-
const references = state.referencedMap ? state.referencedMap.getValues(sourceFile.resolvedPath) : undefined;
470-
if (references) {
471-
state.exportedModulesMap.set(sourceFile.resolvedPath, references);
472-
}
473-
else {
474-
state.exportedModulesMap.deleteKey(sourceFile.resolvedPath);
475-
}
476-
}
446+
if (host.storeSignatureInfo) (state.signatureInfo ??= new Map()).set(sourceFile.resolvedPath, SignatureInfo.UsedVersion);
477447
}
478448
(state.oldSignatures ||= new Map()).set(sourceFile.resolvedPath, prevSignature || false);
479449
(state.hasCalledUpdateShapeSignature ||= new Set()).add(sourceFile.resolvedPath);
480450
info.signature = latestSignature;
481451
return latestSignature !== prevSignature;
482452
}
483453

484-
/**
485-
* Coverts the declaration emit result into exported modules map
486-
*/
487-
export function updateExportedModules(state: BuilderState, sourceFile: SourceFile, exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined) {
488-
if (!state.exportedModulesMap) return;
489-
(state.oldExportedModulesMap ||= new Map()).set(sourceFile.resolvedPath, state.exportedModulesMap.getValues(sourceFile.resolvedPath) || false);
490-
const exportedModules = getExportedModules(exportedModulesFromDeclarationEmit);
491-
if (exportedModules) {
492-
state.exportedModulesMap.set(sourceFile.resolvedPath, exportedModules);
493-
}
494-
else {
495-
state.exportedModulesMap.deleteKey(sourceFile.resolvedPath);
496-
}
497-
}
498-
499-
export function getExportedModules(exportedModulesFromDeclarationEmit: ExportedModulesFromDeclarationEmit | undefined) {
500-
let exportedModules: Set<Path> | undefined;
501-
exportedModulesFromDeclarationEmit?.forEach(
502-
symbol =>
503-
getReferencedFilesFromImportedModuleSymbol(symbol).forEach(
504-
path => (exportedModules ??= new Set()).add(path),
505-
),
506-
);
507-
return exportedModules;
508-
}
509-
510454
/**
511455
* Get all the dependencies of the sourceFile
512456
*/

src/compiler/sys.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1458,7 +1458,7 @@ export interface System {
14581458

14591459
// For testing
14601460
/** @internal */ now?(): Date;
1461-
/** @internal */ storeFilesChangingSignatureDuringEmit?: boolean;
1461+
/** @internal */ storeSignatureInfo?: boolean;
14621462
}
14631463

14641464
export interface FileWatcher {

src/compiler/transformers/declarations.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -532,9 +532,7 @@ export function transformDeclarations(context: TransformationContext) {
532532
combinedStatements = setTextRange(factory.createNodeArray([...combinedStatements, createEmptyExports(factory)]), combinedStatements);
533533
}
534534
}
535-
const updated = factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
536-
updated.exportedModulesFromDeclarationEmit = exportedModulesFromDeclarationEmit;
537-
return updated;
535+
return factory.updateSourceFile(node, combinedStatements, /*isDeclarationFile*/ true, references, getFileReferencesForUsedTypeReferences(), node.hasNoDefaultLib, getLibReferences());
538536

539537
function getLibReferences() {
540538
return arrayFrom(libs.keys(), lib => ({ fileName: lib, pos: -1, end: -1 }));

src/compiler/types.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,7 +4326,6 @@ export interface SourceFile extends Declaration, LocalsContainer {
43264326
/** @internal */ localJsxFactory?: EntityName;
43274327
/** @internal */ localJsxFragmentFactory?: EntityName;
43284328

4329-
/** @internal */ exportedModulesFromDeclarationEmit?: ExportedModulesFromDeclarationEmit;
43304329
/** @internal */ endFlowNode?: FlowNode;
43314330

43324331
/** @internal */ jsDocParsingMode?: JSDocParsingMode;
@@ -4369,9 +4368,6 @@ export const enum CommentDirectiveType {
43694368
Ignore,
43704369
}
43714370

4372-
/** @internal */
4373-
export type ExportedModulesFromDeclarationEmit = readonly Symbol[];
4374-
43754371
export interface Bundle extends Node {
43764372
readonly kind: SyntaxKind.Bundle;
43774373
readonly sourceFiles: readonly SourceFile[];
@@ -7799,7 +7795,7 @@ export interface CompilerHost extends ModuleResolutionHost {
77997795
/** @internal */ getSymlinkCache?(): SymlinkCache;
78007796

78017797
// For testing:
7802-
/** @internal */ storeFilesChangingSignatureDuringEmit?: boolean;
7798+
/** @internal */ storeSignatureInfo?: boolean;
78037799
/** @internal */ getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined;
78047800

78057801
jsDocParsingMode?: JSDocParsingMode;

src/compiler/watch.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,7 @@ export function createCompilerHostFromProgramHost(host: ProgramHost<any>, getCom
765765
getEnvironmentVariable: maybeBind(host, host.getEnvironmentVariable) || (() => ""),
766766
createHash: maybeBind(host, host.createHash),
767767
readDirectory: maybeBind(host, host.readDirectory),
768-
storeFilesChangingSignatureDuringEmit: host.storeFilesChangingSignatureDuringEmit,
768+
storeSignatureInfo: host.storeSignatureInfo,
769769
jsDocParsingMode: host.jsDocParsingMode,
770770
};
771771
return compilerHost;
@@ -847,7 +847,7 @@ export function createProgramHost<T extends BuilderProgram = EmitAndSemanticDiag
847847
writeFile: (path, data, writeByteOrderMark) => system.writeFile(path, data, writeByteOrderMark),
848848
createHash: maybeBind(system, system.createHash),
849849
createProgram: createProgram || createEmitAndSemanticDiagnosticsBuilderProgram as any as CreateProgram<T>,
850-
storeFilesChangingSignatureDuringEmit: system.storeFilesChangingSignatureDuringEmit,
850+
storeSignatureInfo: system.storeSignatureInfo,
851851
now: maybeBind(system, system.now),
852852
};
853853
}

0 commit comments

Comments
 (0)