@@ -333,7 +333,13 @@ namespace ts {
333
333
* This is to allow the callers to be able to actually remove affected file only when the operation is complete
334
334
* eg. if during diagnostics check cancellation token ends up cancelling the request, the affected file should be retained
335
335
*/
336
- function getNextAffectedFile ( state : BuilderProgramState , cancellationToken : CancellationToken | undefined , computeHash : BuilderState . ComputeHash , host : BuilderProgramHost ) : SourceFile | Program | undefined {
336
+ function getNextAffectedFile (
337
+ state : BuilderProgramState ,
338
+ cancellationToken : CancellationToken | undefined ,
339
+ computeHash : BuilderState . ComputeHash ,
340
+ getCanonicalFileName : GetCanonicalFileName ,
341
+ host : BuilderProgramHost
342
+ ) : SourceFile | Program | undefined {
337
343
while ( true ) {
338
344
const { affectedFiles } = state ;
339
345
if ( affectedFiles ) {
@@ -344,7 +350,14 @@ namespace ts {
344
350
if ( ! seenAffectedFiles . has ( affectedFile . resolvedPath ) ) {
345
351
// Set the next affected file as seen and remove the cached semantic diagnostics
346
352
state . affectedFilesIndex = affectedFilesIndex ;
347
- handleDtsMayChangeOfAffectedFile ( state , affectedFile , cancellationToken , computeHash , host ) ;
353
+ handleDtsMayChangeOfAffectedFile (
354
+ state ,
355
+ affectedFile ,
356
+ cancellationToken ,
357
+ computeHash ,
358
+ getCanonicalFileName ,
359
+ host
360
+ ) ;
348
361
return affectedFile ;
349
362
}
350
363
affectedFilesIndex ++ ;
@@ -376,7 +389,14 @@ namespace ts {
376
389
}
377
390
378
391
// Get next batch of affected files
379
- state . affectedFiles = BuilderState . getFilesAffectedByWithOldState ( state , program , nextKey . value , cancellationToken , computeHash ) ;
392
+ state . affectedFiles = BuilderState . getFilesAffectedByWithOldState (
393
+ state ,
394
+ program ,
395
+ nextKey . value ,
396
+ cancellationToken ,
397
+ computeHash ,
398
+ getCanonicalFileName ,
399
+ ) ;
380
400
state . currentChangedFilePath = nextKey . value ;
381
401
state . affectedFilesIndex = 0 ;
382
402
if ( ! state . seenAffectedFiles ) state . seenAffectedFiles = new Set ( ) ;
@@ -435,6 +455,7 @@ namespace ts {
435
455
affectedFile : SourceFile ,
436
456
cancellationToken : CancellationToken | undefined ,
437
457
computeHash : BuilderState . ComputeHash ,
458
+ getCanonicalFileName : GetCanonicalFileName ,
438
459
host : BuilderProgramHost ,
439
460
) {
440
461
removeSemanticDiagnosticsOf ( state , affectedFile . resolvedPath ) ;
@@ -451,11 +472,19 @@ namespace ts {
451
472
affectedFile ,
452
473
cancellationToken ,
453
474
computeHash ,
475
+ getCanonicalFileName ,
454
476
) ;
455
477
return ;
456
478
}
457
479
if ( state . compilerOptions . assumeChangesOnlyAffectDirectDependencies ) return ;
458
- handleDtsMayChangeOfReferencingExportOfAffectedFile ( state , affectedFile , cancellationToken , computeHash , host ) ;
480
+ handleDtsMayChangeOfReferencingExportOfAffectedFile (
481
+ state ,
482
+ affectedFile ,
483
+ cancellationToken ,
484
+ computeHash ,
485
+ getCanonicalFileName ,
486
+ host ,
487
+ ) ;
459
488
}
460
489
461
490
/**
@@ -467,6 +496,7 @@ namespace ts {
467
496
path : Path ,
468
497
cancellationToken : CancellationToken | undefined ,
469
498
computeHash : BuilderState . ComputeHash ,
499
+ getCanonicalFileName : GetCanonicalFileName ,
470
500
host : BuilderProgramHost
471
501
) : void {
472
502
removeSemanticDiagnosticsOf ( state , path ) ;
@@ -486,6 +516,7 @@ namespace ts {
486
516
sourceFile ,
487
517
cancellationToken ,
488
518
computeHash ,
519
+ getCanonicalFileName ,
489
520
! host . disableUseFileVersionAsSignature
490
521
) ;
491
522
// If not dts emit, nothing more to do
@@ -520,6 +551,7 @@ namespace ts {
520
551
filePath : Path ,
521
552
cancellationToken : CancellationToken | undefined ,
522
553
computeHash : BuilderState . ComputeHash ,
554
+ getCanonicalFileName : GetCanonicalFileName ,
523
555
host : BuilderProgramHost ,
524
556
) : boolean {
525
557
if ( ! state . fileInfos . get ( filePath ) ?. affectsGlobalScope ) return false ;
@@ -530,6 +562,7 @@ namespace ts {
530
562
file . resolvedPath ,
531
563
cancellationToken ,
532
564
computeHash ,
565
+ getCanonicalFileName ,
533
566
host ,
534
567
) ) ;
535
568
removeDiagnosticsOfLibraryFiles ( state ) ;
@@ -544,6 +577,7 @@ namespace ts {
544
577
affectedFile : SourceFile ,
545
578
cancellationToken : CancellationToken | undefined ,
546
579
computeHash : BuilderState . ComputeHash ,
580
+ getCanonicalFileName : GetCanonicalFileName ,
547
581
host : BuilderProgramHost
548
582
) {
549
583
// If there was change in signature (dts output) for the changed file,
@@ -561,8 +595,8 @@ namespace ts {
561
595
const currentPath = queue . pop ( ) ! ;
562
596
if ( ! seenFileNamesMap . has ( currentPath ) ) {
563
597
seenFileNamesMap . set ( currentPath , true ) ;
564
- if ( handleDtsMayChangeOfGlobalScope ( state , currentPath , cancellationToken , computeHash , host ) ) return ;
565
- handleDtsMayChangeOf ( state , currentPath , cancellationToken , computeHash , host ) ;
598
+ if ( handleDtsMayChangeOfGlobalScope ( state , currentPath , cancellationToken , computeHash , getCanonicalFileName , host ) ) return ;
599
+ handleDtsMayChangeOf ( state , currentPath , cancellationToken , computeHash , getCanonicalFileName , host ) ;
566
600
if ( isChangedSignature ( state , currentPath ) ) {
567
601
const currentSourceFile = Debug . checkDefined ( state . program ) . getSourceFileByPath ( currentPath ) ! ;
568
602
queue . push ( ...BuilderState . getReferencedByPaths ( state , currentSourceFile . resolvedPath ) ) ;
@@ -575,7 +609,7 @@ namespace ts {
575
609
// Go through exported modules from cache first
576
610
// If exported modules has path, all files referencing file exported from are affected
577
611
state . exportedModulesMap . getKeys ( affectedFile . resolvedPath ) ?. forEach ( exportedFromPath => {
578
- if ( handleDtsMayChangeOfGlobalScope ( state , exportedFromPath , cancellationToken , computeHash , host ) ) return true ;
612
+ if ( handleDtsMayChangeOfGlobalScope ( state , exportedFromPath , cancellationToken , computeHash , getCanonicalFileName , host ) ) return true ;
579
613
const references = state . referencedMap ! . getKeys ( exportedFromPath ) ;
580
614
return references && forEachKey ( references , filePath =>
581
615
handleDtsMayChangeOfFileAndExportsOfFile (
@@ -584,6 +618,7 @@ namespace ts {
584
618
seenFileAndExportsOfFile ,
585
619
cancellationToken ,
586
620
computeHash ,
621
+ getCanonicalFileName ,
587
622
host ,
588
623
)
589
624
) ;
@@ -600,12 +635,13 @@ namespace ts {
600
635
seenFileAndExportsOfFile : Set < string > ,
601
636
cancellationToken : CancellationToken | undefined ,
602
637
computeHash : BuilderState . ComputeHash ,
638
+ getCanonicalFileName : GetCanonicalFileName ,
603
639
host : BuilderProgramHost ,
604
640
) : boolean | undefined {
605
641
if ( ! tryAddToSet ( seenFileAndExportsOfFile , filePath ) ) return undefined ;
606
642
607
- if ( handleDtsMayChangeOfGlobalScope ( state , filePath , cancellationToken , computeHash , host ) ) return true ;
608
- handleDtsMayChangeOf ( state , filePath , cancellationToken , computeHash , host ) ;
643
+ if ( handleDtsMayChangeOfGlobalScope ( state , filePath , cancellationToken , computeHash , getCanonicalFileName , host ) ) return true ;
644
+ handleDtsMayChangeOf ( state , filePath , cancellationToken , computeHash , getCanonicalFileName , host ) ;
609
645
610
646
// If exported modules has path, all files referencing file exported from are affected
611
647
state . exportedModulesMap ! . getKeys ( filePath ) ?. forEach ( exportedFromPath =>
@@ -615,6 +651,7 @@ namespace ts {
615
651
seenFileAndExportsOfFile ,
616
652
cancellationToken ,
617
653
computeHash ,
654
+ getCanonicalFileName ,
618
655
host ,
619
656
)
620
657
) ;
@@ -627,6 +664,7 @@ namespace ts {
627
664
referencingFilePath ,
628
665
cancellationToken ,
629
666
computeHash ,
667
+ getCanonicalFileName ,
630
668
host ,
631
669
)
632
670
) ;
@@ -1038,8 +1076,30 @@ namespace ts {
1038
1076
return { host, newProgram, oldProgram, configFileParsingDiagnostics : configFileParsingDiagnostics || emptyArray } ;
1039
1077
}
1040
1078
1079
+ function getTextHandlingSourceMapForSignature ( text : string , data : WriteFileCallbackData | undefined ) {
1080
+ return data ?. sourceMapUrlPos !== undefined ? text . substring ( 0 , data . sourceMapUrlPos ) : text ;
1081
+ }
1082
+
1083
+ export function computeSignatureWithDiagnostics (
1084
+ program : Program ,
1085
+ text : string ,
1086
+ computeHash : BuilderState . ComputeHash | undefined ,
1087
+ getCanonicalFileName : GetCanonicalFileName ,
1088
+ data : WriteFileCallbackData | undefined
1089
+ ) {
1090
+ text = getTextHandlingSourceMapForSignature ( text , data ) ;
1091
+ if ( data ?. diagnostics ?. length ) {
1092
+ text += formatDiagnostics ( data . diagnostics , {
1093
+ getCurrentDirectory : ( ) => program . getCommonSourceDirectory ( ) ,
1094
+ getCanonicalFileName,
1095
+ getNewLine : ( ) => "\n" ,
1096
+ } ) ;
1097
+ }
1098
+ return ( computeHash || generateDjb2Hash ) ( text ) ;
1099
+ }
1100
+
1041
1101
export function computeSignature ( text : string , computeHash : BuilderState . ComputeHash | undefined , data ?: WriteFileCallbackData ) {
1042
- return ( computeHash || generateDjb2Hash ) ( data ?. sourceMapUrlPos !== undefined ? text . substring ( 0 , data . sourceMapUrlPos ) : text ) ;
1102
+ return ( computeHash || generateDjb2Hash ) ( getTextHandlingSourceMapForSignature ( text , data ) ) ;
1043
1103
}
1044
1104
1045
1105
export function createBuilderProgram ( kind : BuilderProgramKind . SemanticDiagnosticsBuilderProgram , builderCreationParameters : BuilderCreationParameters ) : SemanticDiagnosticsBuilderProgram ;
@@ -1108,7 +1168,7 @@ namespace ts {
1108
1168
* in that order would be used to write the files
1109
1169
*/
1110
1170
function emitNextAffectedFile ( writeFile ?: WriteFileCallback , cancellationToken ?: CancellationToken , emitOnlyDtsFiles ?: boolean , customTransformers ?: CustomTransformers ) : AffectedFileResult < EmitResult > {
1111
- let affected = getNextAffectedFile ( state , cancellationToken , computeHash , host ) ;
1171
+ let affected = getNextAffectedFile ( state , cancellationToken , computeHash , getCanonicalFileName , host ) ;
1112
1172
let emitKind = BuilderFileEmit . Full ;
1113
1173
let isPendingEmitFile = false ;
1114
1174
if ( ! affected ) {
@@ -1170,19 +1230,26 @@ namespace ts {
1170
1230
const file = sourceFiles [ 0 ] ;
1171
1231
const info = state . fileInfos . get ( file . resolvedPath ) ! ;
1172
1232
if ( info . signature === file . version ) {
1173
- newSignature = computeSignature ( text , computeHash , data ) ;
1174
- if ( newSignature !== file . version ) { // Update it
1233
+ const signature = computeSignatureWithDiagnostics (
1234
+ state . program ! ,
1235
+ text ,
1236
+ computeHash ,
1237
+ getCanonicalFileName ,
1238
+ data ,
1239
+ ) ;
1240
+ if ( ! data ?. diagnostics ?. length ) newSignature = signature ;
1241
+ if ( signature !== file . version ) { // Update it
1175
1242
if ( host . storeFilesChangingSignatureDuringEmit ) ( state . filesChangingSignature ||= new Set ( ) ) . add ( file . resolvedPath ) ;
1176
1243
if ( state . exportedModulesMap ) BuilderState . updateExportedModules ( state , file , file . exportedModulesFromDeclarationEmit ) ;
1177
1244
if ( state . affectedFiles ) {
1178
1245
// Keep old signature so we know what to undo if cancellation happens
1179
1246
const existing = state . oldSignatures ?. get ( file . resolvedPath ) ;
1180
1247
if ( existing === undefined ) ( state . oldSignatures ||= new Map ( ) ) . set ( file . resolvedPath , info . signature || false ) ;
1181
- info . signature = newSignature ;
1248
+ info . signature = signature ;
1182
1249
}
1183
1250
else {
1184
1251
// These are directly commited
1185
- info . signature = newSignature ;
1252
+ info . signature = signature ;
1186
1253
state . oldExportedModulesMap ?. clear ( ) ;
1187
1254
}
1188
1255
}
@@ -1287,7 +1354,7 @@ namespace ts {
1287
1354
*/
1288
1355
function getSemanticDiagnosticsOfNextAffectedFile ( cancellationToken ?: CancellationToken , ignoreSourceFile ?: ( sourceFile : SourceFile ) => boolean ) : AffectedFileResult < readonly Diagnostic [ ] > {
1289
1356
while ( true ) {
1290
- const affected = getNextAffectedFile ( state , cancellationToken , computeHash , host ) ;
1357
+ const affected = getNextAffectedFile ( state , cancellationToken , computeHash , getCanonicalFileName , host ) ;
1291
1358
if ( ! affected ) {
1292
1359
// Done
1293
1360
return undefined ;
0 commit comments