Skip to content

Commit 2de171b

Browse files
committed
When trying to check if program is uptodate, read the files from disk to determine the version instead of delaying so that new program is not created if file contents have not changed
1 parent 0a01fcb commit 2de171b

17 files changed

+93
-928
lines changed

src/compiler/tsbuildPublic.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ namespace ts {
292292
// State of the solution
293293
const baseCompilerOptions = getCompilerOptionsOfBuildOptions(options);
294294
const compilerHost = createCompilerHostFromProgramHost(host, () => state.projectCompilerOptions) as CompilerHost & ReadBuildProgramHost;
295-
setGetSourceFileAsHashVersioned(compilerHost, host);
295+
setGetSourceFileAsHashVersioned(compilerHost);
296296
compilerHost.getParsedCommandLine = fileName => parseConfigFile(state, fileName as ResolvedConfigFileName, toResolvedConfigFilePath(state, fileName as ResolvedConfigFileName));
297297
compilerHost.resolveModuleNames = maybeBind(host, host.resolveModuleNames);
298298
compilerHost.resolveTypeReferenceDirectives = maybeBind(host, host.resolveTypeReferenceDirectives);

src/compiler/watch.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -595,12 +595,13 @@ namespace ts {
595595
export function createCompilerHostFromProgramHost(host: ProgramHost<any>, getCompilerOptions: () => CompilerOptions, directoryStructureHost: DirectoryStructureHost = host): CompilerHost {
596596
const useCaseSensitiveFileNames = host.useCaseSensitiveFileNames();
597597
const hostGetNewLine = memoize(() => host.getNewLine());
598-
return {
598+
const compilerHost: CompilerHost = {
599599
getSourceFile: (fileName, languageVersionOrOptions, onError) => {
600600
let text: string | undefined;
601601
try {
602602
performance.mark("beforeIORead");
603-
text = host.readFile(fileName, getCompilerOptions().charset);
603+
const encoding = getCompilerOptions().charset;
604+
text = !encoding ? compilerHost.readFile(fileName) : host.readFile(fileName, encoding);
604605
performance.mark("afterIORead");
605606
performance.measure("I/O Read", "beforeIORead", "afterIORead");
606607
}
@@ -632,6 +633,7 @@ namespace ts {
632633
disableUseFileVersionAsSignature: host.disableUseFileVersionAsSignature,
633634
storeFilesChangingSignatureDuringEmit: host.storeFilesChangingSignatureDuringEmit,
634635
};
636+
return compilerHost;
635637

636638
function writeFile(fileName: string, text: string, writeByteOrderMark: boolean, onError: (message: string) => void) {
637639
try {
@@ -659,9 +661,9 @@ namespace ts {
659661
}
660662
}
661663

662-
export function setGetSourceFileAsHashVersioned(compilerHost: CompilerHost, host: { createHash?(data: string): string; }) {
664+
export function setGetSourceFileAsHashVersioned(compilerHost: CompilerHost) {
663665
const originalGetSourceFile = compilerHost.getSourceFile;
664-
const computeHash = maybeBind(host, host.createHash) || generateDjb2Hash;
666+
const computeHash = maybeBind(compilerHost, compilerHost.createHash) || generateDjb2Hash;
665667
compilerHost.getSourceFile = (...args) => {
666668
const result = originalGetSourceFile.call(compilerHost, ...args);
667669
if (result) {

src/compiler/watchPublic.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ namespace ts {
2828
host.createHash = maybeBind(system, system.createHash);
2929
host.disableUseFileVersionAsSignature = system.disableUseFileVersionAsSignature;
3030
host.storeFilesChangingSignatureDuringEmit = system.storeFilesChangingSignatureDuringEmit;
31-
setGetSourceFileAsHashVersioned(host, system);
31+
setGetSourceFileAsHashVersioned(host);
3232
changeCompilerHostLikeToUseCache(host, fileName => toPath(fileName, host.getCurrentDirectory(), host.getCanonicalFileName));
3333
return host;
3434
}
@@ -330,7 +330,7 @@ namespace ts {
330330
}
331331

332332
const compilerHost = createCompilerHostFromProgramHost(host, () => compilerOptions, directoryStructureHost) as CompilerHost & ResolutionCacheHost;
333-
setGetSourceFileAsHashVersioned(compilerHost, host);
333+
setGetSourceFileAsHashVersioned(compilerHost);
334334
// Members for CompilerHost
335335
const getNewSourceFile = compilerHost.getSourceFile;
336336
compilerHost.getSourceFile = (fileName, ...args) => getVersionedSourceFileByPath(fileName, toPath(fileName), ...args);
@@ -452,9 +452,9 @@ namespace ts {
452452
const hasInvalidatedResolutions = resolutionCache.createHasInvalidatedResolutions(customHasInvalidatedResolutions);
453453
const {
454454
originalReadFile, originalFileExists, originalDirectoryExists,
455-
originalCreateDirectory, originalWriteFile,
455+
originalCreateDirectory, originalWriteFile, readFileWithCache,
456456
} = changeCompilerHostLikeToUseCache(compilerHost, toPath);
457-
if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, getSourceVersion, fileName => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
457+
if (isProgramUptoDate(getCurrentProgram(), rootFileNames, compilerOptions, path => getSourceVersion(path, readFileWithCache), fileName => compilerHost.fileExists(fileName), hasInvalidatedResolutions, hasChangedAutomaticTypeDirectiveNames, getParsedCommandLine, projectReferences)) {
458458
if (hasChangedConfigFileParsingErrors) {
459459
if (reportFileChangeDetectedOnCreateProgram) {
460460
reportWatchDiagnostic(Diagnostics.File_change_detected_Starting_incremental_compilation);
@@ -609,9 +609,13 @@ namespace ts {
609609
}
610610
}
611611

612-
function getSourceVersion(path: Path): string | undefined {
612+
function getSourceVersion(path: Path, readFileWithCache: (fileName: string) => string | undefined): string | undefined {
613613
const hostSourceFile = sourceFilesCache.get(path);
614-
return !hostSourceFile || !hostSourceFile.version ? undefined : hostSourceFile.version;
614+
if (!hostSourceFile) return undefined;
615+
if (hostSourceFile.version) return hostSourceFile.version;
616+
// Read file and get new version
617+
const text = readFileWithCache(path);
618+
return text ? (compilerHost.createHash || generateDjb2Hash)(text) : undefined;
615619
}
616620

617621
function onReleaseOldSourceFile(oldSourceFile: SourceFile, _oldOptions: CompilerOptions, hasSourceFileByPath: boolean) {

tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError-with-incremental.js

+6-73
Original file line numberDiff line numberDiff line change
@@ -179,30 +179,6 @@ Input::
179179
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
180180

181181
Output::
182-
>> Screen clear
183-
[12:00:43 AM] File change detected. Starting incremental compilation...
184-
185-
src/main.ts:4:1 - error TS1005: ',' expected.
186-
187-
4 ;
188-
  ~
189-
190-
[12:00:44 AM] Found 1 error. Watching for file changes.
191-
192-
193-
194-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
195-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"incremental":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
196-
Program structureReused: Completely
197-
Program files::
198-
/a/lib/lib.d.ts
199-
/user/username/projects/noEmitOnError/shared/types/db.ts
200-
/user/username/projects/noEmitOnError/src/main.ts
201-
/user/username/projects/noEmitOnError/src/other.ts
202-
203-
Semantic diagnostics in builder refreshed for::
204-
205-
No shapes updated in the builder::
206182

207183
PolledWatches::
208184
/user/username/projects/noemitonerror/node_modules/@types:
@@ -239,9 +215,9 @@ const a = {
239215

240216
Output::
241217
>> Screen clear
242-
[[90m12:00:48 AM[0m] File change detected. Starting incremental compilation...
218+
[[90m12:00:46 AM[0m] File change detected. Starting incremental compilation...
243219

244-
[[90m12:01:06 AM[0m] Found 0 errors. Watching for file changes.
220+
[[90m12:01:04 AM[0m] Found 0 errors. Watching for file changes.
245221

246222

247223

@@ -370,14 +346,14 @@ const a: string = 10;
370346

371347
Output::
372348
>> Screen clear
373-
[[90m12:01:13 AM[0m] File change detected. Starting incremental compilation...
349+
[[90m12:01:11 AM[0m] File change detected. Starting incremental compilation...
374350

375351
src/main.ts:2:7 - error TS2322: Type 'number' is not assignable to type 'string'.
376352

377353
2 const a: string = 10;
378354
   ~
379355

380-
[[90m12:01:17 AM[0m] Found 1 error. Watching for file changes.
356+
[[90m12:01:15 AM[0m] Found 1 error. Watching for file changes.
381357

382358

383359

@@ -501,30 +477,6 @@ Input::
501477
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
502478

503479
Output::
504-
>> Screen clear
505-
[12:01:25 AM] File change detected. Starting incremental compilation...
506-
507-
src/main.ts:2:7 - error TS2322: Type 'number' is not assignable to type 'string'.
508-
509-
2 const a: string = 10;
510-
   ~
511-
512-
[12:01:26 AM] Found 1 error. Watching for file changes.
513-
514-
515-
516-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
517-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"incremental":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
518-
Program structureReused: Completely
519-
Program files::
520-
/a/lib/lib.d.ts
521-
/user/username/projects/noEmitOnError/shared/types/db.ts
522-
/user/username/projects/noEmitOnError/src/main.ts
523-
/user/username/projects/noEmitOnError/src/other.ts
524-
525-
Semantic diagnostics in builder refreshed for::
526-
527-
No shapes updated in the builder::
528480

529481
PolledWatches::
530482
/user/username/projects/noemitonerror/node_modules/@types:
@@ -559,9 +511,9 @@ const a: string = "hello";
559511

560512
Output::
561513
>> Screen clear
562-
[[90m12:01:30 AM[0m] File change detected. Starting incremental compilation...
514+
[[90m12:01:26 AM[0m] File change detected. Starting incremental compilation...
563515

564-
[[90m12:01:37 AM[0m] Found 0 errors. Watching for file changes.
516+
[[90m12:01:33 AM[0m] Found 0 errors. Watching for file changes.
565517

566518

567519

@@ -673,25 +625,6 @@ Input::
673625
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
674626

675627
Output::
676-
>> Screen clear
677-
[12:01:44 AM] File change detected. Starting incremental compilation...
678-
679-
[12:01:45 AM] Found 0 errors. Watching for file changes.
680-
681-
682-
683-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
684-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"incremental":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
685-
Program structureReused: Completely
686-
Program files::
687-
/a/lib/lib.d.ts
688-
/user/username/projects/noEmitOnError/shared/types/db.ts
689-
/user/username/projects/noEmitOnError/src/main.ts
690-
/user/username/projects/noEmitOnError/src/other.ts
691-
692-
Semantic diagnostics in builder refreshed for::
693-
694-
No shapes updated in the builder::
695628

696629
PolledWatches::
697630
/user/username/projects/noemitonerror/node_modules/@types:

tests/baselines/reference/tscWatch/emitAndErrorUpdates/assumeChangesOnlyAffectDirectDependencies/with-noEmitOnError.js

+6-73
Original file line numberDiff line numberDiff line change
@@ -103,30 +103,6 @@ Input::
103103
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
104104

105105
Output::
106-
>> Screen clear
107-
[12:00:36 AM] File change detected. Starting incremental compilation...
108-
109-
src/main.ts:4:1 - error TS1005: ',' expected.
110-
111-
4 ;
112-
  ~
113-
114-
[12:00:37 AM] Found 1 error. Watching for file changes.
115-
116-
117-
118-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
119-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
120-
Program structureReused: Completely
121-
Program files::
122-
/a/lib/lib.d.ts
123-
/user/username/projects/noEmitOnError/shared/types/db.ts
124-
/user/username/projects/noEmitOnError/src/main.ts
125-
/user/username/projects/noEmitOnError/src/other.ts
126-
127-
Semantic diagnostics in builder refreshed for::
128-
129-
No shapes updated in the builder::
130106

131107
PolledWatches::
132108
/user/username/projects/noemitonerror/node_modules/@types:
@@ -163,9 +139,9 @@ const a = {
163139

164140
Output::
165141
>> Screen clear
166-
[[90m12:00:41 AM[0m] File change detected. Starting incremental compilation...
142+
[[90m12:00:39 AM[0m] File change detected. Starting incremental compilation...
167143

168-
[[90m12:00:58 AM[0m] Found 0 errors. Watching for file changes.
144+
[[90m12:00:56 AM[0m] Found 0 errors. Watching for file changes.
169145

170146

171147

@@ -236,14 +212,14 @@ const a: string = 10;
236212

237213
Output::
238214
>> Screen clear
239-
[[90m12:01:02 AM[0m] File change detected. Starting incremental compilation...
215+
[[90m12:01:00 AM[0m] File change detected. Starting incremental compilation...
240216

241217
src/main.ts:2:7 - error TS2322: Type 'number' is not assignable to type 'string'.
242218

243219
2 const a: string = 10;
244220
   ~
245221

246-
[[90m12:01:03 AM[0m] Found 1 error. Watching for file changes.
222+
[[90m12:01:01 AM[0m] Found 1 error. Watching for file changes.
247223

248224

249225

@@ -291,30 +267,6 @@ Input::
291267
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
292268

293269
Output::
294-
>> Screen clear
295-
[12:01:08 AM] File change detected. Starting incremental compilation...
296-
297-
src/main.ts:2:7 - error TS2322: Type 'number' is not assignable to type 'string'.
298-
299-
2 const a: string = 10;
300-
   ~
301-
302-
[12:01:09 AM] Found 1 error. Watching for file changes.
303-
304-
305-
306-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
307-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
308-
Program structureReused: Completely
309-
Program files::
310-
/a/lib/lib.d.ts
311-
/user/username/projects/noEmitOnError/shared/types/db.ts
312-
/user/username/projects/noEmitOnError/src/main.ts
313-
/user/username/projects/noEmitOnError/src/other.ts
314-
315-
Semantic diagnostics in builder refreshed for::
316-
317-
No shapes updated in the builder::
318270

319271
PolledWatches::
320272
/user/username/projects/noemitonerror/node_modules/@types:
@@ -349,9 +301,9 @@ const a: string = "hello";
349301

350302
Output::
351303
>> Screen clear
352-
[[90m12:01:13 AM[0m] File change detected. Starting incremental compilation...
304+
[[90m12:01:09 AM[0m] File change detected. Starting incremental compilation...
353305

354-
[[90m12:01:17 AM[0m] Found 0 errors. Watching for file changes.
306+
[[90m12:01:13 AM[0m] Found 0 errors. Watching for file changes.
355307

356308

357309

@@ -405,25 +357,6 @@ Input::
405357
//// [/user/username/projects/noEmitOnError/src/main.ts] file written with same contents
406358

407359
Output::
408-
>> Screen clear
409-
[12:01:21 AM] File change detected. Starting incremental compilation...
410-
411-
[12:01:22 AM] Found 0 errors. Watching for file changes.
412-
413-
414-
415-
Program root files: ["/user/username/projects/noEmitOnError/shared/types/db.ts","/user/username/projects/noEmitOnError/src/main.ts","/user/username/projects/noEmitOnError/src/other.ts"]
416-
Program options: {"outDir":"/user/username/projects/noEmitOnError/dev-build","noEmitOnError":true,"watch":true,"assumeChangesOnlyAffectDirectDependencies":true,"configFilePath":"/user/username/projects/noEmitOnError/tsconfig.json"}
417-
Program structureReused: Completely
418-
Program files::
419-
/a/lib/lib.d.ts
420-
/user/username/projects/noEmitOnError/shared/types/db.ts
421-
/user/username/projects/noEmitOnError/src/main.ts
422-
/user/username/projects/noEmitOnError/src/other.ts
423-
424-
Semantic diagnostics in builder refreshed for::
425-
426-
No shapes updated in the builder::
427360

428361
PolledWatches::
429362
/user/username/projects/noemitonerror/node_modules/@types:

0 commit comments

Comments
 (0)