Skip to content

Commit 47f5106

Browse files
committed
Use oldProgram to create the new Program.
This helps in storing the semantic diagnostics
1 parent 69193d9 commit 47f5106

File tree

4 files changed

+53
-19
lines changed

4 files changed

+53
-19
lines changed

src/compiler/builder.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ namespace ts {
410410
/**
411411
* Computing hash to for signature verification
412412
*/
413-
const computeHash = host.createHash || identity;
413+
const computeHash = host.createHash || generateDjb2Hash;
414414
const state = createBuilderProgramState(newProgram, getCanonicalFileName, oldState);
415415

416416
// To ensure that we arent storing any references to old program or new program without state

src/compiler/builderState.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -505,14 +505,14 @@ namespace ts.BuilderState {
505505

506506
// Start with the paths this file was referenced by
507507
seenFileNamesMap.set(sourceFileWithUpdatedShape.path, sourceFileWithUpdatedShape);
508-
const queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.path);
508+
const queue = getReferencedByPaths(state, sourceFileWithUpdatedShape.resolvedPath);
509509
while (queue.length > 0) {
510510
const currentPath = queue.pop()!;
511511
if (!seenFileNamesMap.has(currentPath)) {
512512
const currentSourceFile = programOfThisState.getSourceFileByPath(currentPath)!;
513513
seenFileNamesMap.set(currentPath, currentSourceFile);
514514
if (currentSourceFile && updateShapeSignature(state, programOfThisState, currentSourceFile, cacheToUpdateSignature, cancellationToken, computeHash!, exportedModulesMapCache)) { // TODO: GH#18217
515-
queue.push(...getReferencedByPaths(state, currentPath));
515+
queue.push(...getReferencedByPaths(state, currentSourceFile.resolvedPath));
516516
}
517517
}
518518
}

src/compiler/sys.ts

+10-9
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,16 @@ declare function setTimeout(handler: (...args: any[]) => void, timeout: number):
22
declare function clearTimeout(handle: any): void;
33

44
namespace ts {
5+
/**
6+
* djb2 hashing algorithm
7+
* http://www.cse.yorku.ca/~oz/hash.html
8+
*/
9+
/* @internal */
10+
export function generateDjb2Hash(data: string): string {
11+
const chars = data.split("").map(str => str.charCodeAt(0));
12+
return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`;
13+
}
14+
515
/**
616
* Set a high stack trace limit to provide more information in case of an error.
717
* Called for command-line and server use cases.
@@ -1115,15 +1125,6 @@ namespace ts {
11151125
}
11161126
}
11171127

1118-
/**
1119-
* djb2 hashing algorithm
1120-
* http://www.cse.yorku.ca/~oz/hash.html
1121-
*/
1122-
function generateDjb2Hash(data: string): string {
1123-
const chars = data.split("").map(str => str.charCodeAt(0));
1124-
return `${chars.reduce((prev, curr) => ((prev << 5) + prev) + curr, 5381)}`;
1125-
}
1126-
11271128
function createMD5HashUsingNativeCrypto(data: string): string {
11281129
const hash = _crypto!.createHash("md5");
11291130
hash.update(data);

src/compiler/tsbuild.ts

+40-7
Original file line numberDiff line numberDiff line change
@@ -434,8 +434,12 @@ namespace ts {
434434
let readFileWithCache = (f: string) => host.readFile(f);
435435
let projectCompilerOptions = baseCompilerOptions;
436436
const compilerHost = createCompilerHostFromProgramHost(host, () => projectCompilerOptions);
437+
const originalGetSourceFile = compilerHost.getSourceFile;
438+
const computeHash = host.createHash || generateDjb2Hash;
439+
updateGetSourceFile();
437440

438441
// Watch state
442+
const builderPrograms = createFileMap<T>(toPath);
439443
const diagnostics = createFileMap<ReadonlyArray<Diagnostic>>(toPath);
440444
const projectPendingBuild = createFileMap<ConfigFileProgramReloadLevel>(toPath);
441445
const projectErrorsReported = createFileMap<true>(toPath);
@@ -493,6 +497,29 @@ namespace ts {
493497
clearMap(allWatchedWildcardDirectories, wildCardWatches => clearMap(wildCardWatches, closeFileWatcherOf));
494498
clearMap(allWatchedInputFiles, inputFileWatches => clearMap(inputFileWatches, closeFileWatcher));
495499
clearMap(allWatchedConfigFiles, closeFileWatcher);
500+
if (!options.watch) {
501+
builderPrograms.clear();
502+
}
503+
updateGetSourceFile();
504+
}
505+
506+
function updateGetSourceFile() {
507+
if (options.watch) {
508+
if (compilerHost.getSourceFile === originalGetSourceFile) {
509+
compilerHost.getSourceFile = (...args) => {
510+
const result = originalGetSourceFile.call(compilerHost, ...args);
511+
if (result && options.watch) {
512+
result.version = computeHash.call(host, result.text);
513+
}
514+
return result;
515+
};
516+
}
517+
}
518+
else {
519+
if (compilerHost.getSourceFile !== originalGetSourceFile) {
520+
compilerHost.getSourceFile = originalGetSourceFile;
521+
}
522+
}
496523
}
497524

498525
function isParsedCommandLine(entry: ConfigFileCacheEntry): entry is ParsedCommandLine {
@@ -1057,7 +1084,7 @@ namespace ts {
10571084
configFile.fileNames,
10581085
configFile.options,
10591086
compilerHost,
1060-
/*oldProgram*/ undefined,
1087+
builderPrograms.getValue(proj),
10611088
configFile.errors,
10621089
configFile.projectReferences
10631090
);
@@ -1123,22 +1150,28 @@ namespace ts {
11231150
};
11241151
diagnostics.removeKey(proj);
11251152
projectStatus.setValue(proj, status);
1126-
if (host.afterProgramEmitAndDiagnostics) {
1127-
host.afterProgramEmitAndDiagnostics(program);
1128-
}
1153+
afterProgramCreate(proj, program);
11291154
return resultFlags;
11301155

11311156
function buildErrors(diagnostics: ReadonlyArray<Diagnostic>, errorFlags: BuildResultFlags, errorType: string) {
11321157
resultFlags |= errorFlags;
11331158
reportAndStoreErrors(proj, diagnostics);
11341159
projectStatus.setValue(proj, { type: UpToDateStatusType.Unbuildable, reason: `${errorType} errors` });
1135-
if (host.afterProgramEmitAndDiagnostics) {
1136-
host.afterProgramEmitAndDiagnostics(program);
1137-
}
1160+
afterProgramCreate(proj, program);
11381161
return resultFlags;
11391162
}
11401163
}
11411164

1165+
function afterProgramCreate(proj: ResolvedConfigFileName, program: T) {
1166+
if (host.afterProgramEmitAndDiagnostics) {
1167+
host.afterProgramEmitAndDiagnostics(program);
1168+
}
1169+
if (options.watch) {
1170+
program.releaseProgram();
1171+
builderPrograms.setValue(proj, program);
1172+
}
1173+
}
1174+
11421175
function updateOutputTimestamps(proj: ParsedCommandLine) {
11431176
if (options.dry) {
11441177
return reportStatus(Diagnostics.A_non_dry_build_would_build_project_0, proj.options.configFilePath!);

0 commit comments

Comments
 (0)