fix(ivy): ngInjectorDef should copy full imports/exports nodes (#24862)

@NgModule()s get compiled to two fields: ngModuleDef and ngInjectorDef.
Both fields contain imports, as both selector scopes and injectors have
the concept of composed units of configuration. Previously these fields
were generated by static resolution of imports and exports in metadata.

Support for ModuleWithProviders requires they be generated differently.
ngModuleDef's imports/exports are generated as resolved lists of types,
whereas ngInjectorDef's imports should reflect the raw expressions that
the developer wrote in the metadata.

This change modifies the NgModule handler and properly copies raw nodes
for the imports and exports into the ngInjectorDef.

PR Close #24862
This commit is contained in:
Alex Rickabaugh 2018-07-10 09:59:29 -07:00 committed by Victor Berchet
parent f9a6a175bf
commit 42d4287153
2 changed files with 14 additions and 3 deletions

View File

@ -96,12 +96,19 @@ export class NgModuleDecoratorHandler implements DecoratorHandler<NgModuleAnalys
new WrappedNodeExpr(ngModule.get('providers') !) :
new LiteralArrayExpr([]);
const injectorImports: WrappedNodeExpr<ts.Expression>[] = [];
if (ngModule.has('imports')) {
injectorImports.push(new WrappedNodeExpr(ngModule.get('imports') !));
}
if (ngModule.has('exports')) {
injectorImports.push(new WrappedNodeExpr(ngModule.get('exports') !));
}
const ngInjectorDef: R3InjectorMetadata = {
name: node.name !.text,
type: new WrappedNodeExpr(node.name !),
deps: getConstructorDependencies(node, this.reflector, this.isCore), providers,
imports: new LiteralArrayExpr(
[...imports, ...exports].map(imp => referenceToExpression(imp, context))),
imports: new LiteralArrayExpr(injectorImports),
};
return {

View File

@ -236,7 +236,7 @@ describe('ngtsc behavioral tests', () => {
.toContain(
`TestModule.ngInjectorDef = i0.defineInjector({ factory: ` +
`function TestModule_Factory() { return new TestModule(); }, providers: [{ provide: ` +
`Token, useValue: 'test' }], imports: [OtherModule] });`);
`Token, useValue: 'test' }], imports: [[OtherModule]] });`);
const dtsContents = getContents('test.d.ts');
expect(dtsContents)
@ -366,6 +366,10 @@ describe('ngtsc behavioral tests', () => {
const exitCode = main(['-p', basePath], errorSpy);
expect(errorSpy).not.toHaveBeenCalled();
expect(exitCode).toBe(0);
const jsContents = getContents('test.js');
expect(jsContents).toContain('imports: [[RouterModule.forRoot()]]');
const dtsContents = getContents('test.d.ts');
expect(dtsContents).toContain(`import * as i1 from 'router';`);
expect(dtsContents).toContain('i0.ɵNgModuleDef<TestModule, [], [i1.RouterModule], []>');