Skip to content

Commit

Permalink
perf(ivy): switch ngtsc to use single-file emit
Browse files Browse the repository at this point in the history
In the TypeScript compiler API, emit() can be performed either on a single
ts.SourceFile or on the entire ts.Program simultaneously.

ngtsc previously used whole-program emit, which was convenient to use while
spinning up the project but has a significant drawback: it causes a type
checking operation to occur for the whole program, including .d.ts files.
In large Bazel environments (such as Google's codebase), an ngtsc invocation
can have a few .ts files and thousands of .d.ts inputs. This unwanted type
checking is therefore a significant drain on performance.

This commit switches ngtsc to emit each .ts file individually, avoiding the
unwanted type checking.
  • Loading branch information
alxhub committed Mar 7, 2019
1 parent 5fded9f commit d60c497
Showing 1 changed file with 25 additions and 12 deletions.
37 changes: 25 additions & 12 deletions packages/compiler-cli/src/ngtsc/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export class NgtscProgram implements api.Program {
private refEmitter: ReferenceEmitter|null = null;
private fileToModuleHost: FileToModuleHost|null = null;

private generatedToOriginalSourceFiles = new Map<ts.SourceFile, ts.SourceFile>();

constructor(
rootNames: ReadonlyArray<string>, private options: api.CompilerOptions,
host: api.CompilerHost, oldProgram?: api.Program) {
Expand Down Expand Up @@ -269,6 +271,8 @@ export class NgtscProgram implements api.Program {
if (this.closureCompilerEnabled && fileName.endsWith('.js')) {
data = nocollapseHack(data);
}
let outputSourceFiles = sourceFiles;

this.host.writeFile(fileName, data, writeByteOrderMark, onError, sourceFiles);
};

Expand All @@ -293,19 +297,28 @@ export class NgtscProgram implements api.Program {
beforeTransforms.push(...customTransforms.beforeTs);
}

const emitResults: ts.EmitResult[] = [];
for (const targetSourceFile of this.tsProgram.getSourceFiles()) {
if (targetSourceFile.isDeclarationFile) {
continue;
}

emitResults.push(emitCallback({
targetSourceFile,
program: this.tsProgram,
host: this.host,
options: this.options,
emitOnlyDtsFiles: false, writeFile,
customTransformers: {
before: beforeTransforms,
after: customTransforms && customTransforms.afterTs,
afterDeclarations: afterDeclarationsTransforms,
},
}));
}

// Run the emit, including a custom transformer that will downlevel the Ivy decorators in code.
const emitResult = emitCallback({
program: this.tsProgram,
host: this.host,
options: this.options,
emitOnlyDtsFiles: false, writeFile,
customTransformers: {
before: beforeTransforms,
after: customTransforms && customTransforms.afterTs,
afterDeclarations: afterDeclarationsTransforms,
},
});
return emitResult;
return ((opts && opts.mergeEmitResultsCallback) || mergeEmitResults)(emitResults);
}

private compileTypeCheckProgram(ctx: TypeCheckContext): ReadonlyArray<ts.Diagnostic> {
Expand Down

0 comments on commit d60c497

Please sign in to comment.