fix: consistently rewrite Injector to INJECTOR (#23008)

In Ivy mode we rewrite references to Injector to INJECTOR in ngInjectableDef, to fix tree-shaking.

This changes the rewrite to happen always, even in non-Ivy mode, and makes Angular understand
INJECTOR across the board at runtime.

PR Close #23008
This commit is contained in:
Alex Rickabaugh 2018-03-26 16:22:46 -07:00
parent 0b348c8ffe
commit 884bf0ef09
5 changed files with 33 additions and 4 deletions

View File

@ -6,7 +6,7 @@
* found in the LICENSE file at https://angular.io/license * found in the LICENSE file at https://angular.io/license
*/ */
import {Component, Injectable, NgModule} from '@angular/core'; import {Component, INJECTOR, Injectable, NgModule} from '@angular/core';
import {TestBed} from '@angular/core/testing'; import {TestBed} from '@angular/core/testing';
import {renderModuleFactory} from '@angular/platform-server'; import {renderModuleFactory} from '@angular/platform-server';
import {BasicAppModuleNgFactory} from 'app_built/src/basic.ngfactory'; import {BasicAppModuleNgFactory} from 'app_built/src/basic.ngfactory';
@ -142,4 +142,28 @@ describe('ngInjectableDef Bazel Integration', () => {
TestBed.configureTestingModule({}); TestBed.configureTestingModule({});
expect(TestBed.get(Service).value).toEqual(true); expect(TestBed.get(Service).value).toEqual(true);
}); });
it('NgModule injector understands requests for INJECTABLE', () => {
TestBed.configureTestingModule({
providers: [{provide: 'foo', useValue: 'bar'}],
});
expect(TestBed.get(INJECTOR).get('foo')).toEqual('bar');
});
it('Component injector understands requests for INJECTABLE', () => {
@Component({
selector: 'test-cmp',
template: 'test',
providers: [{provide: 'foo', useValue: 'bar'}],
})
class TestCmp {
}
TestBed.configureTestingModule({
declarations: [TestCmp],
});
const fixture = TestBed.createComponent(TestCmp);
expect(fixture.componentRef.injector.get(INJECTOR).get('foo')).toEqual('bar');
});
}); });

View File

@ -63,7 +63,7 @@ export class InjectableCompiler {
let tokenExpr: o.Expression; let tokenExpr: o.Expression;
if (typeof token === 'string') { if (typeof token === 'string') {
tokenExpr = o.literal(token); tokenExpr = o.literal(token);
} else if (token === this.tokenInjector && this.alwaysGenerateDef) { } else if (token === this.tokenInjector) {
tokenExpr = o.importExpr(Identifiers.INJECTOR); tokenExpr = o.importExpr(Identifiers.INJECTOR);
} else { } else {
tokenExpr = ctx.importExpr(token); tokenExpr = ctx.importExpr(token);

View File

@ -145,7 +145,7 @@ export class StaticInjector implements Injector {
records.set( records.set(
Injector, <Record>{token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false}); Injector, <Record>{token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false});
records.set( records.set(
INJECTOR, <Record>{token: Injector, fn: IDENT, deps: EMPTY, value: this, useNew: false}); INJECTOR, <Record>{token: INJECTOR, fn: IDENT, deps: EMPTY, value: this, useNew: false});
recursivelyProcessProviders(records, providers); recursivelyProcessProviders(records, providers);
} }

View File

@ -19,6 +19,7 @@ import {splitDepsDsl, tokenKey} from './util';
const UNDEFINED_VALUE = new Object(); const UNDEFINED_VALUE = new Object();
const InjectorRefTokenKey = tokenKey(Injector); const InjectorRefTokenKey = tokenKey(Injector);
const INJECTORRefTokenKey = tokenKey(INJECTOR);
const NgModuleRefTokenKey = tokenKey(NgModuleRef); const NgModuleRefTokenKey = tokenKey(NgModuleRef);
export function moduleProvideDef( export function moduleProvideDef(
@ -86,6 +87,7 @@ export function resolveNgModuleDep(
const tokenKey = depDef.tokenKey; const tokenKey = depDef.tokenKey;
switch (tokenKey) { switch (tokenKey) {
case InjectorRefTokenKey: case InjectorRefTokenKey:
case INJECTORRefTokenKey:
case NgModuleRefTokenKey: case NgModuleRefTokenKey:
return data; return data;
} }

View File

@ -7,12 +7,13 @@
*/ */
import {ChangeDetectorRef, SimpleChange, SimpleChanges, WrappedValue} from '../change_detection/change_detection'; import {ChangeDetectorRef, SimpleChange, SimpleChanges, WrappedValue} from '../change_detection/change_detection';
import {Injector, resolveForwardRef} from '../di'; import {INJECTOR, Injector, resolveForwardRef} from '../di';
import {ElementRef} from '../linker/element_ref'; import {ElementRef} from '../linker/element_ref';
import {TemplateRef} from '../linker/template_ref'; import {TemplateRef} from '../linker/template_ref';
import {ViewContainerRef} from '../linker/view_container_ref'; import {ViewContainerRef} from '../linker/view_container_ref';
import {Renderer as RendererV1, Renderer2} from '../render/api'; import {Renderer as RendererV1, Renderer2} from '../render/api';
import {stringify} from '../util'; import {stringify} from '../util';
import {createChangeDetectorRef, createInjector, createRendererV1} from './refs'; import {createChangeDetectorRef, createInjector, createRendererV1} from './refs';
import {BindingDef, BindingFlags, DepDef, DepFlags, NodeDef, NodeFlags, OutputDef, OutputType, ProviderData, QueryValueType, Services, ViewData, ViewFlags, ViewState, asElementData, asProviderData, shouldCallLifecycleInitHook} from './types'; import {BindingDef, BindingFlags, DepDef, DepFlags, NodeDef, NodeFlags, OutputDef, OutputType, ProviderData, QueryValueType, Services, ViewData, ViewFlags, ViewState, asElementData, asProviderData, shouldCallLifecycleInitHook} from './types';
import {calcBindingFlags, checkBinding, dispatchEvent, isComponentView, splitDepsDsl, splitMatchedQueriesDsl, tokenKey, viewParentEl} from './util'; import {calcBindingFlags, checkBinding, dispatchEvent, isComponentView, splitDepsDsl, splitMatchedQueriesDsl, tokenKey, viewParentEl} from './util';
@ -24,6 +25,7 @@ const ViewContainerRefTokenKey = tokenKey(ViewContainerRef);
const TemplateRefTokenKey = tokenKey(TemplateRef); const TemplateRefTokenKey = tokenKey(TemplateRef);
const ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef); const ChangeDetectorRefTokenKey = tokenKey(ChangeDetectorRef);
const InjectorRefTokenKey = tokenKey(Injector); const InjectorRefTokenKey = tokenKey(Injector);
const INJECTORRefTokenKey = tokenKey(INJECTOR);
export function directiveDef( export function directiveDef(
checkIndex: number, flags: NodeFlags, checkIndex: number, flags: NodeFlags,
@ -373,6 +375,7 @@ export function resolveDep(
return createChangeDetectorRef(cdView); return createChangeDetectorRef(cdView);
} }
case InjectorRefTokenKey: case InjectorRefTokenKey:
case INJECTORRefTokenKey:
return createInjector(searchView, elDef); return createInjector(searchView, elDef);
default: default:
const providerDef = const providerDef =