Skip to content

Commit 8811337

Browse files
committed
refactor(ElementInjector): add interfaces for strategies
1 parent 921fb9f commit 8811337

1 file changed

Lines changed: 62 additions & 35 deletions

File tree

modules/angular2/src/core/compiler/element_injector.ts

Lines changed: 62 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,11 @@
1-
import {isPresent, isBlank, Type, BaseException, stringify} from 'angular2/src/facade/lang';
1+
import {
2+
isPresent,
3+
isBlank,
4+
Type,
5+
BaseException,
6+
stringify,
7+
CONST_EXPR
8+
} from 'angular2/src/facade/lang';
29
import {EventEmitter, ObservableWrapper} from 'angular2/src/facade/async';
310
import {List, ListWrapper, MapWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
411
import {
@@ -39,7 +46,7 @@ import {DirectiveMetadata} from 'angular2/src/render/api';
3946
// Threshold for the dynamic version
4047
var _MAX_DIRECTIVE_CONSTRUCTION_COUNTER = 10;
4148

42-
var _undefined = new Object();
49+
const _undefined = CONST_EXPR(new Object());
4350

4451
var _staticKeys;
4552

@@ -424,7 +431,7 @@ export class ProtoElementInjector {
424431
/** The variable name that will be set to $implicit for the element. */
425432
exportImplicitName: string;
426433

427-
_strategy;
434+
_strategy: _ProtoElementInjectorStrategy;
428435

429436
static create(parent: ProtoElementInjector, index: number, bindings: List<ResolvedBinding>,
430437
firstBindingIsComponent: boolean, distanceToParent: number) {
@@ -484,8 +491,8 @@ export class ProtoElementInjector {
484491
this.hostActionAccessors = ListWrapper.createFixedSize(length);
485492

486493
this._strategy = length > _MAX_DIRECTIVE_CONSTRUCTION_COUNTER ?
487-
new ProtoElementInjectorDynamicStrategy(this, bd) :
488-
new ProtoElementInjectorInlineStrategy(this, bd);
494+
new _ProtoElementInjectorDynamicStrategy(this, bd) :
495+
new _ProtoElementInjectorInlineStrategy(this, bd);
489496
}
490497

491498
instantiate(parent: ElementInjector): ElementInjector {
@@ -499,12 +506,17 @@ export class ProtoElementInjector {
499506
getBindingAtIndex(index: number): any { return this._strategy.getBindingAtIndex(index); }
500507
}
501508

509+
interface _ProtoElementInjectorStrategy {
510+
hasBindings(): boolean;
511+
getBindingAtIndex(index: number): any;
512+
createElementInjectorStrategy(ei: ElementInjector): _ElementInjectorStrategy;
513+
}
514+
502515
/**
503516
* Strategy used by the `ProtoElementInjector` when the number of bindings is 10 or less.
504517
* In such a case, inlining fields is benefitial for performances.
505518
*/
506-
// TODO(vicb): add an interface
507-
class ProtoElementInjectorInlineStrategy {
519+
class _ProtoElementInjectorInlineStrategy implements _ProtoElementInjectorStrategy {
508520
// only _binding0 can contain a component
509521
_binding0: ResolvedBinding = null;
510522
_binding1: ResolvedBinding = null;
@@ -630,16 +642,15 @@ class ProtoElementInjectorInlineStrategy {
630642
throw new OutOfBoundsAccess(index);
631643
}
632644

633-
createElementInjectorStrategy(ei: ElementInjector) {
645+
createElementInjectorStrategy(ei: ElementInjector): _ElementInjectorStrategy {
634646
return new ElementInjectorInlineStrategy(this, ei);
635647
}
636648
}
637649

638650
/**
639651
* Strategy used by the `ProtoElementInjector` when the number of bindings is more than 10.
640652
*/
641-
// TODO(vicb): add an interface
642-
class ProtoElementInjectorDynamicStrategy {
653+
class _ProtoElementInjectorDynamicStrategy implements _ProtoElementInjectorStrategy {
643654
// only _bindings[0] can contain a component
644655
_bindings: List<ResolvedBinding>;
645656
_keyIds: List<number>;
@@ -693,7 +704,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
693704
private _query1: QueryRef;
694705
private _query2: QueryRef;
695706

696-
_strategy;
707+
_strategy: _ElementInjectorStrategy;
697708

698709
constructor(public _proto: ProtoElementInjector, parent: ElementInjector) {
699710
super(parent);
@@ -705,7 +716,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
705716
this._buildQueries();
706717
}
707718

708-
dehydrate() {
719+
dehydrate(): void {
709720
this._host = null;
710721
this._preBuiltObjects = null;
711722
this._lightDomAppInjector = null;
@@ -727,7 +738,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
727738
}
728739

729740

730-
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects) {
741+
hydrate(injector: Injector, host: ElementInjector, preBuiltObjects: PreBuiltObjects): void {
731742
var p = this._proto;
732743

733744
this._host = host;
@@ -744,23 +755,24 @@ export class ElementInjector extends TreeNode<ElementInjector> {
744755
this._strategy.hydrate();
745756
}
746757

747-
private _createShadowDomAppInjector(componentDirective: DirectiveBinding, appInjector: Injector) {
758+
private _createShadowDomAppInjector(componentDirective: DirectiveBinding,
759+
appInjector: Injector): Injector {
748760
if (!ListWrapper.isEmpty(componentDirective.resolvedAppInjectables)) {
749761
return appInjector.createChildFromResolved(componentDirective.resolvedAppInjectables);
750762
} else {
751763
return appInjector;
752764
}
753765
}
754766

755-
dynamicallyCreateComponent(componentDirective: DirectiveBinding, parentInjector: Injector) {
767+
dynamicallyCreateComponent(componentDirective: DirectiveBinding, parentInjector: Injector): any {
756768
this._shadowDomAppInjector =
757769
this._createShadowDomAppInjector(componentDirective, parentInjector);
758770
this._dynamicallyCreatedComponentBinding = componentDirective;
759771
this._dynamicallyCreatedComponent = this._new(this._dynamicallyCreatedComponentBinding);
760772
return this._dynamicallyCreatedComponent;
761773
}
762774

763-
private _checkShadowDomAppInjector(shadowDomAppInjector: Injector) {
775+
private _checkShadowDomAppInjector(shadowDomAppInjector: Injector): void {
764776
if (this._proto._firstBindingIsComponent && isBlank(shadowDomAppInjector)) {
765777
throw new BaseException(
766778
'A shadowDomAppInjector is required as this ElementInjector contains a component');
@@ -770,15 +782,15 @@ export class ElementInjector extends TreeNode<ElementInjector> {
770782
}
771783
}
772784

773-
get(token) {
785+
get(token): any {
774786
if (this._isDynamicallyLoadedComponent(token)) {
775787
return this._dynamicallyCreatedComponent;
776788
}
777789

778790
return this._getByKey(Key.get(token), self, false, null);
779791
}
780792

781-
private _isDynamicallyLoadedComponent(token) {
793+
private _isDynamicallyLoadedComponent(token): boolean {
782794
return isPresent(this._dynamicallyCreatedComponentBinding) &&
783795
Key.get(token) === this._dynamicallyCreatedComponentBinding.key;
784796
}
@@ -797,21 +809,21 @@ export class ElementInjector extends TreeNode<ElementInjector> {
797809

798810
getComponent(): any { return this._strategy.getComponent(); }
799811

800-
getElementRef() {
812+
getElementRef(): ElementRef {
801813
return new ElementRef(new ViewRef(this._preBuiltObjects.view), this._proto.index);
802814
}
803815

804-
getViewContainerRef() {
816+
getViewContainerRef(): ViewContainerRef {
805817
return new ViewContainerRef(this._preBuiltObjects.viewManager, this.getElementRef());
806818
}
807819

808-
getDynamicallyLoadedComponent() { return this._dynamicallyCreatedComponent; }
820+
getDynamicallyLoadedComponent(): any { return this._dynamicallyCreatedComponent; }
809821

810822
directParent(): ElementInjector { return this._proto.distanceToParent < 2 ? this.parent : null; }
811823

812-
private _isComponentKey(key: Key) { return this._strategy.isComponentKey(key); }
824+
private _isComponentKey(key: Key): boolean { return this._strategy.isComponentKey(key); }
813825

814-
private _isDynamicallyLoadedComponentKey(key: Key) {
826+
private _isDynamicallyLoadedComponentKey(key: Key): boolean {
815827
return isPresent(this._dynamicallyCreatedComponentBinding) &&
816828
key.id === this._dynamicallyCreatedComponentBinding.key.id;
817829
}
@@ -884,7 +896,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
884896
return obj;
885897
}
886898

887-
private _getByDependency(dep: DependencyWithVisibility, requestor: Key) {
899+
private _getByDependency(dep: DependencyWithVisibility, requestor: Key): any {
888900
if (!(dep instanceof DirectiveDependency)) {
889901
return this._getByKey(dep.key, dep.visibility, dep.optional, requestor);
890902
}
@@ -959,7 +971,7 @@ export class ElementInjector extends TreeNode<ElementInjector> {
959971
}
960972

961973
// TODO(rado): unify with _addParentQueries.
962-
private _inheritQueries(parent: ElementInjector) {
974+
private _inheritQueries(parent: ElementInjector): void {
963975
if (isBlank(parent)) return;
964976
if (isPresent(parent._query0)) {
965977
this._query0 = parent._query0;
@@ -1170,12 +1182,24 @@ export class ElementInjector extends TreeNode<ElementInjector> {
11701182
getBoundElementIndex(): number { return this._proto.index; }
11711183
}
11721184

1185+
interface _ElementInjectorStrategy {
1186+
callOnDestroy(): void;
1187+
clearInstances(): void;
1188+
hydrate(): void;
1189+
getComponent(): any;
1190+
isComponentKey(key: Key): boolean;
1191+
buildQueries(): void;
1192+
getObjByKeyId(keyId: number, visibility: number): any;
1193+
getDirectiveAtIndex(index: number): any;
1194+
getComponentBinding(): DirectiveBinding;
1195+
getMaxDirectives(): number;
1196+
}
1197+
11731198
/**
11741199
* Strategy used by the `ElementInjector` when the number of bindings is 10 or less.
11751200
* In such a case, inlining fields is benefitial for performances.
11761201
*/
1177-
// TODO(vicb): add an interface
1178-
class ElementInjectorInlineStrategy {
1202+
class ElementInjectorInlineStrategy implements _ElementInjectorStrategy {
11791203
// If this element injector has a component, the component instance will be stored in _obj0
11801204
_obj0: any = null;
11811205
_obj1: any = null;
@@ -1188,7 +1212,7 @@ class ElementInjectorInlineStrategy {
11881212
_obj8: any = null;
11891213
_obj9: any = null;
11901214

1191-
constructor(public _protoStrategy: ProtoElementInjectorInlineStrategy,
1215+
constructor(public _protoStrategy: _ProtoElementInjectorInlineStrategy,
11921216
public _ei: ElementInjector) {}
11931217

11941218
callOnDestroy(): void {
@@ -1256,7 +1280,7 @@ class ElementInjectorInlineStrategy {
12561280

12571281
getComponent(): any { return this._obj0; }
12581282

1259-
isComponentKey(key: Key) {
1283+
isComponentKey(key: Key): boolean {
12601284
return this._ei._proto._firstBindingIsComponent && isPresent(key) &&
12611285
key.id === this._protoStrategy._keyId0;
12621286
}
@@ -1376,7 +1400,9 @@ class ElementInjectorInlineStrategy {
13761400
throw new OutOfBoundsAccess(index);
13771401
}
13781402

1379-
getComponentBinding(): ResolvedBinding { return this._protoStrategy._binding0; }
1403+
getComponentBinding(): DirectiveBinding {
1404+
return <DirectiveBinding>this._protoStrategy._binding0;
1405+
}
13801406

13811407
getMaxDirectives(): number { return _MAX_DIRECTIVE_CONSTRUCTION_COUNTER; }
13821408
}
@@ -1385,12 +1411,11 @@ class ElementInjectorInlineStrategy {
13851411
* Strategy used by the `ElementInjector` when the number of bindings is 10 or less.
13861412
* In such a case, inlining fields is benefitial for performances.
13871413
*/
1388-
// TODO(vicb): add an interface
1389-
class ElementInjectorDynamicStrategy {
1414+
class ElementInjectorDynamicStrategy implements _ElementInjectorStrategy {
13901415
// If this element injector has a component, the component instance will be stored in _objs[0]
13911416
_objs: List<any>;
13921417

1393-
constructor(public _protoStrategy: ProtoElementInjectorDynamicStrategy,
1418+
constructor(public _protoStrategy: _ProtoElementInjectorDynamicStrategy,
13941419
public _ei: ElementInjector) {
13951420
this._objs = ListWrapper.createFixedSize(_protoStrategy._bindings.length);
13961421
}
@@ -1420,7 +1445,7 @@ class ElementInjectorDynamicStrategy {
14201445

14211446
getComponent(): any { return this._objs[0]; }
14221447

1423-
isComponentKey(key: Key) {
1448+
isComponentKey(key: Key): boolean {
14241449
return this._ei._proto._firstBindingIsComponent && isPresent(key) &&
14251450
key.id === this._protoStrategy._keyIds[0];
14261451
}
@@ -1460,7 +1485,9 @@ class ElementInjectorDynamicStrategy {
14601485
return this._objs[index];
14611486
}
14621487

1463-
getComponentBinding(): ResolvedBinding { return this._protoStrategy._bindings[0]; }
1488+
getComponentBinding(): DirectiveBinding {
1489+
return <DirectiveBinding>this._protoStrategy._bindings[0];
1490+
}
14641491

14651492
getMaxDirectives(): number { return this._objs.length; }
14661493
}

0 commit comments

Comments
 (0)