X Tutup
Skip to content

Commit 5298055

Browse files
author
Tim Blasi
committed
feat(dart/change_detect): Add type to ChangeDetector context
Add a type for the `context` field in Dart's pre-generated change detectors. This requires slight changes to set the dehydrated value of `context` to `null` rather than `ChangeDetectionUtil.uninitialized()`, which was its former dehydrated state. Mirror these chagnes as closely as possible in the `ChangeDetectionJITGenerator` to allow easier maintenance. Closes #2070
1 parent 851797a commit 5298055

File tree

5 files changed

+45
-28
lines changed

5 files changed

+45
-28
lines changed

modules/angular2/src/change_detection/change_detection_jit_generator.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ export class ChangeDetectorJITGenerator {
131131
}
132132
133133
${this.typeName}.prototype.hydrated = function() {
134-
return ${CONTEXT_ACCESSOR} !== ${UTIL}.uninitialized();
134+
return Boolean(${CONTEXT_ACCESSOR});
135135
}
136136
137137
return function(dispatcher, pipeRegistry) {
@@ -173,7 +173,11 @@ export class ChangeDetectorJITGenerator {
173173
fields = fields.concat(this._getNonNullPipeNames());
174174
fields = fields.concat(this._genGetDirectiveFieldNames());
175175
fields = fields.concat(this._genGetDetectorFieldNames());
176-
return fields.map((n) => `${n} = ${UTIL}.uninitialized();`).join("\n");
176+
return fields.map((n) => {
177+
return n == CONTEXT_ACCESSOR ? `${n} = null;` :
178+
`${n} = ${UTIL}.uninitialized();`;
179+
})
180+
.join("\n");
177181
}
178182

179183
_genHydrateDirectives(): string {

modules/angular2/src/transform/template_compiler/change_detector_codegen.dart

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,11 @@ import 'package:angular2/src/change_detection/proto_record.dart';
1515
class Codegen {
1616
final StringBuffer _buf = new StringBuffer();
1717

18-
void generate(String name, ChangeDetectorDefinition def) {
19-
new _CodegenState(name, def)._writeToBuf(_buf);
18+
/// Generates a change detector class with name `changeDetectorTypeName`
19+
/// which is used to detect changes in Objects of type `typeName`.
20+
void generate(String typeName, String changeDetectorTypeName,
21+
ChangeDetectorDefinition def) {
22+
new _CodegenState(typeName, changeDetectorTypeName, def)._writeToBuf(_buf);
2023
}
2124

2225
String get imports {
@@ -33,7 +36,8 @@ class Codegen {
3336

3437
/// The state needed to generate a change detector for a single `Component`.
3538
class _CodegenState {
36-
final String _typeName;
39+
final String _contextTypeName;
40+
final String _changeDetectorTypeName;
3741
final String _changeDetectionMode;
3842
final List<ProtoRecord> _records;
3943
final List<DirectiveRecord> _directiveRecords;
@@ -42,30 +46,33 @@ class _CodegenState {
4246
final List<String> _fieldNames;
4347
final List<String> _pipeNames;
4448

45-
_CodegenState._(this._typeName, String changeDetectionStrategy, this._records,
46-
this._directiveRecords, List<String> localNames)
49+
_CodegenState._(this._contextTypeName, this._changeDetectorTypeName,
50+
String changeDetectionStrategy, this._records, this._directiveRecords,
51+
List<String> localNames)
4752
: this._localNames = localNames,
4853
_changeNames = _getChangeNames(localNames),
4954
_fieldNames = _getFieldNames(localNames),
5055
_pipeNames = _getPipeNames(localNames),
5156
_changeDetectionMode = ChangeDetectionUtil
5257
.changeDetectionMode(changeDetectionStrategy);
5358

54-
factory _CodegenState(String typeName, ChangeDetectorDefinition def) {
59+
factory _CodegenState(String typeName, String changeDetectorTypeName,
60+
ChangeDetectorDefinition def) {
5561
var protoRecords = new ProtoRecordBuilder();
5662
def.bindingRecords
5763
.forEach((rec) => protoRecords.add(rec, def.variableNames));
5864
var records = coalesce(protoRecords.records);
59-
return new _CodegenState._(typeName, def.strategy, records,
60-
def.directiveRecords, _getLocalNames(records));
65+
return new _CodegenState._(typeName, changeDetectorTypeName, def.strategy,
66+
records, def.directiveRecords, _getLocalNames(records));
6167
}
6268

6369
/// Generates sanitized names for use as local variables.
6470
static List<String> _getLocalNames(List<ProtoRecord> records) {
71+
var whitespacePattern = new RegExp(r'\W');
6572
var localNames = new List<String>(records.length + 1);
6673
localNames[0] = 'context';
6774
for (var i = 0; i < records.length; ++i) {
68-
var sanitizedName = records[i].name.replaceAll(new RegExp(r'\W'), '');
75+
var sanitizedName = records[i].name.replaceAll(whitespacePattern, '');
6976
localNames[i + 1] = '$sanitizedName$i';
7077
}
7178
return localNames;
@@ -85,17 +92,21 @@ class _CodegenState {
8592

8693
void _writeToBuf(StringBuffer buf) {
8794
buf.write('''
88-
class $_typeName extends $_BASE_CLASS {
95+
class $_changeDetectorTypeName extends $_BASE_CLASS {
8996
final dynamic $_DISPATCHER_ACCESSOR;
9097
final $_GEN_PREFIX.PipeRegistry $_PIPE_REGISTRY_ACCESSOR;
9198
final $_GEN_PREFIX.List<$_GEN_PREFIX.ProtoRecord> $_PROTOS_ACCESSOR;
9299
final $_GEN_PREFIX.List<$_GEN_PREFIX.DirectiveRecord>
93100
$_DIRECTIVES_ACCESSOR;
94101
dynamic $_LOCALS_ACCESSOR = null;
95-
${_allFields().map(
96-
(f) => 'dynamic $f = $_UTIL.uninitialized();').join('')}
97-
98-
$_typeName(
102+
${_allFields().map((f) {
103+
if (f == _CONTEXT_ACCESSOR) {
104+
return '$_contextTypeName $f = null;';
105+
}
106+
return 'dynamic $f = $_UTIL.uninitialized();';
107+
}).join('')}
108+
109+
$_changeDetectorTypeName(
99110
this.$_DISPATCHER_ACCESSOR,
100111
this.$_PIPE_REGISTRY_ACCESSOR,
101112
this.$_PROTOS_ACCESSOR,
@@ -116,7 +127,7 @@ class _CodegenState {
116127
${_getCallOnAllChangesDoneBody()}
117128
}
118129
119-
void hydrate(context, locals, directives) {
130+
void hydrate($_contextTypeName context, locals, directives) {
120131
$_MODE_ACCESSOR = '$_changeDetectionMode';
121132
$_CONTEXT_ACCESSOR = context;
122133
$_LOCALS_ACCESSOR = locals;
@@ -126,19 +137,22 @@ class _CodegenState {
126137
127138
void dehydrate() {
128139
${_genPipeOnDestroy()}
129-
${_allFields().map((f) => '$f = $_UTIL.uninitialized();').join('')}
140+
${_allFields().map((f) {
141+
return f == _CONTEXT_ACCESSOR
142+
? '$f = null;'
143+
: '$f = $_UTIL.uninitialized();';
144+
}).join('')}
130145
$_LOCALS_ACCESSOR = null;
131146
}
132147
133-
hydrated() => !$_IDENTICAL_CHECK_FN(
134-
$_CONTEXT_ACCESSOR, $_UTIL.uninitialized());
148+
hydrated() => $_CONTEXT_ACCESSOR == null;
135149
136150
static $_GEN_PREFIX.ProtoChangeDetector
137151
$PROTO_CHANGE_DETECTOR_FACTORY_METHOD(
138152
$_GEN_PREFIX.PipeRegistry registry,
139153
$_GEN_PREFIX.ChangeDetectorDefinition def) {
140154
return new $_GEN_PREFIX.PregenProtoChangeDetector(
141-
(a, b, c, d) => new $_typeName(a, b, c, d),
155+
(a, b, c, d) => new $_changeDetectorTypeName(a, b, c, d),
142156
registry, def);
143157
}
144158
}

modules/angular2/src/transform/template_compiler/generator.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
4848
var defs = getChangeDetectorDefinitions(viewDefEntry.hostMetadata,
4949
result.protoView, viewDefEntry.viewDef.directives);
5050
for (var i = 0; i < defs.length; ++i) {
51-
changeDetectorClasses.generate(
51+
changeDetectorClasses.generate('${rType.typeName}',
5252
'_${rType.typeName}_ChangeDetector$i', defs[i]);
5353
}
5454

modules/angular2/test/change_detection/generator/gen_change_detectors.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ void main(List<String> args) {
1313
var allDefs = getAllDefinitions('propName');
1414
for (var i = 0; i < allDefs.length; ++i) {
1515
var className = 'ChangeDetector${i}';
16-
codegen.generate(className, allDefs[i]);
16+
codegen.generate('dynamic', className, allDefs[i]);
1717
if (i > 0) {
1818
buf.write(',');
1919
}

modules/angular2/test/transform/integration/two_annotations_files/expected/bar.ng_deps.dart

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
2727
final _gen.List<_gen.ProtoRecord> _protos;
2828
final _gen.List<_gen.DirectiveRecord> _directiveRecords;
2929
dynamic _locals = null;
30-
dynamic _context = _gen.ChangeDetectionUtil.uninitialized();
30+
MyComponent _context = null;
3131

3232
_MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry,
3333
this._protos, this._directiveRecords)
@@ -45,19 +45,18 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
4545

4646
void callOnAllChangesDone() {}
4747

48-
void hydrate(context, locals, directives) {
48+
void hydrate(MyComponent context, locals, directives) {
4949
mode = 'ALWAYS_CHECK';
5050
_context = context;
5151
_locals = locals;
5252
}
5353

5454
void dehydrate() {
55-
_context = _gen.ChangeDetectionUtil.uninitialized();
55+
_context = null;
5656
_locals = null;
5757
}
5858

59-
hydrated() =>
60-
!_gen.looseIdentical(_context, _gen.ChangeDetectionUtil.uninitialized());
59+
hydrated() => _context == null;
6160

6261
static _gen.ProtoChangeDetector newProtoChangeDetector(
6362
_gen.PipeRegistry registry, _gen.ChangeDetectorDefinition def) {

0 commit comments

Comments
 (0)
X Tutup