8000 Store package json hash in buildinfo · microsoft/TypeScript@e1ed9ea · GitHub
[go: up one dir, main page]

Skip to content

Commit e1ed9ea

Browse files
committed
Store package json hash in buildinfo
1 parent 6261b6c commit e1ed9ea

File tree

14 files changed

+1182
-122
lines changed

14 files changed

+1182
-122
lines changed

src/compiler/builder.ts

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ import {
7474
OldBuildInfoProgramConstructor,
7575
OldBuildInfoProgramHost,
7676
outFile,
77+
PackageJsonInfo,
7778
Path,
7879
PerDirectoryAndNonRelativeNameCache,
7980
Program,
@@ -179,6 +180,7 @@ export interface ReusableBuilderProgramState extends BuilderState {
179180
cacheResolutions?: {
180181
modules: PerDirectoryAndNonRelativeNameCache<ResolvedModuleWithFailedLookupLocations> | undefined;
181182
typeRefs: PerDirectoryAndNonRelativeNameCache<ResolvedTypeReferenceDirectiveWithFailedLookupLocations> | undefined;
183+
packageJsonCache: Map<Path, PackageJsonInfo | boolean> | undefined;
182184
};
183185
resuableCacheResolutions?: {
184186
cache: ProgramBuildInfoCacheResolutions;
@@ -960,6 +962,8 @@ export interface ProgramBuildInfoResolution {
960962
readonly resolutionDiagnostics: readonly ReusableDiagnostic[] | undefined;
961963
}
962964
/** @internal */
965+
export type ProgramBuildInfoHash = ProgramBuildInfoAbsoluteFileId | [fileId: ProgramBuildInfoAbsoluteFileId, hash: string];
966+
/** @internal */
963967
export type ProgramBuildInfoResolutionId = number & { __programBuildInfoResolutionIdBrand: any };
964968
/** @internal */
965969
export type ProgramBuildInfoResolutionNameId = number & { __programBuildInfoResolutionNameIdBrand: any };
@@ -983,6 +987,7 @@ export type ProgramBuildInfoResolutionCacheWithRedirects = ProgramBuildInfoResol
983987
export interface ProgramBuildInfoCacheResolutions {
984988
resolutions: readonly ProgramBuildInfoResolution[];
985989
names: readonly string[];
990+
hash: readonly ProgramBuildInfoHash[] | undefined;
986991
resolutionEntries: readonly ProgramBuildInfoResolutionEntry[];
987992
modules: ProgramBuildInfoResolutionCacheWithRedirects | undefined;
988993
typeRefs: ProgramBuildInfoResolutionCacheWithRedirects | undefined;
@@ -1038,7 +1043,7 @@ export function isProgramBundleEmitBuildInfo(info: ProgramBuildInfo): info is Pr
10381043
/**
10391044
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
10401045
*/
1041-
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined, buildInfoPath: string,): BuildInfo {
1046+
function getBuildInfo(state: BuilderProgramState, host: BuilderProgramHost, bundle: BundleBuildInfo | undefined, buildInfoPath: string,): BuildInfo {
10421047
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
10431048
buildInfoPath = getNormalizedAbsolutePath(buildInfoPath, currentDirectory);
10441049
const buildInfoDirectory = getDirectoryPath(buildInfoPath);
@@ -1052,6 +1057,7 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
10521057
let resolutionNameToResolutionNameId: Map<string, ProgramBuildInfoResolutionNameId> | undefined;
10531058
let resolutionEntries: ProgramBuildInfoResolutionEntry[] | undefined;
10541059
let resolutionEntryToResolutionEntryId: Map<string, ProgramBuildInfoResolutionEntryId> | undefined;
1060+
let affectedFilesHash: Map<ProgramBuildInfoAbsoluteFileId, string | undefined> | undefined;
10551061
if (outFile(state.compilerOptions)) {
10561062
// Copy all fileInfo, version and impliedFormat
10571063
// 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
13091315
cache: {
13101316
resolutions,
13111317
names,
1318+
hash: toProgramBuildInfoHashes(),
13121319
resolutionEntries,
13131320
modules,
13141321
typeRefs,
@@ -1397,11 +1404,32 @@ function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | unde
13971404
return {
13981405
resolvedModule: toProgramBuildInfoResolved((resolution as ResolvedModuleWithFailedLookupLocations).resolvedModule),
13991406
resolvedTypeReferenceDirective: toProgramBuildInfoResolved((resolution as ResolvedTypeReferenceDirectiveWithFailedLookupLocations).resolvedTypeReferenceDirective),
1400-
affectingLocations: toReadonlyArrayOrUndefined(resolution.affectingLocations, toAbsoluteFileId),
1407+
affectingLocations: toReadonlyArrayOrUndefined(resolution.affectingLocations, toAffectedFileId),
14011408
resolutionDiagnostics: toReadonlyArrayOrUndefined(resolution.resolutionDiagnostics, toReusableDiagnostic),
14021409
};
14031410
}
14041411

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+
14051433
function toProgramBuildInfoResolved(resolved: ResolvedModuleFull | undefined): ProgramBuildInfoResolvedModuleFull | undefined;
14061434
function toProgramBuildInfoResolved(resolved: ResolvedTypeReferenceDirective | undefined): ProgramBuildInfoResolvedTypeReferenceDirective | undefined;
14071435
function toProgramBuildInfoResolved(resolved: ResolvedModuleFull | ResolvedTypeReferenceDirective | undefined): ProgramBuildInfoResolvedModuleFull | ProgramBuildInfoResolvedTypeReferenceDirective | undefined {
@@ -1429,7 +1457,12 @@ function getCacheResolutions(state: BuilderProgramState) {
14291457
const containingPath = toPath(state.program!.getAutomaticTypeDirectiveContainingFile(), state.program!.getCurrentDirectory(), state.program!.getCanonicalFileName);
14301458
typeRefs = toPerDirectoryAndNonRelativeNameCache(state, typeRefs, getOriginalOrResolvedTypeReferenceFileName, state.program!.getAutomaticTypeDirectiveResolutions(), containingPath);
14311459
}
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+
};
14331466
}
14341467

14351468
function toPerDirectoryAndNonRelativeNameCache<T>(
@@ -1566,7 +1599,7 @@ export function createBuilderProgram(kind: BuilderProgramKind, { newProgram, hos
15661599
}
15671600

15681601
const state = createBuilderProgramState(newProgram, oldState);
1569-
newProgram.getBuildInfo = (bundle, buildInfoPath) => getBuildInfo(state, bundle, buildInfoPath);
1602+
newProgram.getBuildInfo = (bundle, buildInfoPath) => getBuildInfo(state, host, bundle, buildInfoPath);
15701603

15711604
// To ensure that we arent storing any references to old program or new program without state
15721605
newProgram = undefined!; // TODO: GH#18217

src/compiler/moduleNameResolver.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2170,6 +2170,7 @@ export interface PackageJsonInfo {
21702170
}
21712171
/** @internal */
21722172
export interface PackageJsonInfoContents {
2173+
packageJsonText: string | undefined;
21732174
packageJsonContent: PackageJsonPathFields;
21742175
/** false: versionPaths are not present. undefined: not yet resolved */
21752176
versionPaths: VersionPaths | false | undefined;
@@ -2228,11 +2229,12 @@ export function getPackageJsonInfo(packageDirectory: string, onlyRecordFailures:
22282229
}
22292230
const directoryExists = directoryProbablyExists(packageDirectory, host);
22302231
if (directoryExists && host.fileExists(packageJsonPath)) {
2231-
const packageJsonContent = readJson(packageJsonPath, host) as PackageJson;
2232+
const packageJsonText = host.readFile(packageJsonPath);
2233+
const packageJsonContent = readJson(packageJsonPath, packageJsonText) as PackageJson;
22322234
if (traceEnabled) {
22332235
trace(host, Diagnostics.Found_package_json_at_0, packageJsonPath);
22342236
}
2235-
const result: PackageJsonInfo = { packageDirectory, contents: { packageJsonContent, versionPaths: undefined, resolvedEntrypoints: undefined } };
2237+
const result: PackageJsonInfo = { packageDirectory, contents: { packageJsonText, packageJsonContent, versionPaths: undefined, resolvedEntrypoints: undefined } };
22362238
state.packageJsonInfoCache?.setPackageJsonInfo(packageJsonPath, result);
22372239
state.affectingLocations.push(packageJsonPath);
22382240
return result;

src/compiler/utilities.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6429,17 +6429,17 @@ export function base64decode(host: { base64decode?(input: string): string } | un
64296429
}
64306430

64316431
/** @internal */
6432-
export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string): object | undefined {
6433-
const jsonText = isString(hostOrText) ? hostOrText : hostOrText.readFile(path);
6432+
export function readJsonOrUndefined(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string | undefined): object | undefined {
6433+
const jsonText = isString(hostOrText) ? hostOrText : hostOrText?.readFile(path);
64346434
if (!jsonText) return undefined;
64356435
// gracefully handle if readFile fails or returns not JSON
64366436
const result = parseConfigFileTextToJson(path, jsonText);
64376437
return !result.error ? result.config : undefined;
64386438
}
64396439

64406440
/** @internal */
6441-
export function readJson(path: string, host: { readFile(fileName: string): string | undefined }): object {
6442-
return readJsonOrUndefined(path, host) || {};
6441+
export function readJson(path: string, hostOrText: { readFile(fileName: string): string | undefined } | string | undefined): object {
6442+
return readJsonOrUndefined(path, hostOrText) || {};
64436443
}
64446444

64456445
/** @internal */

src/testRunner/unittests/tsc/helpers.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -568,10 +568,12 @@ type ReadableProgramBuildInfoResolutionCacheWithRedirects = ReadableProgramBuild
568568
own: ReadableProgramBuildInfoResolutionCacheEntry[] | undefined;
569569
redirects: readonly ReadableProgramBuildInfoResolutionRedirectsCache[];
570570
};
571+
type ReadableProgramBuildInfoHash = string | [file: string, hash: string];
571572
type ReadableProgramBuildInfoCacheResolutions = Omit<ts.ProgramBuildInfoCacheResolutions,
572-
"resolutions" | "resolutionEntries" | "modules" | "typeRefs"
573+
"resolutions" | "hash" | "resolutionEntries" | "modules" | "typeRefs"
573574
> & {
574575
resolutions: readonly ReadableWithOriginal<ReadableProgramBuildInfoResolution, ts.ProgramBuildInfoResolution>[];
576+
hash: readonly ReadableProgramBuildInfoHash[] | undefined;
575577
resolutionEntries: readonly ReadableWithOriginal<ReadableProgramBuildInfoResolutionEntry, ts.ProgramBuildInfoResolutionEntry>[];
576578
modules: ReadableProgramBuildInfoResolutionCacheWithRedirects | undefined;
577579
typeRefs: ReadableProgramBuildInfoResolutionCacheWithRedirects | undefined;
@@ -751,10 +753,15 @@ function generateBuildInfoProgramBaseline(sys: ts.System, buildInfoPath: string,
751753
resolutions: resolutions.withOriginals,
752754
resolutionEntries: resolutionEntries.withOriginals,
753755
modules: toReadableProgramBuildInfoResolutionCacheWithRedirects(cacheResolutions.modules),
754-
typeRefs: toReadableProgramBuildInfoResolutionCacheWithRedirects(cacheResolutions.typeRefs)
756+
typeRefs: toReadableProgramBuildInfoResolutionCacheWithRedirects(cacheResolutions.typeRefs),
757+
hash: cacheResolutions.hash?.map(toReadableProgramBuildInfoHash),
755758
};
756759
}
757760

761+
function toReadableProgramBuildInfoHash(hash: ts.ProgramBuildInfoHash): ReadableProgramBuildInfoHash {
762+
return ts.isArray(hash) ? [toFileName(hash[0]), hash[1]] : toFileName(hash);
763+
}
764+
758765
function toReadableProgramBuildInfoResolutionCacheWithRedirects(cache: ts.ProgramBuildInfoResolutionCacheWithRedirects | undefined): ReadableProgramBuildInfoResolutionCacheWithRedirects | undefined {
759766
return cache ?
760767
ts.isArray(cache) ?

tests/baselines/reference/tsbuild/cacheResolutions/multi-file-discrepancies.js

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,20 @@ CleanBuild:
205205
"pkg3",
206206
"pkg4"
207207
],
208+
"hash": [
209+
[
210+
"./node_modules/pkg0/package.json",
211+
"9838425114-{\"name\":\"pkg0\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
212+
],
213+
[
214+
"./node_modules/pkg2/package.json",
215+
"21696956444-{\"name\":\"pkg2\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
216+
],
217+
[
218+
"./node_modules/pkg3/package.json",
219+
"1856418333-{\"name\":\"pkg3\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
220+
]
221+
],
208222
"resolutionEntries": [
209223
{
210224
"original": [
@@ -611,6 +625,24 @@ IncrementalBuild:
611625
"pkg3",
612626
"pkg4"
613627
],
628+
"hash": [
629+
[
630+
"./node_modules/pkg0/package.json",
631+
"9838425114-{\"name\":\"pkg0\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
632+
],
633+
[
634+
"./node_modules/pkg1/package.json",
635+
"-10723730036-{\"name\":\"pkg1\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require1.js\"}}"
636+
],
637+
[
638+
"./node_modules/pkg2/package.json",
639+
"21696956444-{\"name\":\"pkg2\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
640+
],
641+
[
642+
"./node_modules/pkg3/package.json",
643+
"1856418333-{\"name\":\"pkg3\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
644+
]
645+
],
614646
"resolutionEntries": [
615647
{
616648
"original": [
@@ -1077,6 +1109,24 @@ CleanBuild:
10771109
"pkg3",
10781110
"pkg4"
10791111
],
1112+
"hash": [
1113+
[
1114+
"./node_modules/pkg0/package.json",
1115+
"9838425114-{\"name\":\"pkg0\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1116+
],
1117+
[
1118+
"./node_modules/pkg1/package.json",
1119+
"-10723730036-{\"name\":\"pkg1\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require1.js\"}}"
1120+
],
1121+
[
1122+
"./node_modules/pkg2/package.json",
1123+
"21696956444-{\"name\":\"pkg2\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1124+
],
1125+
[
1126+
"./node_modules/pkg3/package.json",
1127+
"1856418333-{\"name\":\"pkg3\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1128+
]
1129+
],
10801130
"resolutionEntries": [
10811131
{
10821132
"original": [
@@ -1528,6 +1578,24 @@ IncrementalBuild:
15281578
"pkg3",
15291579
"pkg4"
15301580
],
1581+
"hash": [
1582+
[
1583+
"./node_modules/pkg0/package.json",
1584+
"9838425114-{\"name\":\"pkg0\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1585+
],
1586+
[
1587+
"./node_modules/pkg1/package.json",
1588+
"-10723730036-{\"name\":\"pkg1\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require1.js\"}}"
1589+
],
1590+
[
1591+
"./node_modules/pkg2/package.json",
1592+
"21696956444-{\"name\":\"pkg2\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1593+
],
1594+
[
1595+
"./node_modules/pkg3/package.json",
1596+
"1856418333-{\"name\":\"pkg3\",\"version\":\"0.0.1\",\"exports\":{\"import\":\"./import.js\",\"require\":\"./require.js\"}}"
1597+
]
1598+
],
15311599
"resolutionEntries": [
15321600
{
15331601
"original": [

0 commit comments

Comments
 (0)
0