Skip to content

Commit b5f6417

Browse files
committed
refactor(ElementInjector): use index instead of the elementInjector field to instantiate element injectors
1 parent 7908533 commit b5f6417

File tree

7 files changed

+38
-94
lines changed

7 files changed

+38
-94
lines changed

modules/benchmarks/src/element_injector/instantiate_benchmark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ export function run () {
88
var appInjector = new Injector([]);
99

1010
var bindings = [A, B, C];
11-
var proto = new ProtoElementInjector(null, bindings);
11+
var proto = new ProtoElementInjector(null, 0, bindings);
1212
for (var i = 0; i < ITERATIONS; ++i) {
13-
var ei = proto.instantiate({view:null});
13+
var ei = proto.instantiate({view:null, parentElementInjector: null});
1414
ei.instantiateDirectives(appInjector);
1515
}
1616
}

modules/benchmarks/src/element_injector/instantiate_benchmark_codegen.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ export function run () {
1616
], false)];
1717

1818

19-
var proto = new ProtoElementInjector(null, bindings);
19+
var proto = new ProtoElementInjector(null, 0, bindings);
2020
for (var i = 0; i < ITERATIONS; ++i) {
21-
var ei = proto.instantiate({view:null});
21+
var ei = proto.instantiate({view:null, parentElementInjector: null});
2222
ei.instantiateDirectives(appInjector);
2323
}
2424
}

modules/benchmarks/src/element_injector/instantiate_directive_benchmark.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ export function run () {
88
var appInjector = new Injector([]);
99

1010
var bindings = [A, B, C];
11-
var proto = new ProtoElementInjector(null, bindings);
12-
var ei = proto.instantiate({view:null});
11+
var proto = new ProtoElementInjector(null, 0, bindings);
12+
var ei = proto.instantiate({view:null, parentElementInjector: null});
1313

1414
for (var i = 0; i < ITERATIONS; ++i) {
1515
ei.clearDirectives();

modules/core/src/compiler/element_injector.js

Lines changed: 8 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -93,39 +93,7 @@ ElementInjector (ElementModule):
9393
PERF BENCHMARK: http://www.williambrownstreet.net/blog/2014/04/faster-angularjs-rendering-angularjs-and-reactjs/
9494
*/
9595

96-
export class ProtoElementInjector extends TreeNode {
97-
/**
98-
parent:ProtoDirectiveInjector;
99-
next:ProtoDirectiveInjector;
100-
prev:ProtoDirectiveInjector;
101-
head:ProtoDirectiveInjector;
102-
tail:ProtoDirectiveInjector;
103-
DirectiveInjector cloningInstance;
104-
KeyMap keyMap;
105-
/// Because DI tree is sparse, this shows how far away is the Parent DI
106-
parentDistance:int = 1; /// 1 for non-sparse/normal depth.
107-
108-
cKey:int; cFactory:Function; cParams:List<int>;
109-
_keyId0:int; factory0:Function; params0:List<int>;
110-
_keyId1:int; factory1:Function; params1:List<int>;
111-
_keyId2:int; factory2:Function; params2:List<int>;
112-
_keyId3:int; factory3:Function; params3:List<int>;
113-
_keyId4:int; factory4:Function; params4:List<int>;
114-
_keyId5:int; factory5:Function; params5:List<int>;
115-
_keyId6:int; factory6:Function; params6:List<int>;
116-
_keyId7:int; factory7:Function; params7:List<int>;
117-
_keyId8:int; factory8:Function; params8:List<int>;
118-
_keyId9:int; factory9:Function; params9:List<int>;
119-
120-
query_keyId0:int;
121-
query_keyId1:int;
122-
123-
textNodes:List<int>;
124-
events:Map<string, Expression>;
125-
126-
elementInjector:ElementInjector;
127-
*/
128-
@FIELD('_elementInjector:ElementInjector')
96+
export class ProtoElementInjector {
12997
@FIELD('_binding0:Binding')
13098
@FIELD('_binding1:Binding')
13199
@FIELD('_binding2:Binding')
@@ -146,10 +114,11 @@ export class ProtoElementInjector extends TreeNode {
146114
@FIELD('_key7:int')
147115
@FIELD('_key8:int')
148116
@FIELD('_key9:int')
149-
constructor(parent:ProtoElementInjector, bindings:List) {
150-
super(parent);
151-
152-
this._elementInjector = null;
117+
@FIELD('final parent:ProtoElementInjector')
118+
@FIELD('final index:int')
119+
constructor(parent:ProtoElementInjector, index:int, bindings:List) {
120+
this.parent = parent;
121+
this.index = index;
153122

154123
this._binding0 = null; this._keyId0 = null;
155124
this._binding1 = null; this._keyId1 = null;
@@ -179,15 +148,12 @@ export class ProtoElementInjector extends TreeNode {
179148
}
180149
}
181150

182-
instantiate({view}):ElementInjector {
183-
var p = this._parent;
184-
var parentElementInjector = p === null ? null : p._elementInjector;
185-
this._elementInjector = new ElementInjector({
151+
instantiate({view, parentElementInjector}):ElementInjector {
152+
return new ElementInjector({
186153
proto: this,
187154
parent: parentElementInjector,
188155
view: view
189156
});
190-
return this._elementInjector;
191157
}
192158

193159
_createBinding(bindingOrType) {
@@ -198,10 +164,6 @@ export class ProtoElementInjector extends TreeNode {
198164
return new Binding(b.key, b.factory, deps, b.providedAsPromise);
199165
}
200166

201-
clearElementInjector() {
202-
this._elementInjector = null;
203-
}
204-
205167
get hasBindings():boolean {
206168
return isPresent(this._binding0);
207169
}

modules/core/src/compiler/view.js

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -99,13 +99,9 @@ export class ProtoView {
9999
static _createElementInjectors(elements, binders) {
100100
var injectors = ListWrapper.createFixedSize(binders.length);
101101
for (var i = 0; i < binders.length; ++i) {
102-
injectors[i] = ProtoView._createElementInjector(
103-
elements[i], binders[i].protoElementInjector);
104-
}
105-
// Cannot be rolled into loop above, because parentInjector pointers need
106-
// to be set on the children.
107-
for (var i = 0; i < binders.length; ++i) {
108-
binders[i].protoElementInjector.clearElementInjector();
102+
var proto = binders[i].protoElementInjector;
103+
var parentElementInjector = isPresent(proto.parent) ? injectors[proto.parent.index] : null;
104+
injectors[i] = ProtoView._createElementInjector(elements[i], parentElementInjector, proto);
109105
}
110106
return injectors;
111107
}
@@ -117,9 +113,9 @@ export class ProtoView {
117113
}
118114
}
119115

120-
static _createElementInjector(element, proto) {
116+
static _createElementInjector(element, parent:ElementInjector, proto:ProtoElementInjector) {
121117
//TODO: vsavkin: pass element to `proto.instantiate()` once https://github.com/angular/angular/pull/98 is merged
122-
return proto.hasBindings ? proto.instantiate({view:null}) : null;
118+
return proto.hasBindings ? proto.instantiate({view:null, parentElementInjector:parent}) : null;
123119
}
124120

125121
static _rootElementInjectors(injectors) {

modules/core/test/compiler/element_injector_spec.js

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -70,50 +70,36 @@ export function main() {
7070
if (isBlank(appInjector)) appInjector = new Injector([]);
7171
if (isBlank(props)) props = {};
7272

73-
var proto = new ProtoElementInjector(null, bindings);
74-
var inj = proto.instantiate({view: props["view"]});
73+
var proto = new ProtoElementInjector(null, 0, bindings);
74+
var inj = proto.instantiate({view: props["view"], parentElementInjector:null});
7575
inj.instantiateDirectives(appInjector);
7676
return inj;
7777
}
7878

7979
function parentChildInjectors(parentBindings, childBindings) {
8080
var inj = new Injector([]);
8181

82-
var protoParent = new ProtoElementInjector(null, parentBindings);
83-
var parent = protoParent.instantiate({view: null});
82+
var protoParent = new ProtoElementInjector(null, 0, parentBindings);
83+
var parent = protoParent.instantiate({view: null, parentElementInjector: null});
8484
parent.instantiateDirectives(inj);
8585

86-
var protoChild = new ProtoElementInjector(protoParent, childBindings);
87-
var child = protoChild.instantiate({view: null});
86+
var protoChild = new ProtoElementInjector(protoParent, 1, childBindings);
87+
var child = protoChild.instantiate({view: null, parentElementInjector: parent});
8888
child.instantiateDirectives(inj);
8989

9090
return child;
9191
}
9292

9393
describe("ElementInjector", function () {
94-
describe("proto injectors", function () {
95-
it("should construct a proto tree", function () {
96-
var p = new ProtoElementInjector(null, []);
97-
var c1 = new ProtoElementInjector(p, []);
98-
var c2 = new ProtoElementInjector(p, []);
99-
100-
expect(humanize(p, [
101-
[p, 'parent'],
102-
[c1, 'child1'],
103-
[c2, 'child2']
104-
])).toEqual(["parent", ["child1", "child2"]]);
105-
});
106-
});
107-
10894
describe("instantiate", function () {
10995
it("should create an element injector", function () {
110-
var protoParent = new ProtoElementInjector(null, []);
111-
var protoChild1 = new ProtoElementInjector(protoParent, []);
112-
var protoChild2 = new ProtoElementInjector(protoParent, []);
96+
var protoParent = new ProtoElementInjector(null, 0, []);
97+
var protoChild1 = new ProtoElementInjector(protoParent, 1, []);
98+
var protoChild2 = new ProtoElementInjector(protoParent, 2, []);
11399

114-
var p = protoParent.instantiate({view: null});
115-
var c1 = protoChild1.instantiate({view: null});
116-
var c2 = protoChild2.instantiate({view: null});
100+
var p = protoParent.instantiate({view: null, parentElementInjector: null});
101+
var c1 = protoChild1.instantiate({view: null, parentElementInjector: p});
102+
var c2 = protoChild2.instantiate({view: null, parentElementInjector: p});
117103

118104
expect(humanize(p, [
119105
[p, 'parent'],
@@ -125,12 +111,12 @@ export function main() {
125111

126112
describe("hasBindings", function () {
127113
it("should be true when there are bindings", function () {
128-
var p = new ProtoElementInjector(null, [Directive]);
114+
var p = new ProtoElementInjector(null, 0, [Directive]);
129115
expect(p.hasBindings).toBeTruthy();
130116
});
131117

132118
it("should be false otherwise", function () {
133-
var p = new ProtoElementInjector(null, []);
119+
var p = new ProtoElementInjector(null, 0, []);
134120
expect(p.hasBindings).toBeFalsy();
135121
});
136122
});

modules/core/test/compiler/view_spec.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export function main() {
3434
'</section>';
3535

3636
function templateElementBinders() {
37-
var sectionPI = new ElementBinder(new ProtoElementInjector(null, []),
37+
var sectionPI = new ElementBinder(new ProtoElementInjector(null, 0, []),
3838
[0], false);
3939

4040
var divPI = new ElementBinder(new ProtoElementInjector(
41-
sectionPI.protoElementInjector, [Directive]), [], false);
41+
sectionPI.protoElementInjector, 1, [Directive]), [], false);
4242

4343
var spanPI = new ElementBinder(new ProtoElementInjector(
44-
divPI.protoElementInjector, []), [], true);
44+
divPI.protoElementInjector, 2, []), [], true);
4545
return [sectionPI, divPI, spanPI];
4646
}
4747

@@ -76,9 +76,9 @@ export function main() {
7676
'</section>');
7777

7878
var sectionPI = new ElementBinder(new ProtoElementInjector(
79-
null, [Directive]), [], false);
79+
null, 0, [Directive]), [], false);
8080
var divPI = new ElementBinder(new ProtoElementInjector(
81-
sectionPI.protoElementInjector, [Directive]), [], false);
81+
sectionPI.protoElementInjector, 1, [Directive]), [], false);
8282

8383
var pv = new ProtoView(template, [sectionPI, divPI],
8484
new ProtoWatchGroup(), false);

0 commit comments

Comments
 (0)