diff --git a/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts b/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts index 552f4cdcea..90829bbaac 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/factory_generator.ts @@ -26,9 +26,16 @@ export class FactoryGenerator implements ShimGenerator { get factoryFileMap(): Map { return this.map; } - getOriginalSourceOfShim(fileName: string): string|null { return this.map.get(fileName) || null; } + recognize(fileName: string): boolean { return this.map.has(fileName); } + + generate(genFilePath: string, readFile: (fileName: string) => ts.SourceFile | null): ts.SourceFile + |null { + const originalPath = this.map.get(genFilePath) !; + const original = readFile(originalPath); + if (original === null) { + return null; + } - generate(original: ts.SourceFile, genFilePath: string): ts.SourceFile { const relativePathToSource = './' + path.posix.basename(original.fileName).replace(TS_DTS_SUFFIX, ''); // Collect a list of classes that need to have factory types emitted for them. This list is diff --git a/packages/compiler-cli/src/ngtsc/shims/src/host.ts b/packages/compiler-cli/src/ngtsc/shims/src/host.ts index 1c83b09939..4bcf98e2f8 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/host.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/host.ts @@ -11,17 +11,20 @@ import * as ts from 'typescript'; export interface ShimGenerator { /** - * Get the original source file for the given shim path, the contents of which determine the - * contents of the shim file. - * - * If this returns `null` then the given file was not a shim file handled by this generator. + * Returns `true` if this generator is intended to handle the given file. */ - getOriginalSourceOfShim(fileName: string): string|null; + recognize(fileName: string): boolean; /** * Generate a shim's `ts.SourceFile` for the given original file. + * + * `readFile` is a function which allows the generator to look up the contents of existing source + * files. It returns null if the requested file doesn't exist. + * + * If `generate` returns null, then the shim generator declines to generate the file after all. */ - generate(original: ts.SourceFile, genFileName: string): ts.SourceFile; + generate(genFileName: string, readFile: (fileName: string) => ts.SourceFile | null): ts.SourceFile + |null; } /** @@ -55,17 +58,14 @@ export class GeneratedShimsHostWrapper implements ts.CompilerHost { shouldCreateNewSourceFile?: boolean|undefined): ts.SourceFile|undefined { for (let i = 0; i < this.shimGenerators.length; i++) { const generator = this.shimGenerators[i]; - const originalFile = generator.getOriginalSourceOfShim(fileName); - if (originalFile !== null) { - // This shim generator has recognized the filename being requested, and is now responsible - // for generating its contents, based on the contents of the original file it has requested. - const originalSource = this.delegate.getSourceFile( - originalFile, languageVersion, onError, shouldCreateNewSourceFile); - if (originalSource === undefined) { - // The original requested file doesn't exist, so the shim cannot exist either. - return undefined; - } - return generator.generate(originalSource, fileName); + if (generator.recognize(fileName)) { + const readFile = (originalFile: string) => { + return this.delegate.getSourceFile( + originalFile, languageVersion, onError, shouldCreateNewSourceFile) || + null; + }; + + return generator.generate(fileName, readFile) || undefined; } } return this.delegate.getSourceFile( @@ -100,7 +100,7 @@ export class GeneratedShimsHostWrapper implements ts.CompilerHost { // Consider the file as existing whenever 1) it really does exist in the delegate host, or // 2) at least one of the shim generators recognizes it. return this.delegate.fileExists(fileName) || - this.shimGenerators.some(gen => gen.getOriginalSourceOfShim(canonical) !== null); + this.shimGenerators.some(gen => gen.recognize(canonical)); } readFile(fileName: string): string|undefined { return this.delegate.readFile(fileName); } diff --git a/packages/compiler-cli/src/ngtsc/shims/src/summary_generator.ts b/packages/compiler-cli/src/ngtsc/shims/src/summary_generator.ts index bbb8e35266..158f0fdba6 100644 --- a/packages/compiler-cli/src/ngtsc/shims/src/summary_generator.ts +++ b/packages/compiler-cli/src/ngtsc/shims/src/summary_generator.ts @@ -16,9 +16,16 @@ export class SummaryGenerator implements ShimGenerator { getSummaryFileNames(): string[] { return Array.from(this.map.keys()); } - getOriginalSourceOfShim(fileName: string): string|null { return this.map.get(fileName) || null; } + recognize(fileName: string): boolean { return this.map.has(fileName); } + + generate(genFilePath: string, readFile: (fileName: string) => ts.SourceFile | null): ts.SourceFile + |null { + const originalPath = this.map.get(genFilePath) !; + const original = readFile(originalPath); + if (original === null) { + return null; + } - generate(original: ts.SourceFile, genFilePath: string): ts.SourceFile { // Collect a list of classes that need to have factory types emitted for them. This list is // overly broad as at this point the ts.TypeChecker has not been created and so it can't be used // to semantically understand which decorators are Angular decorators. It's okay to output an