@@ -142,6 +142,18 @@ namespace ts {
142
142
filesChangingSignature ?: Set < Path > ;
143
143
}
144
144
145
+ type BackupEmitState = Pick < BuilderProgramState ,
146
+ "affectedFilesPendingEmit" |
147
+ "affectedFilesPendingEmitIndex" |
148
+ "affectedFilesPendingEmitKind" |
149
+ "seenEmittedFiles" |
150
+ "programEmitComplete" |
151
+ "emitSignatures" |
152
+ "outSignature" |
153
+ "dtsChangeTime" |
154
+ "hasChangedEmitSignature"
155
+ > & { changedFilesSet : BuilderProgramState [ "changedFilesSet" ] | undefined } ;
156
+
145
157
function hasSameKeys ( map1 : ReadonlyCollection < string > | undefined , map2 : ReadonlyCollection < string > | undefined ) : boolean {
146
158
// Has same size and every key is present in both maps
147
159
return map1 === map2 || map1 !== undefined && map2 !== undefined && map1 . size === map2 . size && ! forEachKey ( map1 , key => ! map2 . has ( key ) ) ;
@@ -296,34 +308,35 @@ namespace ts {
296
308
state . program = undefined ;
297
309
}
298
310
299
- /**
300
- * Creates a clone of the state
301
- */
302
- function cloneBuilderProgramState ( state : Readonly < BuilderProgramState > ) : BuilderProgramState {
303
- const newState = BuilderState . clone ( state ) as BuilderProgramState ;
304
- newState . semanticDiagnosticsPerFile = state . semanticDiagnosticsPerFile && new Map ( state . semanticDiagnosticsPerFile ) ;
305
- newState . changedFilesSet = new Set ( state . changedFilesSet ) ;
306
- newState . affectedFiles = state . affectedFiles ;
307
- newState . affectedFilesIndex = state . affectedFilesIndex ;
308
- newState . currentChangedFilePath = state . currentChangedFilePath ;
309
- newState . currentAffectedFilesSignatures = state . currentAffectedFilesSignatures && new Map ( state . currentAffectedFilesSignatures ) ;
310
- newState . currentAffectedFilesExportedModulesMap = state . currentAffectedFilesExportedModulesMap ?. clone ( ) ;
311
- newState . seenAffectedFiles = state . seenAffectedFiles && new Set ( state . seenAffectedFiles ) ;
312
- newState . cleanedDiagnosticsOfLibFiles = state . cleanedDiagnosticsOfLibFiles ;
313
- newState . semanticDiagnosticsFromOldState = state . semanticDiagnosticsFromOldState && new Set ( state . semanticDiagnosticsFromOldState ) ;
314
- newState . program = state . program ;
315
- newState . compilerOptions = state . compilerOptions ;
316
- newState . affectedFilesPendingEmit = state . affectedFilesPendingEmit && state . affectedFilesPendingEmit . slice ( ) ;
317
- newState . affectedFilesPendingEmitKind = state . affectedFilesPendingEmitKind && new Map ( state . affectedFilesPendingEmitKind ) ;
318
- newState . affectedFilesPendingEmitIndex = state . affectedFilesPendingEmitIndex ;
319
- newState . seenEmittedFiles = state . seenEmittedFiles && new Map ( state . seenEmittedFiles ) ;
320
- newState . programEmitComplete = state . programEmitComplete ;
321
- newState . filesChangingSignature = state . filesChangingSignature && new Set ( state . filesChangingSignature ) ;
322
- newState . emitSignatures = state . emitSignatures && new Map ( state . emitSignatures ) ;
323
- newState . outSignature = state . outSignature ;
324
- newState . dtsChangeTime = state . dtsChangeTime ;
325
- newState . hasChangedEmitSignature = state . hasChangedEmitSignature ;
326
- return newState ;
311
+ function backupEmitBuilderProgramState ( state : Readonly < BuilderProgramState > ) : BackupEmitState {
312
+ const outFilePath = outFile ( state . compilerOptions ) ;
313
+ // Only in --out changeFileSet is kept around till emit
314
+ Debug . assert ( ! state . changedFilesSet . size || outFilePath ) ;
315
+ return {
316
+ affectedFilesPendingEmit : state . affectedFilesPendingEmit && state . affectedFilesPendingEmit . slice ( ) ,
317
+ affectedFilesPendingEmitKind : state . affectedFilesPendingEmitKind && new Map ( state . affectedFilesPendingEmitKind ) ,
318
+ affectedFilesPendingEmitIndex : state . affectedFilesPendingEmitIndex ,
319
+ seenEmittedFiles : state . seenEmittedFiles && new Map ( state . seenEmittedFiles ) ,
320
+ programEmitComplete : state . programEmitComplete ,
321
+ emitSignatures : state . emitSignatures && new Map ( state . emitSignatures ) ,
322
+ outSignature : state . outSignature ,
323
+ dtsChangeTime : state . dtsChangeTime ,
324
+ hasChangedEmitSignature : state . hasChangedEmitSignature ,
325
+ changedFilesSet : outFilePath ? new Set ( state . changedFilesSet ) : undefined ,
326
+ } ;
327
+ }
328
+
329
+ function restoreEmitBuilderProgramState ( state : BuilderProgramState , backupEmitState : BackupEmitState ) {
330
+ state . affectedFilesPendingEmit = backupEmitState . affectedFilesPendingEmit ;
331
+ state . affectedFilesPendingEmitKind = backupEmitState . affectedFilesPendingEmitKind ;
332
+ state . affectedFilesPendingEmitIndex = backupEmitState . affectedFilesPendingEmitIndex ;
333
+ state . seenEmittedFiles = backupEmitState . seenEmittedFiles ;
334
+ state . programEmitComplete = backupEmitState . programEmitComplete ;
335
+ state . emitSignatures = backupEmitState . emitSignatures ;
336
+ state . outSignature = backupEmitState . outSignature ;
337
+ state . dtsChangeTime = backupEmitState . dtsChangeTime ;
338
+ state . hasChangedEmitSignature = backupEmitState . hasChangedEmitSignature ;
339
+ if ( backupEmitState . changedFilesSet ) state . changedFilesSet = backupEmitState . changedFilesSet ;
327
340
}
328
341
329
342
/**
@@ -1090,8 +1103,8 @@ namespace ts {
1090
1103
* Computing hash to for signature verification
1091
1104
*/
1092
1105
const computeHash = maybeBind ( host , host . createHash ) ;
1093
- let state = createBuilderProgramState ( newProgram , getCanonicalFileName , oldState , host . disableUseFileVersionAsSignature ) ;
1094
- let backupState : BuilderProgramState | undefined ;
1106
+ const state = createBuilderProgramState ( newProgram , getCanonicalFileName , oldState , host . disableUseFileVersionAsSignature ) ;
1107
+ let backupEmitState : BackupEmitState | undefined ;
1095
1108
newProgram . getProgramBuildInfo = ( ) => getProgramBuildInfo ( state , getCanonicalFileName , host ) ;
1096
1109
1097
1110
// To ensure that we arent storing any references to old program or new program without state
@@ -1102,20 +1115,20 @@ namespace ts {
1102
1115
const getState = ( ) => state ;
1103
1116
const builderProgram = createRedirectedBuilderProgram ( getState , configFileParsingDiagnostics ) ;
1104
1117
builderProgram . getState = getState ;
1105
- builderProgram . backupState = ( ) => {
1106
- Debug . assert ( backupState === undefined ) ;
1107
- backupState = cloneBuilderProgramState ( state ) ;
1118
+ builderProgram . backupEmitState = ( ) => {
1119
+ Debug . assert ( backupEmitState === undefined ) ;
1120
+ backupEmitState = backupEmitBuilderProgramState ( state ) ;
1108
1121
} ;
1109
- builderProgram . restoreState = ( ) => {
1110
- state = Debug . checkDefined ( backupState ) ;
1111
- backupState = undefined ;
1122
+ builderProgram . restoreEmitState = ( ) => {
1123
+ restoreEmitBuilderProgramState ( state , Debug . checkDefined ( backupEmitState ) ) ;
1124
+ backupEmitState = undefined ;
1112
1125
} ;
1113
1126
builderProgram . getAllDependencies = sourceFile => BuilderState . getAllDependencies ( state , Debug . checkDefined ( state . program ) , sourceFile ) ;
1114
1127
builderProgram . getSemanticDiagnostics = getSemanticDiagnostics ;
1115
1128
builderProgram . emit = emit ;
1116
1129
builderProgram . releaseProgram = ( ) => {
1117
1130
releaseCache ( state ) ;
1118
- backupState = undefined ;
1131
+ backupEmitState = undefined ;
1119
1132
} ;
1120
1133
1121
1134
if ( kind === BuilderProgramKind . SemanticDiagnosticsBuilderProgram ) {
@@ -1451,8 +1464,8 @@ namespace ts {
1451
1464
} ;
1452
1465
return {
1453
1466
getState : ( ) => state ,
1454
- backupState : noop ,
1455
- restoreState : noop ,
1467
+ backupEmitState : noop ,
1468
+ restoreEmitState : noop ,
1456
1469
getProgram : notImplemented ,
1457
1470
getProgramOrUndefined : returnUndefined ,
1458
1471
releaseProgram : noop ,
@@ -1506,8 +1519,8 @@ namespace ts {
1506
1519
export function createRedirectedBuilderProgram ( getState : ( ) => { program ?: Program | undefined ; compilerOptions : CompilerOptions ; } , configFileParsingDiagnostics : readonly Diagnostic [ ] ) : BuilderProgram {
1507
1520
return {
1508
1521
getState : notImplemented ,
1509
- backupState : noop ,
1510
- restoreState : noop ,
1522
+ backupEmitState : noop ,
1523
+ restoreEmitState : noop ,
1511
1524
getProgram,
1512
1525
getProgramOrUndefined : ( ) => getState ( ) . program ,
1513
1526
releaseProgram : ( ) => getState ( ) . program = undefined ,
0 commit comments