From 4352dd27c4d69638a11c8d686e4d568de947e829 Mon Sep 17 00:00:00 2001 From: Chuck Jazdzewski Date: Wed, 21 Jun 2017 15:05:11 -0700 Subject: [PATCH] fix(compiler): avoid emitting self importing factories Fixes: #17389 --- packages/compiler-cli/src/compiler_host.ts | 2 +- packages/compiler/src/aot/compiler.ts | 5 ++- .../src/aot/static_symbol_resolver.ts | 3 -- packages/compiler/test/aot/compiler_spec.ts | 31 +++++++++++++++++++ 4 files changed, 36 insertions(+), 5 deletions(-) diff --git a/packages/compiler-cli/src/compiler_host.ts b/packages/compiler-cli/src/compiler_host.ts index 41d781a9ad..70ca33f1a2 100644 --- a/packages/compiler-cli/src/compiler_host.ts +++ b/packages/compiler-cli/src/compiler_host.ts @@ -110,7 +110,7 @@ export class CompilerHost implements AotCompilerHost { fileNameToModuleName(importedFile: string, containingFile: string): string { // If a file does not yet exist (because we compile it later), we still need to // assume it exists it so that the `resolve` method works! - if (!this.context.fileExists(importedFile)) { + if (importedFile !== containingFile && !this.context.fileExists(importedFile)) { this.context.assumeFileExists(importedFile); } diff --git a/packages/compiler/src/aot/compiler.ts b/packages/compiler/src/aot/compiler.ts index f8e57b0d5d..e5ae0d0779 100644 --- a/packages/compiler/src/aot/compiler.ts +++ b/packages/compiler/src/aot/compiler.ts @@ -304,7 +304,10 @@ export class AotCompiler { } const arity = this._symbolResolver.getTypeArity(symbol) || 0; const {filePath, name, members} = this._symbolResolver.getImportAs(symbol) || symbol; - const moduleName = this._symbolResolver.fileNameToModuleName(filePath, genFilePath); + const importModule = this._symbolResolver.fileNameToModuleName(filePath, genFilePath); + const selfReference = this._symbolResolver.fileNameToModuleName(genFilePath, genFilePath); + const moduleName = importModule === selfReference ? null : importModule; + // If we are in a type expression that refers to a generic type then supply // the required type parameters. If there were not enough type parameters // supplied, supply any as the type. Outside a type expression the reference diff --git a/packages/compiler/src/aot/static_symbol_resolver.ts b/packages/compiler/src/aot/static_symbol_resolver.ts index 6577119247..201c27c257 100644 --- a/packages/compiler/src/aot/static_symbol_resolver.ts +++ b/packages/compiler/src/aot/static_symbol_resolver.ts @@ -162,9 +162,6 @@ export class StaticSymbolResolver { * Converts a file path to a module name that can be used as an `import`. */ fileNameToModuleName(importedFilePath: string, containingFilePath: string): string|null { - if (importedFilePath === containingFilePath) { - return null; - } return this.knownFileNameToModuleNames.get(importedFilePath) || this.host.fileNameToModuleName(importedFilePath, containingFilePath); } diff --git a/packages/compiler/test/aot/compiler_spec.ts b/packages/compiler/test/aot/compiler_spec.ts index ad68561051..a00e2c9ea2 100644 --- a/packages/compiler/test/aot/compiler_spec.ts +++ b/packages/compiler/test/aot/compiler_spec.ts @@ -233,6 +233,37 @@ describe('compiler (unbundled Angular)', () => { }; compile([FILES, angularFiles], {postCompile: expectNoDiagnostics}); }); + + it('should not contain a self import in factory', () => { + const FILES: MockDirectory = { + app: { + 'app.ts': ` + import {Component, NgModule} from '@angular/core'; + + interface Person { name: string; } + + @Component({ + selector: 'my-comp', + template: '{{person.name}}' + }) + export class MyComp { + person: Person; + } + + @NgModule({ + declarations: [MyComp] + }) + export class MyModule {} + ` + } + }; + compile([FILES, angularFiles], { + postCompile: program => { + const factorySource = program.getSourceFile('/app/app.ngfactory.ts'); + expect(factorySource.text).not.toContain('\'/app/app.ngfactory\''); + } + }); + }); }); it('should add the preamble to generated files', () => {