@@ -74,6 +74,7 @@ import {
74
74
OldBuildInfoProgramConstructor ,
75
75
OldBuildInfoProgramHost ,
76
76
outFile ,
77
+ PackageJsonInfo ,
77
78
Path ,
78
79
PerDirectoryAndNonRelativeNameCache ,
79
80
Program ,
@@ -179,6 +180,7 @@ export interface ReusableBuilderProgramState extends BuilderState {
179
180
cacheResolutions ?: {
180
181
modules : PerDirectoryAndNonRelativeNameCache < ResolvedModuleWithFailedLookupLocations > | undefined ;
181
182
typeRefs : PerDirectoryAndNonRelativeNameCache < ResolvedTypeReferenceDirectiveWithFailedLookupLocations > | undefined ;
183
+ packageJsonCache : Map < Path , PackageJsonInfo | boolean > | undefined ;
182
184
} ;
183
185
resuableCacheResolutions ?: {
184
186
cache : ProgramBuildInfoCacheResolutions ;
@@ -960,6 +962,8 @@ export interface ProgramBuildInfoResolution {
960
962
readonly resolutionDiagnostics : readonly ReusableDiagnostic [ ] | undefined ;
961
963
}
962
964
/** @internal */
965
+ export type ProgramBuildInfoHash = ProgramBuildInfoAbsoluteFileId | [ fileId : ProgramBuildInfoAbsoluteFileId , hash : string ] ;
966
+ /** @internal */
963
967
export type ProgramBuildInfoResolutionId = number & { __programBuildInfoResolutionIdBrand : any } ;
964
968
/** @internal */
965
969
export type ProgramBuildInfoResolutionNameId = number & { __programBuildInfoResolutionNameIdBrand : any } ;
@@ -983,6 +987,7 @@ export type ProgramBuildInfoResolutionCacheWithRedirects = ProgramBuildInfoResol
983
987
export interface ProgramBuildInfoCacheResolutions {
984
988
resolutions : readonly ProgramBuildInfoResolution [ ] ;
985
989
names : readonly string [ ] ;
990
+ hash : readonly ProgramBuildInfoHash [ ] | undefined ;
986
991
resolutionEntries : readonly ProgramBuildInfoResolutionEntry [ ] ;
987
992
modules : ProgramBuildInfoResolutionCacheWithRedirects | undefined ;
988
993
typeRefs : ProgramBuildInfoResolutionCacheWithRedirects | undefined ;
@@ -1038,7 +1043,7 @@ export function isProgramBundleEmitBuildInfo(info: ProgramBuildInfo): info is Pr
1038
1043
/**
1039
1044
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
1040
1045
*/
1041
- function getBuildInfo ( state : BuilderProgramState , bundle : BundleBuildInfo | undefined , buildInfoPath : string , ) : BuildInfo {
1046
+ function getBuildInfo ( state : BuilderProgramState , host : BuilderProgramHost , bundle : BundleBuildInfo | undefined , buildInfoPath : string , ) : BuildInfo {
1042
1047
const currentDirectory = Debug . checkDefined ( state . program ) . getCurrentDirectory ( ) ;
1043
1048
buildInfoPath = getNormalizedAbsolutePath ( buildInfoPath , currentDirectory ) ;
1044
1049
const buildInfoDirectory = getDirectoryPath ( buildInfoPath ) ;
@@ -1052,6 +1057,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
1052
1057
let resolutionNameToResolutionNameId : Map < string , ProgramBuildInfoResolutionNameId > | undefined ;
1053
1058
let resolutionEntries : ProgramBuildInfoResolutionEntry [ ] | undefined ;
1054
1059
let resolutionEntryToResolutionEntryId : Map < string , ProgramBuildInfoResolutionEntryId > | undefined ;
1060
+ let affectedFilesHash : Map < ProgramBuildInfoAbsoluteFileId , string | undefined > | undefined ;
1055
1061
if ( outFile ( state . compilerOptions ) ) {
1056
1062
// Copy all fileInfo, version and impliedFormat
1057
1063
// Affects global scope and signature doesnt matter because with --out they arent calculated or needed to determine upto date ness
@@ -1309,6 +1315,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
1309
1315
cache : {
1310
1316
resolutions,
1311
1317
names,
1318
+ hash : toProgramBuildInfoHashes ( ) ,
1312
1319
resolutionEntries,
1313
1320
modules,
1314
1321
typeRefs,
@@ -1397,11 +1404,32 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
1397
1404
return {
1398
1405
resolvedModule : toProgramBuildInfoResolved ( ( resolution as ResolvedModuleWithFailedLookupLocations ) . resolvedModule ) ,
1399
1406
resolvedTypeReferenceDirective : toProgramBuildInfoResolved ( ( resolution as ResolvedTypeReferenceDirectiveWithFailedLookupLocations ) . resolvedTypeReferenceDirective ) ,
1400
- affectingLocations : toReadonlyArrayOrUndefined ( resolution . affectingLocations , toAbsoluteFileId ) ,
1407
+ affectingLocations : toReadonlyArrayOrUndefined ( resolution . affectingLocations , toAffectedFileId ) ,
1401
1408
resolutionDiagnostics : toReadonlyArrayOrUndefined ( resolution . resolutionDiagnostics , toReusableDiagnostic ) ,
1402
1409
} ;
1403
1410
}
1404
1411
1412
+ function toProgramBuildInfoHashes ( ) : readonly ProgramBuildInfoHash [ ] | undefined {
1413
+ if ( ! affectedFilesHash ) return undefined ;
1414
+ const hashes : ProgramBuildInfoHash [ ] = [ ] ;
1415
+ for ( const key of arrayFrom ( affectedFilesHash . keys ( ) ) . sort ( compareValues ) ) {
1416
+ const value = affectedFilesHash . get ( key ) ;
1417
+ hashes . push ( value ? [ key , value ] : key ) ;
1418
+ }
1419
+ return hashes ;
1420
+ }
1421
+
1422
+ function toAffectedFileId ( file : string ) {
1423
+ const fileId = toAbsoluteFileId ( file ) ;
1424
+ if ( ! affectedFilesHash ?. has ( fileId ) ) {
1425
+ // Store the file hash
1426
+ const packageJsonInfo = state . program ! . getModuleResolutionCache ( ) ?. getPackageJsonInfo ( file ) ;
1427
+ const text = typeof packageJsonInfo === "object" ? packageJsonInfo . contents . packageJsonText : undefined ;
1428
+ ( affectedFilesHash ??= new Map ( ) ) . set ( fileId , text ? ( host . createHash ?? generateDjb2Hash ) ( text ) : undefined ) ;
1429
+ }
1430
+ return fileId ;
1431
+ }
1432
+
1405
1433
function toProgramBuildInfoResolved ( resolved : ResolvedModuleFull | undefined ) : ProgramBuildInfoResolvedModuleFull | undefined ;
1406
1434
function toProgramBuildInfoResolved ( resolved : ResolvedTypeReferenceDirective | undefined ) : ProgramBuildInfoResolvedTypeReferenceDirective | undefined ;
1407
1435
function toProgramBuildInfoResolved ( resolved : ResolvedModuleFull | ResolvedTypeReferenceDirective | undefined ) : ProgramBuildInfoResolvedModuleFull | ProgramBuildInfoResolvedTypeReferenceDirective | undefined {
@@ -1429,7 +1457,12 @@ function getCacheResolutions(state: BuilderProgramState) {
1429
1457
const containingPath = toPath ( state . program ! . getAutomaticTypeDirectiveContainingFile ( ) , state . program ! . getCurrentDirectory ( ) , state . program ! . getCanonicalFileName ) ;
1430
1458
typeRefs = toPerDirectoryAndNonRelativeNameCache ( state , typeRefs , getOriginalOrResolvedTypeReferenceFileName , state . program ! . getAutomaticTypeDirectiveResolutions ( ) , containingPath ) ;
1431
1459
}
1432
- return state . cacheResolutions = { modules, typeRefs } ;
1460
+ const packageJsonMap = state . program ! . getModuleResolutionCache ( ) ?. getPackageJsonInfoCache ( ) . getInternalMap ( ) ;
1461
+ return state . cacheResolutions = {
1462
+ modules,
1463
+ typeRefs,
1464
+ packageJsonCache : packageJsonMap && new Map ( packageJsonMap ) ,
1465
+ } ;
1433
1466
}
1434
1467
1435
1468
function toPerDirectoryAndNonRelativeNameCache < T > (
@@ -1566,7 +1599,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
1566
1599
}
1567
1600
1568
1601
const state = createBuilderProgramState ( newProgram , oldState ) ;
1569
- newProgram . getBuildInfo = ( bundle , buildInfoPath ) => getBuildInfo ( state , bundle , buildInfoPath ) ;
1602
+ newProgram . getBuildInfo = ( bundle , buildInfoPath ) => getBuildInfo ( state , host , bundle , buildInfoPath ) ;
1570
1603
1571
1604
// To ensure that we arent storing any references to old program or new program without state
1572
1605
newProgram = undefined ! ; // TODO: GH#18217
0 commit comments