@@ -61,13 +61,16 @@ namespace ts {
61
61
allFileNames ?: readonly string [ ] ;
62
62
}
63
63
64
+ export const NOT_COMPUTED_YET = 0 ;
65
+ export const SHAPE_CHANGE_UNKNOWN = Symbol ( "shape change unknown" ) ;
66
+
64
67
export namespace BuilderState {
65
68
/**
66
69
* Information about the source file: Its version and optional signature from last emit
67
70
*/
68
71
export interface FileInfo {
69
72
readonly version : string ;
70
- signature : string | undefined ;
73
+ signature : string | typeof NOT_COMPUTED_YET | undefined ;
71
74
affectsGlobalScope : boolean ;
72
75
}
73
76
/**
@@ -264,7 +267,7 @@ namespace ts {
264
267
/**
265
268
* Gets the files affected by the path from the program
266
269
*/
267
- export function getFilesAffectedBy ( state : BuilderState , programOfThisState : Program , path : Path , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , cacheToUpdateSignature ?: ESMap < Path , string > , exportedModulesMapCache ?: ComputingExportedModulesMap ) : readonly SourceFile [ ] {
270
+ export function getFilesAffectedBy ( state : BuilderState , programOfThisState : Program , path : Path , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , cacheToUpdateSignature ?: ESMap < Path , string | typeof NOT_COMPUTED_YET > , exportedModulesMapCache ?: ComputingExportedModulesMap ) : readonly SourceFile [ ] {
268
271
// Since the operation could be cancelled, the signatures are always stored in the cache
269
272
// They will be committed once it is safe to use them
270
273
// eg when calling this api from tsserver, if there is no cancellation of the operation
@@ -275,11 +278,12 @@ namespace ts {
275
278
return emptyArray ;
276
279
}
277
280
278
- if ( ! updateShapeSignature ( state , programOfThisState , sourceFile , signatureCache , cancellationToken , computeHash , exportedModulesMapCache ) ) {
281
+ const updateResult = updateShapeSignature ( state , programOfThisState , sourceFile , signatureCache , cancellationToken , computeHash , exportedModulesMapCache , /*fromChange*/ true ) ;
282
+ if ( ! updateResult ) {
279
283
return [ sourceFile ] ;
280
284
}
281
285
282
- const result = ( state . referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit ) ( state , programOfThisState , sourceFile , signatureCache , cancellationToken , computeHash , exportedModulesMapCache ) ;
286
+ const result = ( state . referencedMap ? getFilesAffectedByUpdatedShapeWhenModuleEmit : getFilesAffectedByUpdatedShapeWhenNonModuleEmit ) ( state , programOfThisState , sourceFile , signatureCache , cancellationToken , computeHash , exportedModulesMapCache , updateResult === true ) ;
283
287
if ( ! cacheToUpdateSignature ) {
284
288
// Commit all the signatures in the signature cache
285
289
updateSignaturesFromCache ( state , signatureCache ) ;
@@ -291,19 +295,19 @@ namespace ts {
291
295
* Updates the signatures from the cache into state's fileinfo signatures
292
296
* This should be called whenever it is safe to commit the state of the builder
293
297
*/
294
- export function updateSignaturesFromCache ( state : BuilderState , signatureCache : ESMap < Path , string > ) {
298
+ export function updateSignaturesFromCache ( state : BuilderState , signatureCache : ESMap < Path , string | typeof NOT_COMPUTED_YET > ) {
295
299
signatureCache . forEach ( ( signature , path ) => updateSignatureOfFile ( state , signature , path ) ) ;
296
300
}
297
301
298
- export function updateSignatureOfFile ( state : BuilderState , signature : string | undefined , path : Path ) {
302
+ export function updateSignatureOfFile ( state : BuilderState , signature : string | typeof NOT_COMPUTED_YET | undefined , path : Path ) {
299
303
state . fileInfos . get ( path ) ! . signature = signature ;
300
304
state . hasCalledUpdateShapeSignature . add ( path ) ;
301
305
}
302
306
303
307
/**
304
308
* Returns if the shape of the signature has changed since last emit
305
309
*/
306
- export function updateShapeSignature ( state : Readonly < BuilderState > , programOfThisState : Program , sourceFile : SourceFile , cacheToUpdateSignature : ESMap < Path , string > , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , exportedModulesMapCache ?: ComputingExportedModulesMap ) {
310
+ export function updateShapeSignature ( state : Readonly < BuilderState > , programOfThisState : Program , sourceFile : SourceFile , cacheToUpdateSignature : ESMap < Path , string | typeof NOT_COMPUTED_YET > , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , exportedModulesMapCache ?: ComputingExportedModulesMap , fromChange ?: boolean ) : ( boolean | typeof SHAPE_CHANGE_UNKNOWN ) {
307
311
Debug . assert ( ! ! sourceFile ) ;
308
312
Debug . assert ( ! exportedModulesMapCache || ! ! state . exportedModulesMap , "Compute visible to outside map only if visibleToOutsideReferencedMap present in the state" ) ;
309
313
@@ -316,7 +320,7 @@ namespace ts {
316
320
if ( ! info ) return Debug . fail ( ) ;
317
321
318
322
const prevSignature = info . signature ;
319
- let latestSignature : string ;
323
+ let latestSignature : string | typeof NOT_COMPUTED_YET ;
320
324
if ( sourceFile . isDeclarationFile ) {
321
325
latestSignature = sourceFile . version ;
322
326
if ( exportedModulesMapCache && latestSignature !== prevSignature ) {
@@ -326,6 +330,14 @@ namespace ts {
326
330
}
327
331
}
328
332
else {
333
+ if ( ( prevSignature === undefined || prevSignature === NOT_COMPUTED_YET && ! fromChange ) && ! programOfThisState . getCompilerOptions ( ) . disableLazyShapeComputation ) {
334
+ if ( exportedModulesMapCache ) {
335
+ const references = state . referencedMap ? state . referencedMap . get ( sourceFile . resolvedPath ) : undefined ;
336
+ exportedModulesMapCache . set ( sourceFile . resolvedPath , references || false ) ;
337
+ }
338
+ cacheToUpdateSignature . set ( sourceFile . resolvedPath , NOT_COMPUTED_YET ) ;
339
+ return SHAPE_CHANGE_UNKNOWN ;
340
+ }
329
341
const emitOutput = getFileEmitOutput (
330
342
programOfThisState ,
331
343
sourceFile ,
@@ -352,7 +364,7 @@ namespace ts {
352
364
}
353
365
cacheToUpdateSignature . set ( sourceFile . resolvedPath , latestSignature ) ;
354
366
355
- return ! prevSignature || latestSignature !== prevSignature ;
367
+ return prevSignature ? latestSignature !== prevSignature : SHAPE_CHANGE_UNKNOWN ;
356
368
}
357
369
358
370
/**
@@ -524,7 +536,7 @@ namespace ts {
524
536
/**
525
537
* When program emits modular code, gets the files affected by the sourceFile whose shape has changed
526
538
*/
527
- function getFilesAffectedByUpdatedShapeWhenModuleEmit ( state : BuilderState , programOfThisState : Program , sourceFileWithUpdatedShape : SourceFile , cacheToUpdateSignature : ESMap < Path , string > , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , exportedModulesMapCache : ComputingExportedModulesMap | undefined ) {
539
+ function getFilesAffectedByUpdatedShapeWhenModuleEmit ( state : BuilderState , programOfThisState : Program , sourceFileWithUpdatedShape : SourceFile , cacheToUpdateSignature : ESMap < Path , string | typeof NOT_COMPUTED_YET > , cancellationToken : CancellationToken | undefined , computeHash : ComputeHash , exportedModulesMapCache : ComputingExportedModulesMap | undefined , realShapeChange : boolean ) {
528
540
if ( isFileAffectingGlobalScope ( sourceFileWithUpdatedShape ) ) {
529
541
return getAllFilesExcludingDefaultLibraryFile ( state , programOfThisState , sourceFileWithUpdatedShape ) ;
530
542
}
@@ -541,14 +553,20 @@ namespace ts {
541
553
542
554
// Start with the paths this file was referenced by
543
555
seenFileNamesMap . set ( sourceFileWithUpdatedShape . resolvedPath , sourceFileWithUpdatedShape ) ;
544
- const queue = getReferencedByPaths ( state , sourceFileWithUpdatedShape . resolvedPath ) ;
556
+ const queue = getReferencedByPaths ( state , sourceFileWithUpdatedShape . resolvedPath ) . map ( path => ( { path , updatedShape : realShapeChange } ) ) ;
545
557
while ( queue . length > 0 ) {
546
- const currentPath = queue . pop ( ) ! ;
558
+ const { path : currentPath , updatedShape } = queue . pop ( ) ! ;
547
559
if ( ! seenFileNamesMap . has ( currentPath ) ) {
548
560
const currentSourceFile = programOfThisState . getSourceFileByPath ( currentPath ) ! ;
549
561
seenFileNamesMap . set ( currentPath , currentSourceFile ) ;
550
- if ( currentSourceFile && updateShapeSignature ( state , programOfThisState , currentSourceFile , cacheToUpdateSignature , cancellationToken , computeHash , exportedModulesMapCache ) ) {
551
- queue . push ( ...getReferencedByPaths ( state , currentSourceFile . resolvedPath ) ) ;
562
+ if ( currentSourceFile ) {
563
+ const updateResult = updateShapeSignature ( state , programOfThisState , currentSourceFile , cacheToUpdateSignature , cancellationToken , computeHash , exportedModulesMapCache , updatedShape ) ;
564
+ if ( updateResult ) {
565
+ const updatedShape = updateResult === true ;
566
+ getReferencedByPaths ( state , currentSourceFile . resolvedPath ) . forEach ( path => {
567
+ queue . push ( { path, updatedShape } ) ;
568
+ } ) ;
569
+ }
552
570
}
553
571
}
554
572
}
0 commit comments