Skip to content

Commit 0f7903d

Browse files
committed
Reconcile reusable builder state and builder state so there are not two different types that are almost similar looking
1 parent d8d8609 commit 0f7903d

File tree

2 files changed

+33
-93
lines changed

2 files changed

+33
-93
lines changed

src/compiler/builder.ts

+24-62
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ namespace ts {
2020

2121
export type ReusableDiagnosticMessageChain = DiagnosticMessageChain;
2222

23-
export interface ReusableBuilderProgramState extends ReusableBuilderState {
23+
export interface ReusableBuilderProgramState extends BuilderState {
2424
/**
2525
* Cache of bind and check diagnostics for files with their Path being the key
2626
*/
27-
semanticDiagnosticsPerFile?: ReadonlyESMap<Path, readonly ReusableDiagnostic[] | readonly Diagnostic[]> | undefined;
27+
semanticDiagnosticsPerFile?: ESMap<Path, readonly ReusableDiagnostic[] | readonly Diagnostic[]> | undefined;
2828
/**
2929
* The map has key by source file's path that has been changed
3030
*/
31-
changedFilesSet: ReadonlySet<Path>;
31+
changedFilesSet: Set<Path>;
3232
/**
3333
* Set of affected files being iterated
3434
*/
@@ -41,11 +41,11 @@ namespace ts {
4141
* Map of file signatures, with key being file path, calculated while getting current changed file's affected files
4242
* These will be committed whenever the iteration through affected files of current changed file is complete
4343
*/
44-
currentAffectedFilesSignatures?: ReadonlyESMap<Path, string> | undefined;
44+
currentAffectedFilesSignatures?: ESMap<Path, string> | undefined;
4545
/**
4646
* Newly computed visible to outside referencedSet
4747
*/
48-
currentAffectedFilesExportedModulesMap?: BuilderState.ReadonlyManyToManyPathMap | undefined;
48+
currentAffectedFilesExportedModulesMap?: BuilderState.ManyToManyPathMap | undefined;
4949
/**
5050
* True if the semantic diagnostics were copied from the old state
5151
*/
@@ -65,7 +65,7 @@ namespace ts {
6565
/**
6666
* Files pending to be emitted kind.
6767
*/
68-
affectedFilesPendingEmitKind?: ReadonlyESMap<Path, BuilderFileEmit> | undefined;
68+
affectedFilesPendingEmitKind?: ESMap<Path, BuilderFileEmit> | undefined;
6969
/**
7070
* Current index to retrieve pending affected file
7171
*/
@@ -74,11 +74,18 @@ namespace ts {
7474
* true if semantic diagnostics are ReusableDiagnostic instead of Diagnostic
7575
*/
7676
hasReusableDiagnostic?: true;
77-
78-
emitSignatures?: ReadonlyESMap<Path, string>;
77+
/**
78+
* Hash of d.ts emitted for the file, use to track when emit of d.ts changes
79+
*/
80+
emitSignatures?: ESMap<Path, string>;
81+
/**
82+
* Hash of d.ts emit with --out
83+
*/
7984
outSignature?: string;
85+
/**
86+
* Time when d.ts was modified
87+
*/
8088
dtsChangeTime: number | undefined;
81-
hasChangedEmitSignature?: boolean;
8289
}
8390

8491
export const enum BuilderFileEmit {
@@ -90,38 +97,15 @@ namespace ts {
9097
* State to store the changed files, affected files and cache semantic diagnostics
9198
*/
9299
// TODO: GH#18217 Properties of this interface are frequently asserted to be defined.
93-
export interface BuilderProgramState extends BuilderState {
100+
export interface BuilderProgramState extends BuilderState, ReusableBuilderProgramState {
94101
/**
95102
* Cache of bind and check diagnostics for files with their Path being the key
96103
*/
97104
semanticDiagnosticsPerFile: ESMap<Path, readonly Diagnostic[]> | undefined;
98-
/**
99-
* The map has key by source file's path that has been changed
100-
*/
101-
changedFilesSet: Set<Path>;
102-
/**
103-
* Set of affected files being iterated
104-
*/
105-
affectedFiles: readonly SourceFile[] | undefined;
106105
/**
107106
* Current index to retrieve affected file from
108107
*/
109108
affectedFilesIndex: number | undefined;
110-
/**
111-
* Current changed file for iterating over affected files
112-
*/
113-
currentChangedFilePath: Path | undefined;
114-
/**
115-
* Map of file signatures, with key being file path, calculated while getting current changed file's affected files
116-
* These will be committed whenever the iteration through affected files of current changed file is complete
117-
*/
118-
currentAffectedFilesSignatures: ESMap<Path, string> | undefined;
119-
/**
120-
* Newly computed visible to outside referencedSet
121-
* We need to store the updates separately in case the in-progress build is cancelled
122-
* and we need to roll back.
123-
*/
124-
currentAffectedFilesExportedModulesMap: BuilderState.ManyToManyPathMap | undefined;
125109
/**
126110
* Already seen affected files
127111
*/
@@ -131,33 +115,13 @@ namespace ts {
131115
*/
132116
cleanedDiagnosticsOfLibFiles?: boolean;
133117
/**
134-
* True if the semantic diagnostics were copied from the old state
135-
*/
136-
semanticDiagnosticsFromOldState?: Set<Path>;
137-
/**
138-
* program corresponding to this state
139-
*/
140-
program: Program | undefined;
141-
/**
142-
* compilerOptions for the program
118+
* Records if change in dts emit was detected
143119
*/
144-
compilerOptions: CompilerOptions;
145-
emitSignatures?: ESMap<Path, string>;
146-
outSignature?: string;
147-
dtsChangeTime: number | undefined;
148-
hasChangedEmitSignature?: boolean;
120+
hasChangedEmitSignature?: boolean;
149121
/**
150122
* Files pending to be emitted
151123
*/
152124
affectedFilesPendingEmit: Path[] | undefined;
153-
/**
154-
* Files pending to be emitted kind.
155-
*/
156-
affectedFilesPendingEmitKind: ESMap<Path, BuilderFileEmit> | undefined;
157-
/**
158-
* Current index to retrieve pending affected file
159-
*/
160-
affectedFilesPendingEmitIndex: number | undefined;
161125
/**
162126
* true if build info is emitted
163127
*/
@@ -196,7 +160,7 @@ namespace ts {
196160
state.outSignature = oldState?.outSignature;
197161
}
198162
state.changedFilesSet = new Set();
199-
state.dtsChangeTime = oldState?.dtsChangeTime;
163+
state.dtsChangeTime = compilerOptions.composite ? oldState?.dtsChangeTime : undefined;
200164

201165
const useOldState = BuilderState.canReuseOldState(state.referencedMap, oldState);
202166
const oldCompilerOptions = useOldState ? oldState!.compilerOptions : undefined;
@@ -507,7 +471,7 @@ namespace ts {
507471
);
508472
return;
509473
}
510-
Debug.assert(state.hasCalledUpdateShapeSignature.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`);
474+
Debug.assert(state.hasCalledUpdateShapeSignature?.has(affectedFile.resolvedPath) || state.currentAffectedFilesSignatures?.has(affectedFile.resolvedPath), `Signature not updated for affected file: ${affectedFile.fileName}`);
511475
if (state.compilerOptions.assumeChangesOnlyAffectDirectDependencies) return;
512476
handleDtsMayChangeOfReferencingExportOfAffectedFile(state, affectedFile, cancellationToken, computeHash, host);
513477
}
@@ -844,7 +808,7 @@ namespace ts {
844808
/**
845809
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
846810
*/
847-
function getProgramBuildInfo(state: ReusableBuilderProgramState, getCanonicalFileName: GetCanonicalFileName, host: BuilderProgramHost): ProgramBuildInfo | undefined {
811+
function getProgramBuildInfo(state: BuilderProgramState, getCanonicalFileName: GetCanonicalFileName, host: BuilderProgramHost): ProgramBuildInfo | undefined {
848812
const outFilePath = outFile(state.compilerOptions);
849813
if (outFilePath && !state.compilerOptions.composite) return;
850814
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
@@ -924,9 +888,7 @@ namespace ts {
924888
value.length ?
925889
[
926890
toFileId(key),
927-
state.hasReusableDiagnostic ?
928-
value as readonly ReusableDiagnostic[] :
929-
convertToReusableDiagnostics(value as readonly Diagnostic[], relativeToBuildInfo)
891+
convertToReusableDiagnostics(value, relativeToBuildInfo)
930892
] :
931893
toFileId(key)
932894
);
@@ -1541,7 +1503,7 @@ namespace ts {
15411503
}
15421504
}
15431505

1544-
export function createRedirectedBuilderProgram(getState: () => { program: Program | undefined; compilerOptions: CompilerOptions; }, configFileParsingDiagnostics: readonly Diagnostic[]): BuilderProgram {
1506+
export function createRedirectedBuilderProgram(getState: () => { program?: Program | undefined; compilerOptions: CompilerOptions; }, configFileParsingDiagnostics: readonly Diagnostic[]): BuilderProgram {
15451507
return {
15461508
getState: notImplemented,
15471509
backupState: noop,

src/compiler/builderState.ts

+9-31
Original file line numberDiff line numberDiff line change
@@ -10,26 +10,7 @@ namespace ts {
1010
outputFiles.push({ name: fileName, writeByteOrderMark, text });
1111
}
1212
}
13-
14-
export interface ReusableBuilderState {
15-
/**
16-
* Information of the file eg. its version, signature etc
17-
*/
18-
fileInfos: ReadonlyESMap<Path, BuilderState.FileInfo>;
19-
/**
20-
* Contains the map of ReferencedSet=Referenced files of the file if module emit is enabled
21-
* Otherwise undefined
22-
* Thus non undefined value indicates, module emit
23-
*/
24-
readonly referencedMap?: BuilderState.ReadonlyManyToManyPathMap | undefined;
25-
/**
26-
* Contains the map of exported modules ReferencedSet=exported module files from the file if module emit is enabled
27-
* Otherwise undefined
28-
*/
29-
readonly exportedModulesMap?: BuilderState.ReadonlyManyToManyPathMap | undefined;
30-
}
31-
32-
export interface BuilderState extends ReusableBuilderState {
13+
export interface BuilderState {
3314
/**
3415
* Information of the file eg. its version, signature etc
3516
*/
@@ -52,13 +33,13 @@ namespace ts {
5233
* true if file version is used as signature
5334
* This helps in delaying the calculation of the d.ts hash as version for the file till reasonable time
5435
*/
55-
useFileVersionAsSignature: boolean;
36+
useFileVersionAsSignature?: boolean;
5637
/**
5738
* Map of files that have already called update signature.
5839
* That means hence forth these files are assumed to have
5940
* no change in their signature for this version of the program
6041
*/
61-
hasCalledUpdateShapeSignature: Set<Path>;
42+
hasCalledUpdateShapeSignature?: Set<Path>;
6243
/**
6344
* Cache of all files excluding default library file for the current program
6445
*/
@@ -68,7 +49,6 @@ namespace ts {
6849
*/
6950
allFileNames?: readonly string[];
7051
}
71-
7252
export namespace BuilderState {
7353
/**
7454
* Information about the source file: Its version and optional signature from last emit
@@ -287,18 +267,17 @@ namespace ts {
287267
/**
288268
* Returns true if oldState is reusable, that is the emitKind = module/non module has not changed
289269
*/
290-
export function canReuseOldState(newReferencedMap: ReadonlyManyToManyPathMap | undefined, oldState: Readonly<ReusableBuilderState> | undefined) {
270+
export function canReuseOldState(newReferencedMap: ReadonlyManyToManyPathMap | undefined, oldState: BuilderState | undefined) {
291271
return oldState && !oldState.referencedMap === !newReferencedMap;
292272
}
293273

294274
/**
295275
* Creates the state of file references and signature for the new program from oldState if it is safe
296276
*/
297-
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<ReusableBuilderState>, disableUseFileVersionAsSignature?: boolean): BuilderState {
277+
export function create(newProgram: Program, getCanonicalFileName: GetCanonicalFileName, oldState?: Readonly<BuilderState>, disableUseFileVersionAsSignature?: boolean): BuilderState {
298278
const fileInfos = new Map<Path, FileInfo>();
299279
const referencedMap = newProgram.getCompilerOptions().module !== ModuleKind.None ? createManyToManyPathMap() : undefined;
300280
const exportedModulesMap = referencedMap ? createManyToManyPathMap() : undefined;
301-
const hasCalledUpdateShapeSignature = new Set<Path>();
302281
const useOldState = canReuseOldState(referencedMap, oldState);
303282

304283
// Ensure source files have parent pointers set
@@ -328,7 +307,6 @@ namespace ts {
328307
fileInfos,
329308
referencedMap,
330309
exportedModulesMap,
331-
hasCalledUpdateShapeSignature,
332310
useFileVersionAsSignature: !disableUseFileVersionAsSignature && !useOldState
333311
};
334312
}
@@ -350,7 +328,7 @@ namespace ts {
350328
fileInfos: new Map(state.fileInfos),
351329
referencedMap: state.referencedMap?.clone(),
352330
exportedModulesMap: state.exportedModulesMap?.clone(),
353-
hasCalledUpdateShapeSignature: new Set(state.hasCalledUpdateShapeSignature),
331+
hasCalledUpdateShapeSignature: state.hasCalledUpdateShapeSignature && new Set(state.hasCalledUpdateShapeSignature),
354332
useFileVersionAsSignature: state.useFileVersionAsSignature,
355333
};
356334
}
@@ -391,18 +369,18 @@ namespace ts {
391369

392370
export function updateSignatureOfFile(state: BuilderState, signature: string | undefined, path: Path) {
393371
state.fileInfos.get(path)!.signature = signature;
394-
state.hasCalledUpdateShapeSignature.add(path);
372+
(state.hasCalledUpdateShapeSignature ||= new Set()).add(path);
395373
}
396374

397375
/**
398376
* Returns if the shape of the signature has changed since last emit
399377
*/
400-
export function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap<Path, string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap, useFileVersionAsSignature: boolean = state.useFileVersionAsSignature) {
378+
export function updateShapeSignature(state: Readonly<BuilderState>, programOfThisState: Program, sourceFile: SourceFile, cacheToUpdateSignature: ESMap<Path, string>, cancellationToken: CancellationToken | undefined, computeHash: ComputeHash, exportedModulesMapCache?: ManyToManyPathMap, useFileVersionAsSignature = state.useFileVersionAsSignature) {
401379
Debug.assert(!!sourceFile);
402380
Debug.assert(!exportedModulesMapCache || !!state.exportedModulesMap, "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state");
403381

404382
// If we have cached the result for this file, that means hence forth we should assume file shape is uptodate
405-
if (state.hasCalledUpdateShapeSignature.has(sourceFile.resolvedPath) || cacheToUpdateSignature.has(sourceFile.resolvedPath)) {
383+
if (state.hasCalledUpdateShapeSignature?.has(sourceFile.resolvedPath) || cacheToUpdateSignature.has(sourceFile.resolvedPath)) {
406384
return false;
407385
}
408386

0 commit comments

Comments
 (0)