@@ -10,18 +10,13 @@ namespace ts {
10
10
export interface ReusableDiagnosticRelatedInformation {
11
11
category : DiagnosticCategory ;
12
12
code : number ;
13
- file : Path | undefined ;
13
+ file : string | undefined ;
14
14
start : number | undefined ;
15
15
length : number | undefined ;
16
16
messageText : string | ReusableDiagnosticMessageChain ;
17
17
}
18
18
19
- export interface ReusableDiagnosticMessageChain {
20
- messageText : string ;
21
- category : DiagnosticCategory ;
22
- code : number ;
23
- next ?: ReusableDiagnosticMessageChain ;
24
- }
19
+ export type ReusableDiagnosticMessageChain = DiagnosticMessageChain ;
25
20
26
21
export interface ReusableBuilderProgramState extends ReusableBuilderState {
27
22
/**
@@ -227,7 +222,7 @@ namespace ts {
227
222
// Unchanged file copy diagnostics
228
223
const diagnostics = oldState ! . semanticDiagnosticsPerFile ! . get ( sourceFilePath ) ;
229
224
if ( diagnostics ) {
230
- state . semanticDiagnosticsPerFile ! . set ( sourceFilePath , oldState ! . hasReusableDiagnostic ? convertToDiagnostics ( diagnostics as ReadonlyArray < ReusableDiagnostic > , newProgram ) : diagnostics as ReadonlyArray < Diagnostic > ) ;
225
+ state . semanticDiagnosticsPerFile ! . set ( sourceFilePath , oldState ! . hasReusableDiagnostic ? convertToDiagnostics ( diagnostics as ReadonlyArray < ReusableDiagnostic > , newProgram , getCanonicalFileName ) : diagnostics as ReadonlyArray < Diagnostic > ) ;
231
226
if ( ! state . semanticDiagnosticsFromOldState ) {
232
227
state . semanticDiagnosticsFromOldState = createMap < true > ( ) ;
233
228
}
@@ -246,37 +241,32 @@ namespace ts {
246
241
return state ;
247
242
}
248
243
249
- function convertToDiagnostics ( diagnostics : ReadonlyArray < ReusableDiagnostic > , newProgram : Program ) : ReadonlyArray < Diagnostic > {
244
+ function convertToDiagnostics ( diagnostics : ReadonlyArray < ReusableDiagnostic > , newProgram : Program , getCanonicalFileName : GetCanonicalFileName ) : ReadonlyArray < Diagnostic > {
250
245
if ( ! diagnostics . length ) return emptyArray ;
246
+ const buildInfoDirectory = getDirectoryPath ( getOutputPathForBuildInfo ( newProgram . getCompilerOptions ( ) ) ! ) ;
251
247
return diagnostics . map ( diagnostic => {
252
- const result : Diagnostic = convertToDiagnosticRelatedInformation ( diagnostic , newProgram ) ;
248
+ const result : Diagnostic = convertToDiagnosticRelatedInformation ( diagnostic , newProgram , toPath ) ;
253
249
result . reportsUnnecessary = diagnostic . reportsUnnecessary ;
254
250
result . source = diagnostic . source ;
255
251
const { relatedInformation } = diagnostic ;
256
252
result . relatedInformation = relatedInformation ?
257
253
relatedInformation . length ?
258
- relatedInformation . map ( r => convertToDiagnosticRelatedInformation ( r , newProgram ) ) :
254
+ relatedInformation . map ( r => convertToDiagnosticRelatedInformation ( r , newProgram , toPath ) ) :
259
255
emptyArray :
260
256
undefined ;
261
257
return result ;
262
258
} ) ;
263
- }
264
259
265
- function convertToDiagnosticRelatedInformation ( diagnostic : ReusableDiagnosticRelatedInformation , newProgram : Program ) : DiagnosticRelatedInformation {
266
- const { file, messageText } = diagnostic ;
267
- return {
268
- ...diagnostic ,
269
- file : file && newProgram . getSourceFileByPath ( file ) ,
270
- messageText : messageText === undefined || isString ( messageText ) ?
271
- messageText :
272
- convertToDiagnosticMessageChain ( messageText , newProgram )
273
- } ;
260
+ function toPath ( path : string ) {
261
+ return ts . toPath ( path , buildInfoDirectory , getCanonicalFileName ) ;
262
+ }
274
263
}
275
264
276
- function convertToDiagnosticMessageChain ( diagnostic : ReusableDiagnosticMessageChain , newProgram : Program ) : DiagnosticMessageChain {
265
+ function convertToDiagnosticRelatedInformation ( diagnostic : ReusableDiagnosticRelatedInformation , newProgram : Program , toPath : ( path : string ) => Path ) : DiagnosticRelatedInformation {
266
+ const { file } = diagnostic ;
277
267
return {
278
268
...diagnostic ,
279
- next : diagnostic . next && convertToDiagnosticMessageChain ( diagnostic . next , newProgram )
269
+ file : file ? newProgram . getSourceFileByPath ( toPath ( file ) ) : undefined
280
270
} ;
281
271
}
282
272
@@ -620,19 +610,20 @@ namespace ts {
620
610
/**
621
611
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
622
612
*/
623
- function getProgramBuildInfo ( state : Readonly < ReusableBuilderProgramState > ) : ProgramBuildInfo | undefined {
613
+ function getProgramBuildInfo ( state : Readonly < ReusableBuilderProgramState > , getCanonicalFileName : GetCanonicalFileName ) : ProgramBuildInfo | undefined {
624
614
if ( state . compilerOptions . outFile || state . compilerOptions . out ) return undefined ;
615
+ const buildInfoDirectory = getDirectoryPath ( getOutputPathForBuildInfo ( state . compilerOptions ) ! ) ;
625
616
const fileInfos : MapLike < BuilderState . FileInfo > = { } ;
626
617
state . fileInfos . forEach ( ( value , key ) => {
627
618
const signature = state . currentAffectedFilesSignatures && state . currentAffectedFilesSignatures . get ( key ) ;
628
- fileInfos [ key ] = signature === undefined ? value : { version : value . version , signature } ;
619
+ fileInfos [ relativeToBuildInfo ( key ) ] = signature === undefined ? value : { version : value . version , signature } ;
629
620
} ) ;
630
621
631
622
const result : ProgramBuildInfo = { fileInfos, options : state . compilerOptions } ;
632
623
if ( state . referencedMap ) {
633
624
const referencedMap : MapLike < string [ ] > = { } ;
634
625
state . referencedMap . forEach ( ( value , key ) => {
635
- referencedMap [ key ] = arrayFrom ( value . keys ( ) ) ;
626
+ referencedMap [ relativeToBuildInfo ( key ) ] = arrayFrom ( value . keys ( ) , relativeToBuildInfo ) ;
636
627
} ) ;
637
628
result . referencedMap = referencedMap ;
638
629
}
@@ -642,9 +633,9 @@ namespace ts {
642
633
state . exportedModulesMap . forEach ( ( value , key ) => {
643
634
const newValue = state . currentAffectedFilesExportedModulesMap && state . currentAffectedFilesExportedModulesMap . get ( key ) ;
644
635
// Not in temporary cache, use existing value
645
- if ( newValue === undefined ) exportedModulesMap [ key ] = arrayFrom ( value . keys ( ) ) ;
636
+ if ( newValue === undefined ) exportedModulesMap [ relativeToBuildInfo ( key ) ] = arrayFrom ( value . keys ( ) , relativeToBuildInfo ) ;
646
637
// Value in cache and has updated value map, use that
647
- else if ( newValue ) exportedModulesMap [ key ] = arrayFrom ( newValue . keys ( ) ) ;
638
+ else if ( newValue ) exportedModulesMap [ relativeToBuildInfo ( key ) ] = arrayFrom ( newValue . keys ( ) , relativeToBuildInfo ) ;
648
639
} ) ;
649
640
result . exportedModulesMap = exportedModulesMap ;
650
641
}
@@ -655,50 +646,44 @@ namespace ts {
655
646
state . semanticDiagnosticsPerFile . forEach ( ( value , key ) => semanticDiagnosticsPerFile . push (
656
647
value . length ?
657
648
[
658
- key ,
649
+ relativeToBuildInfo ( key ) ,
659
650
state . hasReusableDiagnostic ?
660
651
value as ReadonlyArray < ReusableDiagnostic > :
661
- convertToReusableDiagnostics ( value as ReadonlyArray < Diagnostic > )
652
+ convertToReusableDiagnostics ( value as ReadonlyArray < Diagnostic > , relativeToBuildInfo )
662
653
] :
663
- key
654
+ relativeToBuildInfo ( key )
664
655
) ) ;
665
656
result . semanticDiagnosticsPerFile = semanticDiagnosticsPerFile ;
666
657
}
667
658
668
659
return result ;
660
+
661
+ function relativeToBuildInfo ( path : string ) {
662
+ return ensurePathIsNonModuleName ( getRelativePathFromDirectory ( buildInfoDirectory , path , getCanonicalFileName ) ) ;
663
+ }
669
664
}
670
665
671
- function convertToReusableDiagnostics ( diagnostics : ReadonlyArray < Diagnostic > ) : ReadonlyArray < ReusableDiagnostic > {
666
+ function convertToReusableDiagnostics ( diagnostics : ReadonlyArray < Diagnostic > , relativeToBuildInfo : ( path : string ) => string ) : ReadonlyArray < ReusableDiagnostic > {
672
667
Debug . assert ( ! ! diagnostics . length ) ;
673
668
return diagnostics . map ( diagnostic => {
674
- const result : ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation ( diagnostic ) ;
669
+ const result : ReusableDiagnostic = convertToReusableDiagnosticRelatedInformation ( diagnostic , relativeToBuildInfo ) ;
675
670
result . reportsUnnecessary = diagnostic . reportsUnnecessary ;
676
671
result . source = diagnostic . source ;
677
672
const { relatedInformation } = diagnostic ;
678
673
result . relatedInformation = relatedInformation ?
679
674
relatedInformation . length ?
680
- relatedInformation . map ( r => convertToReusableDiagnosticRelatedInformation ( r ) ) :
675
+ relatedInformation . map ( r => convertToReusableDiagnosticRelatedInformation ( r , relativeToBuildInfo ) ) :
681
676
emptyArray :
682
677
undefined ;
683
678
return result ;
684
679
} ) ;
685
680
}
686
681
687
- function convertToReusableDiagnosticRelatedInformation ( diagnostic : DiagnosticRelatedInformation ) : ReusableDiagnosticRelatedInformation {
688
- const { file, messageText } = diagnostic ;
682
+ function convertToReusableDiagnosticRelatedInformation ( diagnostic : DiagnosticRelatedInformation , relativeToBuildInfo : ( path : string ) => string ) : ReusableDiagnosticRelatedInformation {
683
+ const { file } = diagnostic ;
689
684
return {
690
685
...diagnostic ,
691
- file : file && file . path ,
692
- messageText : messageText === undefined || isString ( messageText ) ?
693
- messageText :
694
- convertToReusableDiagnosticMessageChain ( messageText )
695
- } ;
696
- }
697
-
698
- function convertToReusableDiagnosticMessageChain ( diagnostic : DiagnosticMessageChain ) : ReusableDiagnosticMessageChain {
699
- return {
700
- ...diagnostic ,
701
- next : diagnostic . next && convertToReusableDiagnosticMessageChain ( diagnostic . next )
686
+ file : file ? relativeToBuildInfo ( file . path ) : undefined
702
687
} ;
703
688
}
704
689
@@ -767,7 +752,7 @@ namespace ts {
767
752
const computeHash = host . createHash || generateDjb2Hash ;
768
753
let state = createBuilderProgramState ( newProgram , getCanonicalFileName , oldState ) ;
769
754
let backupState : BuilderProgramState | undefined ;
770
- newProgram . getProgramBuildInfo = ( ) => getProgramBuildInfo ( state ) ;
755
+ newProgram . getProgramBuildInfo = ( ) => getProgramBuildInfo ( state , getCanonicalFileName ) ;
771
756
772
757
// To ensure that we arent storing any references to old program or new program without state
773
758
newProgram = undefined ! ; // TODO: GH#18217
@@ -980,26 +965,35 @@ namespace ts {
980
965
}
981
966
}
982
967
983
- function getMapOfReferencedSet ( mapLike : MapLike < ReadonlyArray < string > > | undefined ) : ReadonlyMap < BuilderState . ReferencedSet > | undefined {
968
+ function getMapOfReferencedSet ( mapLike : MapLike < ReadonlyArray < string > > | undefined , toPath : ( path : string ) => Path ) : ReadonlyMap < BuilderState . ReferencedSet > | undefined {
984
969
if ( ! mapLike ) return undefined ;
985
970
const map = createMap < BuilderState . ReferencedSet > ( ) ;
986
971
// Copies keys/values from template. Note that for..in will not throw if
987
972
// template is undefined, and instead will just exit the loop.
988
973
for ( const key in mapLike ) {
989
974
if ( hasProperty ( mapLike , key ) ) {
990
- map . set ( key , arrayToSet ( mapLike [ key ] ) ) ;
975
+ map . set ( toPath ( key ) , arrayToSet ( mapLike [ key ] , toPath ) ) ;
991
976
}
992
977
}
993
978
return map ;
994
979
}
995
980
996
- export function createBuildProgramUsingProgramBuildInfo ( program : ProgramBuildInfo ) : EmitAndSemanticDiagnosticsBuilderProgram {
997
- const fileInfos = createMapFromTemplate ( program . fileInfos ) ;
981
+ export function createBuildProgramUsingProgramBuildInfo ( program : ProgramBuildInfo , buildInfoPath : string , useCaseSensitiveFileNames : boolean ) : EmitAndSemanticDiagnosticsBuilderProgram {
982
+ const buildInfoDirectory = getDirectoryPath ( buildInfoPath ) ;
983
+ const getCanonicalFileName = createGetCanonicalFileName ( useCaseSensitiveFileNames ) ;
984
+
985
+ const fileInfos = createMap < BuilderState . FileInfo > ( ) ;
986
+ for ( const key in program . fileInfos ) {
987
+ if ( hasProperty ( program . fileInfos , key ) ) {
988
+ fileInfos . set ( toPath ( key ) , program . fileInfos [ key ] ) ;
989
+ }
990
+ }
991
+
998
992
const state : ReusableBuilderProgramState = {
999
993
fileInfos,
1000
994
compilerOptions : program . options ,
1001
- referencedMap : getMapOfReferencedSet ( program . referencedMap ) ,
1002
- exportedModulesMap : getMapOfReferencedSet ( program . exportedModulesMap ) ,
995
+ referencedMap : getMapOfReferencedSet ( program . referencedMap , toPath ) ,
996
+ exportedModulesMap : getMapOfReferencedSet ( program . exportedModulesMap , toPath ) ,
1003
997
semanticDiagnosticsPerFile : program . semanticDiagnosticsPerFile && arrayToMap ( program . semanticDiagnosticsPerFile , value => isString ( value ) ? value : value [ 0 ] , value => isString ( value ) ? emptyArray : value [ 1 ] ) ,
1004
998
hasReusableDiagnostic : true
1005
999
} ;
@@ -1025,6 +1019,10 @@ namespace ts {
1025
1019
emitNextAffectedFile : notImplemented ,
1026
1020
getSemanticDiagnosticsOfNextAffectedFile : notImplemented ,
1027
1021
} ;
1022
+
1023
+ function toPath ( path : string ) {
1024
+ return ts . toPath ( path , buildInfoDirectory , getCanonicalFileName ) ;
1025
+ }
1028
1026
}
1029
1027
1030
1028
export function createRedirectedBuilderProgram ( state : { program : Program | undefined ; compilerOptions : CompilerOptions ; } , configFileParsingDiagnostics : ReadonlyArray < Diagnostic > ) : BuilderProgram {
0 commit comments