refactor: use view engine also for NgModuleFactorys (#16658)

* refactor(core): provide error message in stack for reflective DI

Fixes #16355

* fix(compiler): make AOT work with `noUnusedParameters`

Fixes #15532

* refactor: use view engine also for `NgModuleFactory`s

This is a prerequisite for being able to mock providers
in AOTed code later on.
This commit is contained in:
Tobias Bosch
2017-05-11 10:26:02 -07:00
committed by Jason Aden
parent b9521b568f
commit ce1d7c4a6e
25 changed files with 800 additions and 604 deletions

View File

@ -977,8 +977,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirA = createDir('[dirA]', {providers: [provider]});
const elAst: ElementAst = <ElementAst>parse('<div dirA>', [dirA])[0];
expect(elAst.providers.length).toBe(2);
expect(elAst.providers[1].providerType).toBe(ProviderAstType.PublicService);
expect(elAst.providers[1].providers).toEqual([provider]);
expect(elAst.providers[0].providerType).toBe(ProviderAstType.PublicService);
expect(elAst.providers[0].providers).toEqual([provider]);
});
it('should use the private providers of a component', () => {
@ -986,8 +986,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const comp = createDir('my-comp', {viewProviders: [provider]});
const elAst: ElementAst = <ElementAst>parse('<my-comp>', [comp])[0];
expect(elAst.providers.length).toBe(2);
expect(elAst.providers[1].providerType).toBe(ProviderAstType.PrivateService);
expect(elAst.providers[1].providers).toEqual([provider]);
expect(elAst.providers[0].providerType).toBe(ProviderAstType.PrivateService);
expect(elAst.providers[0].providers).toEqual([provider]);
});
it('should support multi providers', () => {
@ -998,8 +998,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirB = createDir('[dirB]', {providers: [provider2]});
const elAst: ElementAst = <ElementAst>parse('<div dirA dirB>', [dirA, dirB])[0];
expect(elAst.providers.length).toBe(4);
expect(elAst.providers[2].providers).toEqual([provider0, provider2]);
expect(elAst.providers[3].providers).toEqual([provider1]);
expect(elAst.providers[0].providers).toEqual([provider0, provider2]);
expect(elAst.providers[1].providers).toEqual([provider1]);
});
it('should overwrite non multi providers', () => {
@ -1010,8 +1010,8 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirB = createDir('[dirB]', {providers: [provider3]});
const elAst: ElementAst = <ElementAst>parse('<div dirA dirB>', [dirA, dirB])[0];
expect(elAst.providers.length).toBe(4);
expect(elAst.providers[2].providers).toEqual([provider3]);
expect(elAst.providers[3].providers).toEqual([provider2]);
expect(elAst.providers[0].providers).toEqual([provider3]);
expect(elAst.providers[1].providers).toEqual([provider2]);
});
it('should overwrite component providers by directive providers', () => {
@ -1021,7 +1021,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirA = createDir('[dirA]', {providers: [dirProvider]});
const elAst: ElementAst = <ElementAst>parse('<my-comp dirA>', [dirA, comp])[0];
expect(elAst.providers.length).toBe(3);
expect(elAst.providers[2].providers).toEqual([dirProvider]);
expect(elAst.providers[0].providers).toEqual([dirProvider]);
});
it('should overwrite view providers by directive providers', () => {
@ -1031,7 +1031,7 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirA = createDir('[dirA]', {providers: [dirProvider]});
const elAst: ElementAst = <ElementAst>parse('<my-comp dirA>', [dirA, comp])[0];
expect(elAst.providers.length).toBe(3);
expect(elAst.providers[2].providers).toEqual([dirProvider]);
expect(elAst.providers[0].providers).toEqual([dirProvider]);
});
it('should overwrite directives by providers', () => {
@ -1053,17 +1053,17 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
`Mixing multi and non multi provider is not possible for token service0 ("[ERROR ->]<div dirA dirB>"): TestComp@0:0`);
});
it('should sort providers by their DI order', () => {
it('should sort providers by their DI order, lazy providers first', () => {
const provider0 = createProvider('service0', {deps: ['type:[dir2]']});
const provider1 = createProvider('service1');
const dir2 = createDir('[dir2]', {deps: ['service1']});
const comp = createDir('my-comp', {providers: [provider0, provider1]});
const elAst: ElementAst = <ElementAst>parse('<my-comp dir2>', [comp, dir2])[0];
expect(elAst.providers.length).toBe(4);
expect(elAst.providers[0].providers[0].useClass).toEqual(comp.type);
expect(elAst.providers[1].providers).toEqual([provider1]);
expect(elAst.providers[2].providers[0].useClass).toEqual(dir2.type);
expect(elAst.providers[3].providers).toEqual([provider0]);
expect(elAst.providers[1].providers[0].useClass).toEqual(comp.type);
expect(elAst.providers[2].providers).toEqual([provider1]);
expect(elAst.providers[3].providers[0].useClass).toEqual(dir2.type);
expect(elAst.providers[0].providers).toEqual([provider0]);
});
it('should sort directives by their DI order', () => {
@ -1086,12 +1086,12 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const dirA = createDir('[dirA]', {providers: [provider0, provider1], deps: ['service0']});
const elAst: ElementAst = <ElementAst>parse('<div dirA>', [dirA])[0];
expect(elAst.providers.length).toBe(3);
expect(elAst.providers[0].providers).toEqual([provider0]);
expect(elAst.providers[0].eager).toBe(true);
expect(elAst.providers[1].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[1].providers).toEqual([provider0]);
expect(elAst.providers[1].eager).toBe(true);
expect(elAst.providers[2].providers).toEqual([provider1]);
expect(elAst.providers[2].eager).toBe(false);
expect(elAst.providers[2].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[2].eager).toBe(true);
expect(elAst.providers[0].providers).toEqual([provider1]);
expect(elAst.providers[0].eager).toBe(false);
});
it('should mark dependencies on parent elements as eager', () => {
@ -1102,12 +1102,12 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const elAst: ElementAst =
<ElementAst>parse('<div dirA><div dirB></div></div>', [dirA, dirB])[0];
expect(elAst.providers.length).toBe(3);
expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[0].eager).toBe(true);
expect(elAst.providers[1].providers).toEqual([provider0]);
expect(elAst.providers[1].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[1].eager).toBe(true);
expect(elAst.providers[2].providers).toEqual([provider1]);
expect(elAst.providers[2].eager).toBe(false);
expect(elAst.providers[2].providers).toEqual([provider0]);
expect(elAst.providers[2].eager).toBe(true);
expect(elAst.providers[0].providers).toEqual([provider1]);
expect(elAst.providers[0].eager).toBe(false);
});
it('should mark queried providers as eager', () => {
@ -1117,12 +1117,12 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
createDir('[dirA]', {providers: [provider0, provider1], queries: ['service0']});
const elAst: ElementAst = <ElementAst>parse('<div dirA></div>', [dirA])[0];
expect(elAst.providers.length).toBe(3);
expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[0].eager).toBe(true);
expect(elAst.providers[1].providers).toEqual([provider0]);
expect(elAst.providers[1].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[1].eager).toBe(true);
expect(elAst.providers[2].providers).toEqual([provider1]);
expect(elAst.providers[2].eager).toBe(false);
expect(elAst.providers[2].providers).toEqual([provider0]);
expect(elAst.providers[2].eager).toBe(true);
expect(elAst.providers[0].providers).toEqual([provider1]);
expect(elAst.providers[0].eager).toBe(false);
});
it('should not mark dependencies across embedded views as eager', () => {
@ -1132,10 +1132,10 @@ Binding to attribute 'onEvent' is disallowed for security reasons ("<my-componen
const elAst: ElementAst =
<ElementAst>parse('<div dirA><div *ngIf dirB></div></div>', [dirA, dirB])[0];
expect(elAst.providers.length).toBe(2);
expect(elAst.providers[0].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[0].eager).toBe(true);
expect(elAst.providers[1].providers).toEqual([provider0]);
expect(elAst.providers[1].eager).toBe(false);
expect(elAst.providers[1].providers[0].useClass).toEqual(dirA.type);
expect(elAst.providers[1].eager).toBe(true);
expect(elAst.providers[0].providers).toEqual([provider0]);
expect(elAst.providers[0].eager).toBe(false);
});
it('should report missing @Self() deps as errors', () => {