refactor(ivy): compute ignoreFiles for compilation on initialization (#34792)

This commit moves the calculation of `ignoreFiles` - the set of files to be
ignored by a consumer of the `NgCompiler` API - from its `prepareEmit`
operation to its initialization. It's now available as a field on
`NgCompiler`.

This will allow a consumer to skip gathering diagnostics for `ignoreFiles`
as well as skip emit.

PR Close #34792
This commit is contained in:
Alex Rickabaugh 2020-02-03 10:48:05 -08:00 committed by Misko Hevery
parent 49dd7b6a0a
commit 14aa6d090e
5 changed files with 70 additions and 20 deletions

View File

@ -97,6 +97,8 @@ export class NgCompiler {
private resourceManager: HostResourceLoader;
private cycleAnalyzer: CycleAnalyzer;
readonly incrementalDriver: IncrementalDriver;
readonly ignoreForDiagnostics: Set<ts.SourceFile>;
readonly ignoreForEmit: Set<ts.SourceFile>;
constructor(
private host: NgCompilerHost, private options: NgCompilerOptions,
@ -142,6 +144,14 @@ export class NgCompiler {
}
}
setIncrementalDriver(tsProgram, this.incrementalDriver);
this.ignoreForDiagnostics = new Set([
this.typeCheckFile,
...host.factoryFiles.map(fileName => getSourceFileOrError(tsProgram, fileName)),
...host.summaryFiles.map(fileName => getSourceFileOrError(tsProgram, fileName)),
]);
this.ignoreForEmit = new Set([this.typeCheckFile]);
}
/**
@ -285,7 +295,6 @@ export class NgCompiler {
*/
prepareEmit(): {
transformers: ts.CustomTransformers,
ignoreFiles: Set<ts.SourceFile>,
} {
const compilation = this.ensureAnalyzed();
@ -321,9 +330,7 @@ export class NgCompiler {
}
before.push(ivySwitchTransform);
const ignoreFiles = new Set<ts.SourceFile>([this.typeCheckFile]);
return {transformers: {before, afterDeclarations} as ts.CustomTransformers, ignoreFiles};
return {transformers: {before, afterDeclarations} as ts.CustomTransformers};
}
/**

View File

@ -97,17 +97,22 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
readonly inputFiles: ReadonlyArray<string>;
readonly rootDirs: ReadonlyArray<AbsoluteFsPath>;
readonly typeCheckFile: AbsoluteFsPath;
readonly factoryFiles: AbsoluteFsPath[];
readonly summaryFiles: AbsoluteFsPath[];
constructor(
delegate: ExtendedTsCompilerHost, inputFiles: ReadonlyArray<string>,
rootDirs: ReadonlyArray<AbsoluteFsPath>, private shims: ShimGenerator[],
entryPoint: AbsoluteFsPath|null, typeCheckFile: AbsoluteFsPath,
factoryFiles: AbsoluteFsPath[], summaryFiles: AbsoluteFsPath[],
factoryTracker: FactoryTracker|null, diagnostics: ts.Diagnostic[]) {
super(delegate);
this.factoryTracker = factoryTracker;
this.entryPoint = entryPoint;
this.typeCheckFile = typeCheckFile;
this.factoryFiles = factoryFiles;
this.summaryFiles = summaryFiles;
this.diagnostics = diagnostics;
this.inputFiles = inputFiles;
this.rootDirs = rootDirs;
@ -136,31 +141,36 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
const generators: ShimGenerator[] = [];
let summaryGenerator: SummaryGenerator|null = null;
let summaryFiles: AbsoluteFsPath[];
if (shouldGenerateSummaryShims) {
// Summary generation.
summaryGenerator = SummaryGenerator.forRootFiles(normalizedInputFiles);
generators.push(summaryGenerator);
summaryFiles = summaryGenerator.getSummaryFileNames();
} else {
summaryFiles = [];
}
let factoryTracker: FactoryTracker|null = null;
let factoryFiles: AbsoluteFsPath[];
if (shouldGenerateFactoryShims) {
// Factory generation.
const factoryGenerator = FactoryGenerator.forRootFiles(normalizedInputFiles);
const factoryFileMap = factoryGenerator.factoryFileMap;
const factoryFileNames = Array.from(factoryFileMap.keys());
rootFiles.push(...factoryFileNames);
factoryFiles = Array.from(factoryFileMap.keys());
rootFiles.push(...factoryFiles);
generators.push(factoryGenerator);
factoryTracker = new FactoryTracker(factoryGenerator);
} else {
factoryFiles = [];
}
// Done separately to preserve the order of factory files before summary files in rootFiles.
// TODO(alxhub): validate that this is necessary.
if (summaryGenerator !== null) {
rootFiles.push(...summaryGenerator.getSummaryFileNames());
}
rootFiles.push(...summaryFiles);
const rootDirs = getRootDirs(delegate, options as ts.CompilerOptions);
@ -203,8 +213,8 @@ export class NgCompilerHost extends DelegatingCompilerHost implements
}
return new NgCompilerHost(
delegate, rootFiles, rootDirs, generators, entryPoint, typeCheckFile, factoryTracker,
diagnostics);
delegate, rootFiles, rootDirs, generators, entryPoint, typeCheckFile, factoryFiles,
summaryFiles, factoryTracker, diagnostics);
}
getSourceFile(

View File

@ -88,13 +88,43 @@ export class NgtscProgram implements api.Program {
getTsSyntacticDiagnostics(
sourceFile?: ts.SourceFile|undefined,
cancellationToken?: ts.CancellationToken|undefined): readonly ts.Diagnostic[] {
return this.tsProgram.getSyntacticDiagnostics(sourceFile, cancellationToken);
const ignoredFiles = this.compiler.ignoreForDiagnostics;
if (sourceFile !== undefined) {
if (ignoredFiles.has(sourceFile)) {
return [];
}
return this.tsProgram.getSyntacticDiagnostics(sourceFile, cancellationToken);
} else {
const diagnostics: ts.Diagnostic[] = [];
for (const sf of this.tsProgram.getSourceFiles()) {
if (!ignoredFiles.has(sf)) {
diagnostics.push(...this.tsProgram.getSyntacticDiagnostics(sf, cancellationToken));
}
}
return diagnostics;
}
}
getTsSemanticDiagnostics(
sourceFile?: ts.SourceFile|undefined,
cancellationToken?: ts.CancellationToken|undefined): readonly ts.Diagnostic[] {
return this.tsProgram.getSemanticDiagnostics(sourceFile, cancellationToken);
const ignoredFiles = this.compiler.ignoreForDiagnostics;
if (sourceFile !== undefined) {
if (ignoredFiles.has(sourceFile)) {
return [];
}
return this.tsProgram.getSemanticDiagnostics(sourceFile, cancellationToken);
} else {
const diagnostics: ts.Diagnostic[] = [];
for (const sf of this.tsProgram.getSourceFiles()) {
if (!ignoredFiles.has(sf)) {
diagnostics.push(...this.tsProgram.getSemanticDiagnostics(sf, cancellationToken));
}
}
return diagnostics;
}
}
getNgOptionDiagnostics(cancellationToken?: ts.CancellationToken|
@ -144,7 +174,8 @@ export class NgtscProgram implements api.Program {
emitCallback?: api.TsEmitCallback | undefined;
mergeEmitResultsCallback?: api.TsMergeEmitResultsCallback | undefined;
}|undefined): ts.EmitResult {
const {transformers, ignoreFiles} = this.compiler.prepareEmit();
const {transformers} = this.compiler.prepareEmit();
const ignoreFiles = this.compiler.ignoreForEmit;
const emitCallback = opts && opts.emitCallback || defaultEmitCallback;
const writeFile: ts.WriteFileCallback =

View File

@ -22,9 +22,11 @@ const STRIP_NG_FACTORY = /(.*)NgFactory$/;
* class of an input ts.SourceFile.
*/
export class FactoryGenerator implements ShimGenerator {
private constructor(private map: Map<string, string>) {}
private constructor(private map: Map<AbsoluteFsPath, AbsoluteFsPath>) {}
get factoryFileMap(): Map<string, string> { return this.map; }
get factoryFileMap(): Map<AbsoluteFsPath, AbsoluteFsPath> { return this.map; }
get factoryFileNames(): AbsoluteFsPath[] { return Array.from(this.map.keys()); }
recognize(fileName: AbsoluteFsPath): boolean { return this.map.has(fileName); }
@ -101,7 +103,7 @@ export class FactoryGenerator implements ShimGenerator {
}
static forRootFiles(files: ReadonlyArray<AbsoluteFsPath>): FactoryGenerator {
const map = new Map<AbsoluteFsPath, string>();
const map = new Map<AbsoluteFsPath, AbsoluteFsPath>();
files.filter(sourceFile => isNonDeclarationTsPath(sourceFile))
.forEach(
sourceFile =>

View File

@ -15,9 +15,9 @@ import {ShimGenerator} from './api';
import {generatedModuleName} from './util';
export class SummaryGenerator implements ShimGenerator {
private constructor(private map: Map<AbsoluteFsPath, string>) {}
private constructor(private map: Map<AbsoluteFsPath, AbsoluteFsPath>) {}
getSummaryFileNames(): string[] { return Array.from(this.map.keys()); }
getSummaryFileNames(): AbsoluteFsPath[] { return Array.from(this.map.keys()); }
recognize(fileName: AbsoluteFsPath): boolean { return this.map.has(fileName); }
@ -78,7 +78,7 @@ export class SummaryGenerator implements ShimGenerator {
}
static forRootFiles(files: ReadonlyArray<AbsoluteFsPath>): SummaryGenerator {
const map = new Map<AbsoluteFsPath, string>();
const map = new Map<AbsoluteFsPath, AbsoluteFsPath>();
files.filter(sourceFile => isNonDeclarationTsPath(sourceFile))
.forEach(
sourceFile =>