fix(compiler): avoid emitting self importing factories

Fixes: #17389
This commit is contained in:
Chuck Jazdzewski 2017-06-21 15:05:11 -07:00 committed by Hans
parent 34cc3f2982
commit 4352dd27c4
4 changed files with 36 additions and 5 deletions

View File

@ -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);
}

View File

@ -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

View File

@ -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);
}

View File

@ -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', () => {