Skip to content

Commit 3e5466e

Browse files
committed
Read log file or requests file if supplied as input
1 parent 9f18c3f commit 3e5466e

File tree

11 files changed

+322
-52
lines changed

11 files changed

+322
-52
lines changed

src/compiler/builder.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ import {
8181
WriteFileCallback,
8282
WriteFileCallbackData,
8383
} from "./_namespaces/ts";
84+
import * as performance from "./_namespaces/ts.performance";
8485

8586
/** @internal */
8687
export interface ReusableDiagnostic extends ReusableDiagnosticRelatedInformation {
@@ -966,10 +967,18 @@ export function isProgramBundleEmitBuildInfo(info: ProgramBuildInfo): info is Pr
966967
return !!outFile(info.options || {});
967968
}
968969

970+
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined) {
971+
performance.mark("beforeGetProgramBuildInfo");
972+
const result = getBuildInfoWorker(state, bundle);
973+
performance.mark("afterGetProgramBuildInfo");
974+
performance.measure("BuildInfo generation", "beforeGetProgramBuildInfo", "afterGetProgramBuildInfo");
975+
return result;
976+
}
977+
969978
/**
970979
* Gets the program information to be emitted in buildInfo so that we can use it to create new program
971980
*/
972-
function getBuildInfo(state: BuilderProgramState, bundle: BundleBuildInfo | undefined): BuildInfo {
981+
function getBuildInfoWorker(state: BuilderProgramState, bundle: BundleBuildInfo | undefined): BuildInfo {
973982
const currentDirectory = Debug.checkDefined(state.program).getCurrentDirectory();
974983
const buildInfoDirectory = getDirectoryPath(getNormalizedAbsolutePath(getTsBuildInfoEmitOutputFilePath(state.compilerOptions)!, currentDirectory));
975984
// Convert the file name to Path here if we set the fileName instead to optimize multiple d.ts file emits and having to compute Canonical path

src/compiler/emitter.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -829,8 +829,13 @@ export function emitFiles(resolver: EmitResolver, host: EmitHost, targetSourceFi
829829
return;
830830
}
831831
const buildInfo = host.getBuildInfo(bundle) || createBuildInfo(/*program*/ undefined, bundle);
832+
performance.mark("beforeBuildInfoStringify");
833+
const buildInfoText = getBuildInfoText(buildInfo);
834+
performance.mark("afterBuildInfoStringify");
835+
performance.measure("BuildInfo stringify", "beforeBuildInfoStringify", "afterBuildInfoStringify");
836+
host.buildInfoCallbacks?.onWrite(buildInfoText.length);
832837
// Pass buildinfo as additional data to avoid having to reparse
833-
writeFile(host, emitterDiagnostics, buildInfoPath, getBuildInfoText(buildInfo), /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
838+
writeFile(host, emitterDiagnostics, buildInfoPath, buildInfoText, /*writeByteOrderMark*/ false, /*sourceFiles*/ undefined, { buildInfo });
834839
}
835840

836841
function emitJsFileOrBundle(
@@ -1229,7 +1234,7 @@ function emitUsingBuildInfoWorker(
12291234
): EmitUsingBuildInfoResult {
12301235
const { buildInfoPath, jsFilePath, sourceMapFilePath, declarationFilePath, declarationMapPath } = getOutputPathsForBundle(config.options, /*forceDtsPaths*/ false);
12311236
// If host directly provides buildinfo we can get it directly. This allows host to cache the buildinfo
1232-
const buildInfo = host.getBuildInfo!(buildInfoPath!, config.options.configFilePath);
1237+
const buildInfo = host.getBuildInfo!(buildInfoPath!, config.options);
12331238
if (!buildInfo) return buildInfoPath!;
12341239
if (!buildInfo.bundle || !buildInfo.bundle.js || (declarationFilePath && !buildInfo.bundle.dts)) return buildInfoPath!;
12351240

@@ -1330,6 +1335,7 @@ function emitUsingBuildInfoWorker(
13301335
redirectTargetsMap: createMultiMap(),
13311336
getFileIncludeReasons: notImplemented,
13321337
createHash: maybeBind(host, host.createHash),
1338+
buildInfoCallbacks: host.buildInfoCallbacks,
13331339
};
13341340
emitFiles(
13351341
notImplementedResolver,

src/compiler/factory/nodeFactory.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7514,11 +7514,14 @@ export function createInputFilesWithFilePaths(
75147514
const getAndCacheBuildInfo = () => {
75157515
if (buildInfo === undefined && buildInfoPath) {
75167516
if (host?.getBuildInfo) {
7517-
buildInfo = host.getBuildInfo(buildInfoPath, options!.configFilePath) ?? false;
7517+
buildInfo = host.getBuildInfo(buildInfoPath, options!) ?? false;
75187518
}
75197519
else {
7520+
host?.buildInfoCallbacks?.onReadStart(options);
75207521
const result = textGetter(buildInfoPath);
7522+
host?.buildInfoCallbacks?.onReadText(result);
75217523
buildInfo = result !== undefined ? getBuildInfo(buildInfoPath, result) ?? false : false;
7524+
host?.buildInfoCallbacks?.onReadEnd();
75227525
}
75237526
}
75247527
return buildInfo || undefined;

src/compiler/program.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2518,6 +2518,7 @@ export function createProgram(rootNamesOrOptions: readonly string[] | CreateProg
25182518
redirectTargetsMap,
25192519
getFileIncludeReasons: program.getFileIncludeReasons,
25202520
createHash: maybeBind(host, host.createHash),
2521+
buildInfoCallbacks: host.buildInfoCallbacks,
25212522
};
25222523
}
25232524

src/compiler/tsbuildPublic.ts

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ export interface SolutionBuilderHostBase<T extends BuilderProgram> extends Progr
239239

240240
// TODO: To do better with watch mode and normal build mode api that creates program and emits files
241241
// This currently helps enable --diagnostics and --extendedDiagnostics
242-
afterProgramEmitAndDiagnostics?(program: T): void;
243-
/** @deprecated @internal */ beforeEmitBundle?(config: ParsedCommandLine): void;
244-
/** @deprecated @internal */ afterEmitBundle?(config: ParsedCommandLine): void;
242+
afterProgramEmitAndDiagnostics?(program: T, host?: CompilerHost): void;
243+
/** @deprecated @internal */ beforeEmitBundle?(config: ParsedCommandLine, host: CompilerHost): void;
244+
/** @deprecated @internal */ afterEmitBundle?(config: ParsedCommandLine, host: CompilerHost): void;
245245

246246
// For testing
247247
/** @internal */ now?(): Date;
@@ -465,7 +465,7 @@ function createSolutionBuilderState<T extends BuilderProgram>(watch: boolean, ho
465465
createTypeReferenceResolutionLoader,
466466
);
467467
}
468-
compilerHost.getBuildInfo = (fileName, configFilePath) => getBuildInfo(state, fileName, toResolvedConfigFilePath(state, configFilePath as ResolvedConfigFileName), /*modifiedTime*/ undefined);
468+
compilerHost.getBuildInfo = (fileName, options) => getBuildInfo(state, fileName, options, toResolvedConfigFilePath(state, options.configFilePath as ResolvedConfigFileName), /*modifiedTime*/ undefined);
469469

470470
const { watchFile, watchDirectory, writeLog } = createWatchFactory<ResolvedConfigFileName>(hostWithWatch, options);
471471

@@ -1125,6 +1125,8 @@ function createBuildOrUpdateInvalidedProject<T extends BuilderProgram>(
11251125
// Don't emit .d.ts if there are decl file errors
11261126
if (declDiagnostics) {
11271127
program.restoreEmitState(saved);
1128+
// Revert buildInfo write size
1129+
state.compilerHost.buildInfoCallbacks?.revertLastWrite();
11281130
({ buildResult, step } = buildErrors(
11291131
state,
11301132
projectPath,
@@ -1142,6 +1144,7 @@ function createBuildOrUpdateInvalidedProject<T extends BuilderProgram>(
11421144

11431145
// Actual Emit
11441146
const { host, compilerHost } = state;
1147+
compilerHost.buildInfoCallbacks?.clearLastWrite();
11451148
const resultFlags = program.hasChangedEmitSignature?.() ? BuildResultFlags.None : BuildResultFlags.DeclarationOutputUnchanged;
11461149
const emitterDiagnostics = createDiagnosticCollection();
11471150
const emittedOutputs = new Map<Path, string>();
@@ -1244,7 +1247,7 @@ function createBuildOrUpdateInvalidedProject<T extends BuilderProgram>(
12441247
// Update js, and source map
12451248
const { compilerHost } = state;
12461249
state.projectCompilerOptions = config.options;
1247-
state.host.beforeEmitBundle?.(config);
1250+
state.host.beforeEmitBundle?.(config, compilerHost);
12481251
const outputFiles = emitUsingBuildInfo(
12491252
config,
12501253
compilerHost,
@@ -1525,12 +1528,12 @@ function afterProgramDone<T extends BuilderProgram>(
15251528
if (program) {
15261529
if (state.write) listFiles(program, state.write);
15271530
if (state.host.afterProgramEmitAndDiagnostics) {
1528-
state.host.afterProgramEmitAndDiagnostics(program);
1531+
state.host.afterProgramEmitAndDiagnostics(program, state.compilerHost);
15291532
}
15301533
program.releaseProgram();
15311534
}
15321535
else if (state.host.afterEmitBundle) {
1533-
state.host.afterEmitBundle(config);
1536+
state.host.afterEmitBundle(config, state.compilerHost);
15341537
}
15351538
state.projectCompilerOptions = state.baseCompilerOptions;
15361539
}
@@ -1653,14 +1656,24 @@ function getBuildInfoCacheEntry<T extends BuilderProgram>(state: SolutionBuilder
16531656
return existing?.path === path ? existing : undefined;
16541657
}
16551658

1656-
function getBuildInfo<T extends BuilderProgram>(state: SolutionBuilderState<T>, buildInfoPath: string, resolvedConfigPath: ResolvedConfigFilePath, modifiedTime: Date | undefined): BuildInfo | undefined {
1659+
function getBuildInfo<T extends BuilderProgram>(
1660+
state: SolutionBuilderState<T>,
1661+
buildInfoPath: string,
1662+
options: CompilerOptions,
1663+
resolvedConfigPath: ResolvedConfigFilePath,
1664+
modifiedTime: Date | undefined,
1665+
): BuildInfo | undefined {
16571666
const path = toPath(state, buildInfoPath);
16581667
const existing = state.buildInfoCache.get(resolvedConfigPath);
16591668
if (existing !== undefined && existing.path === path) {
16601669
return existing.buildInfo || undefined;
16611670
}
1671+
const host = (modifiedTime ? state.host : state.compilerHost);
1672+
host.buildInfoCallbacks?.onReadStart(options);
16621673
const value = state.readFileWithCache(buildInfoPath);
1674+
host.buildInfoCallbacks?.onReadText(value);
16631675
const buildInfo = value ? ts_getBuildInfo(buildInfoPath, value) : undefined;
1676+
host.buildInfoCallbacks?.onReadEnd();
16641677
state.buildInfoCache.set(resolvedConfigPath, { path, buildInfo: buildInfo || false, modifiedTime: modifiedTime || missingFileModifiedTime });
16651678
return buildInfo;
16661679
}
@@ -1750,7 +1763,7 @@ function getUpToDateStatusWorker<T extends BuilderProgram>(state: SolutionBuilde
17501763
};
17511764
}
17521765

1753-
const buildInfo = getBuildInfo(state, buildInfoPath, resolvedPath, buildInfoTime);
1766+
const buildInfo = getBuildInfo(state, buildInfoPath, project.options, resolvedPath, buildInfoTime);
17541767
if (!buildInfo) {
17551768
// Error reading buildInfo
17561769
return {

src/compiler/types.ts

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7706,6 +7706,16 @@ export type HasInvalidatedResolutions = (sourceFile: Path) => boolean;
77067706
/** @internal */
77077707
export type HasChangedAutomaticTypeDirectiveNames = () => boolean;
77087708

7709+
/** @internal */
7710+
export interface BuildInfoCallbacks {
7711+
onReadStart(compilerOptions: CompilerOptions | undefined): void;
7712+
onReadText(text: string | undefined): void;
7713+
onReadEnd(): void;
7714+
onWrite(size: number): void;
7715+
revertLastWrite(): void;
7716+
clearLastWrite(): void;
7717+
}
7718+
77097719
export interface CompilerHost extends ModuleResolutionHost {
77107720
getSourceFile(fileName: string, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
77117721
getSourceFileByPath?(fileName: string, path: Path, languageVersionOrOptions: ScriptTarget | CreateSourceFileOptions, onError?: (message: string) => void, shouldCreateNewSourceFile?: boolean): SourceFile | undefined;
@@ -7770,7 +7780,8 @@ export interface CompilerHost extends ModuleResolutionHost {
77707780

77717781
// For testing:
77727782
/** @internal */ storeFilesChangingSignatureDuringEmit?: boolean;
7773-
/** @internal */ getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined;
7783+
/** @internal */ getBuildInfo?(fileName: string, options: CompilerOptions): BuildInfo | undefined;
7784+
/** @internal */ buildInfoCallbacks?: BuildInfoCallbacks;
77747785
}
77757786

77767787
/** true if --out otherwise source file name *
@@ -8091,6 +8102,7 @@ export interface EmitHost extends ScriptReferenceHost, ModuleSpecifierResolution
80918102
getSourceFileFromReference: Program["getSourceFileFromReference"];
80928103
readonly redirectTargetsMap: RedirectTargetsMap;
80938104
createHash?(data: string): string;
8105+
buildInfoCallbacks: BuildInfoCallbacks | undefined;
80948106
}
80958107

80968108
/** @internal */

src/compiler/watch.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -763,6 +763,7 @@ export function createCompilerHostFromProgramHost(host: ProgramHost<any>, getCom
763763
createHash: maybeBind(host, host.createHash),
764764
readDirectory: maybeBind(host, host.readDirectory),
765765
storeFilesChangingSignatureDuringEmit: host.storeFilesChangingSignatureDuringEmit,
766+
buildInfoCallbacks: host.buildInfoCallbacks,
766767
};
767768
return compilerHost;
768769
}

src/compiler/watchPublic.ts

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
BuilderProgram,
33
BuildInfo,
4+
BuildInfoCallbacks,
45
canJsonReportNoInputFiles,
56
changeCompilerHostLikeToUseCache,
67
changesAffectModuleResolution,
@@ -98,20 +99,23 @@ export interface ReadBuildProgramHost {
9899
getCurrentDirectory(): string;
99100
readFile(fileName: string): string | undefined;
100101
/** @internal */
101-
getBuildInfo?(fileName: string, configFilePath: string | undefined): BuildInfo | undefined;
102+
getBuildInfo?(fileName: string, options: CompilerOptions): BuildInfo | undefined;
103+
/** @internal */ buildInfoCallbacks?: BuildInfoCallbacks;
102104
}
103105
export function readBuilderProgram(compilerOptions: CompilerOptions, host: ReadBuildProgramHost) {
104106
const buildInfoPath = getTsBuildInfoEmitOutputFilePath(compilerOptions);
105107
if (!buildInfoPath) return undefined;
106108
let buildInfo;
107109
if (host.getBuildInfo) {
108110
// host provides buildinfo, get it from there. This allows host to cache it
109-
buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions.configFilePath);
111+
buildInfo = host.getBuildInfo(buildInfoPath, compilerOptions);
110112
}
111113
else {
114+
host.buildInfoCallbacks?.onReadStart(compilerOptions);
112115
const content = host.readFile(buildInfoPath);
113-
if (!content) return undefined;
114-
buildInfo = getBuildInfo(buildInfoPath, content);
116+
host.buildInfoCallbacks?.onReadText(content);
117+
buildInfo = content ? getBuildInfo(buildInfoPath, content) : undefined;
118+
host.buildInfoCallbacks?.onReadEnd();
115119
}
116120
if (!buildInfo || buildInfo.version !== version || !buildInfo.program) return undefined;
117121
return createBuilderProgramUsingProgramBuildInfo(buildInfo, buildInfoPath, host);
@@ -245,6 +249,7 @@ export interface ProgramHost<T extends BuilderProgram> {
245249
// TODO: GH#18217 Optional methods are frequently asserted
246250
createDirectory?(path: string): void;
247251
writeFile?(path: string, data: string, writeByteOrderMark?: boolean): void;
252+
buildInfoCallbacks?: BuildInfoCallbacks;
248253
// For testing
249254
storeFilesChangingSignatureDuringEmit?: boolean;
250255
now?(): Date;
@@ -258,7 +263,7 @@ export interface WatchCompilerHost<T extends BuilderProgram> extends ProgramHost
258263
getParsedCommandLine?(fileName: string): ParsedCommandLine | undefined;
259264

260265
/** If provided, callback to invoke after every new program creation */
261-
afterProgramCreate?(program: T): void;
266+
afterProgramCreate?(program: T, host?: CompilerHost): void;
262267
}
263268

264269
/**
@@ -611,7 +616,7 @@ export function createWatchProgram<T extends BuilderProgram>(host: WatchCompiler
611616

612617
reportFileChangeDetectedOnCreateProgram = false;
613618
if (host.afterProgramCreate && program !== builderProgram) {
614-
host.afterProgramCreate(builderProgram);
619+
host.afterProgramCreate(builderProgram, compilerHost);
615620
}
616621

617622
compilerHost.readFile = originalReadFile;

0 commit comments

Comments
 (0)