Skip to content

Commit ec4652f

Browse files
committed
Use also mtime to validate source file cache
1 parent a1a6c1e commit ec4652f

2 files changed

Lines changed: 71 additions & 21 deletions

File tree

build/monaco/api.js

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -456,11 +456,20 @@ class FSProvider {
456456
existsSync(filePath) {
457457
return fs.existsSync(filePath);
458458
}
459+
statSync(filePath) {
460+
return fs.statSync(filePath);
461+
}
459462
readFileSync(_moduleId, filePath) {
460463
return fs.readFileSync(filePath);
461464
}
462465
}
463466
exports.FSProvider = FSProvider;
467+
class CacheEntry {
468+
constructor(sourceFile, mtime) {
469+
this.sourceFile = sourceFile;
470+
this.mtime = mtime;
471+
}
472+
}
464473
class DeclarationResolver {
465474
constructor(_fsProvider) {
466475
this._fsProvider = _fsProvider;
@@ -470,31 +479,43 @@ class DeclarationResolver {
470479
this._sourceFileCache[moduleId] = null;
471480
}
472481
getDeclarationSourceFile(moduleId) {
482+
if (this._sourceFileCache[moduleId]) {
483+
// Since we cannot trust file watching to invalidate the cache, check also the mtime
484+
const fileName = this._getFileName(moduleId);
485+
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
486+
if (this._sourceFileCache[moduleId].mtime !== mtime) {
487+
this._sourceFileCache[moduleId] = null;
488+
}
489+
}
473490
if (!this._sourceFileCache[moduleId]) {
474491
this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
475492
}
476-
return this._sourceFileCache[moduleId];
493+
return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId].sourceFile : null;
477494
}
478-
_getDeclarationSourceFile(moduleId) {
495+
_getFileName(moduleId) {
479496
if (/\.d\.ts$/.test(moduleId)) {
480-
const fileName = path.join(SRC, moduleId);
481-
if (!this._fsProvider.existsSync(fileName)) {
482-
return null;
483-
}
484-
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
485-
return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
497+
return path.join(SRC, moduleId);
486498
}
487-
const fileName = path.join(SRC, `${moduleId}.ts`);
499+
return path.join(SRC, `${moduleId}.ts`);
500+
}
501+
_getDeclarationSourceFile(moduleId) {
502+
const fileName = this._getFileName(moduleId);
488503
if (!this._fsProvider.existsSync(fileName)) {
489504
return null;
490505
}
506+
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
507+
if (/\.d\.ts$/.test(moduleId)) {
508+
// const mtime = this._fsProvider.statFileSync()
509+
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
510+
return new CacheEntry(ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5), mtime);
511+
}
491512
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
492513
const fileMap = {
493514
'file.ts': fileContents
494515
};
495516
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
496517
const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
497-
return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
518+
return new CacheEntry(ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5), mtime);
498519
}
499520
}
500521
exports.DeclarationResolver = DeclarationResolver;

build/monaco/api.ts

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -547,14 +547,24 @@ export class FSProvider {
547547
public existsSync(filePath: string): boolean {
548548
return fs.existsSync(filePath);
549549
}
550+
public statSync(filePath: string): fs.Stats {
551+
return fs.statSync(filePath);
552+
}
550553
public readFileSync(_moduleId: string, filePath: string): Buffer {
551554
return fs.readFileSync(filePath);
552555
}
553556
}
554557

558+
class CacheEntry {
559+
constructor(
560+
public readonly sourceFile: ts.SourceFile,
561+
public readonly mtime: number
562+
) {}
563+
}
564+
555565
export class DeclarationResolver {
556566

557-
private _sourceFileCache: { [moduleId: string]: ts.SourceFile | null; };
567+
private _sourceFileCache: { [moduleId: string]: CacheEntry | null; };
558568

559569
constructor(private readonly _fsProvider: FSProvider) {
560570
this._sourceFileCache = Object.create(null);
@@ -565,32 +575,51 @@ export class DeclarationResolver {
565575
}
566576

567577
public getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
578+
if (this._sourceFileCache[moduleId]) {
579+
// Since we cannot trust file watching to invalidate the cache, check also the mtime
580+
const fileName = this._getFileName(moduleId);
581+
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
582+
if (this._sourceFileCache[moduleId]!.mtime !== mtime) {
583+
this._sourceFileCache[moduleId] = null;
584+
}
585+
}
568586
if (!this._sourceFileCache[moduleId]) {
569587
this._sourceFileCache[moduleId] = this._getDeclarationSourceFile(moduleId);
570588
}
571-
return this._sourceFileCache[moduleId];
589+
return this._sourceFileCache[moduleId] ? this._sourceFileCache[moduleId]!.sourceFile : null;
572590
}
573591

574-
private _getDeclarationSourceFile(moduleId: string): ts.SourceFile | null {
592+
private _getFileName(moduleId: string): string {
575593
if (/\.d\.ts$/.test(moduleId)) {
576-
const fileName = path.join(SRC, moduleId);
577-
if (!this._fsProvider.existsSync(fileName)) {
578-
return null;
579-
}
580-
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
581-
return ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5);
594+
return path.join(SRC, moduleId);
582595
}
583-
const fileName = path.join(SRC, `${moduleId}.ts`);
596+
return path.join(SRC, `${moduleId}.ts`);
597+
}
598+
599+
private _getDeclarationSourceFile(moduleId: string): CacheEntry | null {
600+
const fileName = this._getFileName(moduleId);
584601
if (!this._fsProvider.existsSync(fileName)) {
585602
return null;
586603
}
604+
const mtime = this._fsProvider.statSync(fileName).mtime.getTime();
605+
if (/\.d\.ts$/.test(moduleId)) {
606+
// const mtime = this._fsProvider.statFileSync()
607+
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
608+
return new CacheEntry(
609+
ts.createSourceFile(fileName, fileContents, ts.ScriptTarget.ES5),
610+
mtime
611+
);
612+
}
587613
const fileContents = this._fsProvider.readFileSync(moduleId, fileName).toString();
588614
const fileMap: IFileMap = {
589615
'file.ts': fileContents
590616
};
591617
const service = ts.createLanguageService(new TypeScriptLanguageServiceHost({}, fileMap, {}));
592618
const text = service.getEmitOutput('file.ts', true).outputFiles[0].text;
593-
return ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5);
619+
return new CacheEntry(
620+
ts.createSourceFile(fileName, text, ts.ScriptTarget.ES5),
621+
mtime
622+
);
594623
}
595624
}
596625

0 commit comments

Comments
 (0)