Skip to content

Commit

Permalink
fix(rosetta): cache source file parses (#3163)
Browse files Browse the repository at this point in the history
Store parsed source files in a cache, so that we can avoid re-parsing
the same TypeScript library files every time we compile a sample in
a batch.

Reduces compilation time by ~4x on my machine.



---

By submitting this pull request, I confirm that my contribution is made under the terms of the [Apache 2.0 license].

[Apache 2.0 license]: https://www.apache.org/licenses/LICENSE-2.0
  • Loading branch information
rix0rrr authored Nov 12, 2021
1 parent e303365 commit 307d3ca
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions packages/jsii-rosetta/lib/typescript/ts-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ import * as ts from 'typescript';
export class TypeScriptCompiler {
private readonly realHost = ts.createCompilerHost(STANDARD_COMPILER_OPTIONS, true);

/**
* A compiler-scoped cache to avoid having to re-parse the same library files for every compilation
*/
private readonly fileCache = new Map<string, ts.SourceFile | undefined>();

public createInMemoryCompilerHost(
sourcePath: string,
sourceContents: string,
Expand All @@ -13,12 +18,23 @@ export class TypeScriptCompiler {

return {
...realHost,
fileExists: (filePath) => filePath === sourcePath || realHost.fileExists(filePath),
fileExists: (filePath) =>
filePath === sourcePath || this.fileCache.has(filePath) || realHost.fileExists(filePath),
getCurrentDirectory: currentDirectory != null ? () => currentDirectory : realHost.getCurrentDirectory,
getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) =>
fileName === sourcePath
? sourceFile
: realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile),
getSourceFile: (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
if (fileName === sourcePath) {
return sourceFile;
}

const existing = this.fileCache.get(fileName);
if (existing) {
return existing;
}

const parsed = realHost.getSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
this.fileCache.set(fileName, parsed);
return parsed;
},
readFile: (filePath) => (filePath === sourcePath ? sourceContents : realHost.readFile(filePath)),
writeFile: () => void undefined,
};
Expand Down

0 comments on commit 307d3ca

Please sign in to comment.