@@ -5,6 +5,7 @@ namespace ts {
5
5
/**
6
6
* State to store the changed files, affected files and cache semantic diagnostics
7
7
*/
8
+ // TODO: GH#18217 Properties of this interface are frequently asserted to be defined.
8
9
export interface BuilderProgramState extends BuilderState {
9
10
/**
10
11
* Cache of semantic diagnostics for files with their Path being the key
@@ -43,7 +44,7 @@ namespace ts {
43
44
44
45
function hasSameKeys < T , U > ( map1 : ReadonlyMap < T > | undefined , map2 : ReadonlyMap < U > | undefined ) : boolean {
45
46
// Has same size and every key is present in both maps
46
- return map1 as ReadonlyMap < T | U > === map2 || map1 && map2 && map1 . size === map2 . size && ! forEachKey ( map1 , key => ! map2 . has ( key ) ) ;
47
+ return map1 as ReadonlyMap < T | U > === map2 || map1 !== undefined && map2 !== undefined && map1 . size === map2 . size && ! forEachKey ( map1 , key => ! map2 . has ( key ) ) ;
47
48
}
48
49
49
50
/**
@@ -58,45 +59,45 @@ namespace ts {
58
59
}
59
60
state . changedFilesSet = createMap < true > ( ) ;
60
61
const useOldState = BuilderState . canReuseOldState ( state . referencedMap , oldState ) ;
61
- const canCopySemanticDiagnostics = useOldState && oldState . semanticDiagnosticsPerFile && ! ! state . semanticDiagnosticsPerFile ;
62
+ const canCopySemanticDiagnostics = useOldState && oldState ! . semanticDiagnosticsPerFile && ! ! state . semanticDiagnosticsPerFile ;
62
63
if ( useOldState ) {
63
64
// Verify the sanity of old state
64
- if ( ! oldState . currentChangedFilePath ) {
65
- Debug . assert ( ! oldState . affectedFiles && ( ! oldState . currentAffectedFilesSignatures || ! oldState . currentAffectedFilesSignatures . size ) , "Cannot reuse if only few affected files of currentChangedFile were iterated" ) ;
65
+ if ( ! oldState ! . currentChangedFilePath ) {
66
+ Debug . assert ( ! oldState ! . affectedFiles && ( ! oldState ! . currentAffectedFilesSignatures || ! oldState ! . currentAffectedFilesSignatures ! . size ) , "Cannot reuse if only few affected files of currentChangedFile were iterated" ) ;
66
67
}
67
68
if ( canCopySemanticDiagnostics ) {
68
- Debug . assert ( ! forEachKey ( oldState . changedFilesSet , path => oldState . semanticDiagnosticsPerFile . has ( path ) ) , "Semantic diagnostics shouldnt be available for changed files" ) ;
69
+ Debug . assert ( ! forEachKey ( oldState ! . changedFilesSet , path => oldState ! . semanticDiagnosticsPerFile ! . has ( path ) ) , "Semantic diagnostics shouldnt be available for changed files" ) ;
69
70
}
70
71
71
72
// Copy old state's changed files set
72
- copyEntries ( oldState . changedFilesSet , state . changedFilesSet ) ;
73
+ copyEntries ( oldState ! . changedFilesSet , state . changedFilesSet ) ;
73
74
}
74
75
75
76
// Update changed files and copy semantic diagnostics if we can
76
77
const referencedMap = state . referencedMap ;
77
- const oldReferencedMap = useOldState && oldState . referencedMap ;
78
+ const oldReferencedMap = useOldState ? oldState ! . referencedMap : undefined ;
78
79
state . fileInfos . forEach ( ( info , sourceFilePath ) => {
79
- let oldInfo : Readonly < BuilderState . FileInfo > ;
80
- let newReferences : BuilderState . ReferencedSet ;
80
+ let oldInfo : Readonly < BuilderState . FileInfo > | undefined ;
81
+ let newReferences : BuilderState . ReferencedSet | undefined ;
81
82
82
83
// if not using old state, every file is changed
83
84
if ( ! useOldState ||
84
85
// File wasnt present in old state
85
- ! ( oldInfo = oldState . fileInfos . get ( sourceFilePath ) ) ||
86
+ ! ( oldInfo = oldState ! . fileInfos . get ( sourceFilePath ) ) ||
86
87
// versions dont match
87
88
oldInfo . version !== info . version ||
88
89
// Referenced files changed
89
90
! hasSameKeys ( newReferences = referencedMap && referencedMap . get ( sourceFilePath ) , oldReferencedMap && oldReferencedMap . get ( sourceFilePath ) ) ||
90
91
// Referenced file was deleted in the new program
91
- newReferences && forEachKey ( newReferences , path => ! state . fileInfos . has ( path ) && oldState . fileInfos . has ( path ) ) ) {
92
+ newReferences && forEachKey ( newReferences , path => ! state . fileInfos . has ( path ) && oldState ! . fileInfos . has ( path ) ) ) {
92
93
// Register file as changed file and do not copy semantic diagnostics, since all changed files need to be re-evaluated
93
94
state . changedFilesSet . set ( sourceFilePath , true ) ;
94
95
}
95
96
else if ( canCopySemanticDiagnostics ) {
96
97
// Unchanged file copy diagnostics
97
- const diagnostics = oldState . semanticDiagnosticsPerFile . get ( sourceFilePath ) ;
98
+ const diagnostics = oldState ! . semanticDiagnosticsPerFile ! . get ( sourceFilePath ) ;
98
99
if ( diagnostics ) {
99
- state . semanticDiagnosticsPerFile . set ( sourceFilePath , diagnostics ) ;
100
+ state . semanticDiagnosticsPerFile ! . set ( sourceFilePath , diagnostics ) ;
100
101
}
101
102
}
102
103
} ) ;
@@ -108,7 +109,7 @@ namespace ts {
108
109
* Verifies that source file is ok to be used in calls that arent handled by next
109
110
*/
110
111
function assertSourceFileOkWithoutNextAffectedCall ( state : BuilderProgramState , sourceFile : SourceFile | undefined ) {
111
- Debug . assert ( ! sourceFile || ! state . affectedFiles || state . affectedFiles [ state . affectedFilesIndex - 1 ] !== sourceFile || ! state . semanticDiagnosticsPerFile . has ( sourceFile . path ) ) ;
112
+ Debug . assert ( ! sourceFile || ! state . affectedFiles || state . affectedFiles [ state . affectedFilesIndex ! - 1 ] !== sourceFile || ! state . semanticDiagnosticsPerFile ! . has ( sourceFile . path ) ) ;
112
113
}
113
114
114
115
/**
@@ -122,25 +123,25 @@ namespace ts {
122
123
const { affectedFiles } = state ;
123
124
if ( affectedFiles ) {
124
125
const { seenAffectedFiles, semanticDiagnosticsPerFile } = state ;
125
- let { affectedFilesIndex } = state ;
126
+ let affectedFilesIndex = state . affectedFilesIndex ! ; // TODO: GH#18217
126
127
while ( affectedFilesIndex < affectedFiles . length ) {
127
128
const affectedFile = affectedFiles [ affectedFilesIndex ] ;
128
- if ( ! seenAffectedFiles . has ( affectedFile . path ) ) {
129
+ if ( ! seenAffectedFiles ! . has ( affectedFile . path ) ) {
129
130
// Set the next affected file as seen and remove the cached semantic diagnostics
130
131
state . affectedFilesIndex = affectedFilesIndex ;
131
- semanticDiagnosticsPerFile . delete ( affectedFile . path ) ;
132
+ semanticDiagnosticsPerFile ! . delete ( affectedFile . path ) ;
132
133
return affectedFile ;
133
134
}
134
- seenAffectedFiles . set ( affectedFile . path , true ) ;
135
+ seenAffectedFiles ! . set ( affectedFile . path , true ) ;
135
136
affectedFilesIndex ++ ;
136
137
}
137
138
138
139
// Remove the changed file from the change set
139
- state . changedFilesSet . delete ( state . currentChangedFilePath ) ;
140
+ state . changedFilesSet . delete ( state . currentChangedFilePath ! ) ;
140
141
state . currentChangedFilePath = undefined ;
141
142
// Commit the changes in file signature
142
- BuilderState . updateSignaturesFromCache ( state , state . currentAffectedFilesSignatures ) ;
143
- state . currentAffectedFilesSignatures . clear ( ) ;
143
+ BuilderState . updateSignaturesFromCache ( state , state . currentAffectedFilesSignatures ! ) ;
144
+ state . currentAffectedFilesSignatures ! . clear ( ) ;
144
145
state . affectedFiles = undefined ;
145
146
}
146
147
@@ -163,7 +164,7 @@ namespace ts {
163
164
state . currentAffectedFilesSignatures = state . currentAffectedFilesSignatures || createMap ( ) ;
164
165
state . affectedFiles = BuilderState . getFilesAffectedBy ( state , state . program , nextKey . value as Path , cancellationToken , computeHash , state . currentAffectedFilesSignatures ) ;
165
166
state . currentChangedFilePath = nextKey . value as Path ;
166
- state . semanticDiagnosticsPerFile . delete ( nextKey . value as Path ) ;
167
+ state . semanticDiagnosticsPerFile ! . delete ( nextKey . value as Path ) ;
167
168
state . affectedFilesIndex = 0 ;
168
169
state . seenAffectedFiles = state . seenAffectedFiles || createMap < true > ( ) ;
169
170
}
@@ -178,8 +179,8 @@ namespace ts {
178
179
state . changedFilesSet . clear ( ) ;
179
180
}
180
181
else {
181
- state . seenAffectedFiles . set ( ( affected as SourceFile ) . path , true ) ;
182
- state . affectedFilesIndex ++ ;
182
+ state . seenAffectedFiles ! . set ( ( affected as SourceFile ) . path , true ) ;
183
+ state . affectedFilesIndex ! ++ ;
183
184
}
184
185
}
185
186
@@ -197,15 +198,15 @@ namespace ts {
197
198
*/
198
199
function getSemanticDiagnosticsOfFile ( state : BuilderProgramState , sourceFile : SourceFile , cancellationToken ?: CancellationToken ) : ReadonlyArray < Diagnostic > {
199
200
const path = sourceFile . path ;
200
- const cachedDiagnostics = state . semanticDiagnosticsPerFile . get ( path ) ;
201
+ const cachedDiagnostics = state . semanticDiagnosticsPerFile ! . get ( path ) ;
201
202
// Report the semantic diagnostics from the cache if we already have those diagnostics present
202
203
if ( cachedDiagnostics ) {
203
204
return cachedDiagnostics ;
204
205
}
205
206
206
207
// Diagnostics werent cached, get them from program, and cache the result
207
208
const diagnostics = state . program . getSemanticDiagnostics ( sourceFile , cancellationToken ) ;
208
- state . semanticDiagnosticsPerFile . set ( path , diagnostics ) ;
209
+ state . semanticDiagnosticsPerFile ! . set ( path , diagnostics ) ;
209
210
return diagnostics ;
210
211
}
211
212
@@ -241,7 +242,7 @@ namespace ts {
241
242
// Return same program if underlying program doesnt change
242
243
let oldState = oldProgram && oldProgram . getState ( ) ;
243
244
if ( oldState && newProgram === oldState . program ) {
244
- newProgram = undefined ;
245
+ newProgram = undefined ! ; // TODO: GH#18217
245
246
oldState = undefined ;
246
247
return oldProgram ;
247
248
}
@@ -257,7 +258,7 @@ namespace ts {
257
258
const state = createBuilderProgramState ( newProgram , getCanonicalFileName , oldState ) ;
258
259
259
260
// To ensure that we arent storing any references to old program or new program without state
260
- newProgram = undefined ;
261
+ newProgram = undefined ! ; // TODO: GH#18217
261
262
oldProgram = undefined ;
262
263
oldState = undefined ;
263
264
@@ -326,8 +327,8 @@ namespace ts {
326
327
if ( ! targetSourceFile ) {
327
328
// Emit and report any errors we ran into.
328
329
let sourceMaps : SourceMapData [ ] = [ ] ;
329
- let emitSkipped : boolean ;
330
- let diagnostics : Diagnostic [ ] ;
330
+ let emitSkipped = false ;
331
+ let diagnostics : Diagnostic [ ] | undefined ;
331
332
let emittedFiles : string [ ] = [ ] ;
332
333
333
334
let affectedEmitResult : AffectedFileResult < EmitResult > ;
@@ -413,7 +414,7 @@ namespace ts {
413
414
}
414
415
}
415
416
416
- let diagnostics : Diagnostic [ ] ;
417
+ let diagnostics : Diagnostic [ ] | undefined ;
417
418
for ( const sourceFile of state . program . getSourceFiles ( ) ) {
418
419
diagnostics = addRange ( diagnostics , getSemanticDiagnosticsOfFile ( state , sourceFile , cancellationToken ) ) ;
419
420
}
0 commit comments