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
This commit is contained in:
parent
851797aecb
commit
529805508a
|
@ -131,7 +131,7 @@ export class ChangeDetectorJITGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
${this.typeName}.prototype.hydrated = function() {
|
${this.typeName}.prototype.hydrated = function() {
|
||||||
return ${CONTEXT_ACCESSOR} !== ${UTIL}.uninitialized();
|
return Boolean(${CONTEXT_ACCESSOR});
|
||||||
}
|
}
|
||||||
|
|
||||||
return function(dispatcher, pipeRegistry) {
|
return function(dispatcher, pipeRegistry) {
|
||||||
|
@ -173,7 +173,11 @@ export class ChangeDetectorJITGenerator {
|
||||||
fields = fields.concat(this._getNonNullPipeNames());
|
fields = fields.concat(this._getNonNullPipeNames());
|
||||||
fields = fields.concat(this._genGetDirectiveFieldNames());
|
fields = fields.concat(this._genGetDirectiveFieldNames());
|
||||||
fields = fields.concat(this._genGetDetectorFieldNames());
|
fields = fields.concat(this._genGetDetectorFieldNames());
|
||||||
return fields.map((n) => `${n} = ${UTIL}.uninitialized();`).join("\n");
|
return fields.map((n) => {
|
||||||
|
return n == CONTEXT_ACCESSOR ? `${n} = null;` :
|
||||||
|
`${n} = ${UTIL}.uninitialized();`;
|
||||||
|
})
|
||||||
|
.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
_genHydrateDirectives(): string {
|
_genHydrateDirectives(): string {
|
||||||
|
|
|
@ -15,8 +15,11 @@ import 'package:angular2/src/change_detection/proto_record.dart';
|
||||||
class Codegen {
|
class Codegen {
|
||||||
final StringBuffer _buf = new StringBuffer();
|
final StringBuffer _buf = new StringBuffer();
|
||||||
|
|
||||||
void generate(String name, ChangeDetectorDefinition def) {
|
/// Generates a change detector class with name `changeDetectorTypeName`
|
||||||
new _CodegenState(name, def)._writeToBuf(_buf);
|
/// which is used to detect changes in Objects of type `typeName`.
|
||||||
|
void generate(String typeName, String changeDetectorTypeName,
|
||||||
|
ChangeDetectorDefinition def) {
|
||||||
|
new _CodegenState(typeName, changeDetectorTypeName, def)._writeToBuf(_buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
String get imports {
|
String get imports {
|
||||||
|
@ -33,7 +36,8 @@ class Codegen {
|
||||||
|
|
||||||
/// The state needed to generate a change detector for a single `Component`.
|
/// The state needed to generate a change detector for a single `Component`.
|
||||||
class _CodegenState {
|
class _CodegenState {
|
||||||
final String _typeName;
|
final String _contextTypeName;
|
||||||
|
final String _changeDetectorTypeName;
|
||||||
final String _changeDetectionMode;
|
final String _changeDetectionMode;
|
||||||
final List<ProtoRecord> _records;
|
final List<ProtoRecord> _records;
|
||||||
final List<DirectiveRecord> _directiveRecords;
|
final List<DirectiveRecord> _directiveRecords;
|
||||||
|
@ -42,8 +46,9 @@ class _CodegenState {
|
||||||
final List<String> _fieldNames;
|
final List<String> _fieldNames;
|
||||||
final List<String> _pipeNames;
|
final List<String> _pipeNames;
|
||||||
|
|
||||||
_CodegenState._(this._typeName, String changeDetectionStrategy, this._records,
|
_CodegenState._(this._contextTypeName, this._changeDetectorTypeName,
|
||||||
this._directiveRecords, List<String> localNames)
|
String changeDetectionStrategy, this._records, this._directiveRecords,
|
||||||
|
List<String> localNames)
|
||||||
: this._localNames = localNames,
|
: this._localNames = localNames,
|
||||||
_changeNames = _getChangeNames(localNames),
|
_changeNames = _getChangeNames(localNames),
|
||||||
_fieldNames = _getFieldNames(localNames),
|
_fieldNames = _getFieldNames(localNames),
|
||||||
|
@ -51,21 +56,23 @@ class _CodegenState {
|
||||||
_changeDetectionMode = ChangeDetectionUtil
|
_changeDetectionMode = ChangeDetectionUtil
|
||||||
.changeDetectionMode(changeDetectionStrategy);
|
.changeDetectionMode(changeDetectionStrategy);
|
||||||
|
|
||||||
factory _CodegenState(String typeName, ChangeDetectorDefinition def) {
|
factory _CodegenState(String typeName, String changeDetectorTypeName,
|
||||||
|
ChangeDetectorDefinition def) {
|
||||||
var protoRecords = new ProtoRecordBuilder();
|
var protoRecords = new ProtoRecordBuilder();
|
||||||
def.bindingRecords
|
def.bindingRecords
|
||||||
.forEach((rec) => protoRecords.add(rec, def.variableNames));
|
.forEach((rec) => protoRecords.add(rec, def.variableNames));
|
||||||
var records = coalesce(protoRecords.records);
|
var records = coalesce(protoRecords.records);
|
||||||
return new _CodegenState._(typeName, def.strategy, records,
|
return new _CodegenState._(typeName, changeDetectorTypeName, def.strategy,
|
||||||
def.directiveRecords, _getLocalNames(records));
|
records, def.directiveRecords, _getLocalNames(records));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates sanitized names for use as local variables.
|
/// Generates sanitized names for use as local variables.
|
||||||
static List<String> _getLocalNames(List<ProtoRecord> records) {
|
static List<String> _getLocalNames(List<ProtoRecord> records) {
|
||||||
|
var whitespacePattern = new RegExp(r'\W');
|
||||||
var localNames = new List<String>(records.length + 1);
|
var localNames = new List<String>(records.length + 1);
|
||||||
localNames[0] = 'context';
|
localNames[0] = 'context';
|
||||||
for (var i = 0; i < records.length; ++i) {
|
for (var i = 0; i < records.length; ++i) {
|
||||||
var sanitizedName = records[i].name.replaceAll(new RegExp(r'\W'), '');
|
var sanitizedName = records[i].name.replaceAll(whitespacePattern, '');
|
||||||
localNames[i + 1] = '$sanitizedName$i';
|
localNames[i + 1] = '$sanitizedName$i';
|
||||||
}
|
}
|
||||||
return localNames;
|
return localNames;
|
||||||
|
@ -85,17 +92,21 @@ class _CodegenState {
|
||||||
|
|
||||||
void _writeToBuf(StringBuffer buf) {
|
void _writeToBuf(StringBuffer buf) {
|
||||||
buf.write('''
|
buf.write('''
|
||||||
class $_typeName extends $_BASE_CLASS {
|
class $_changeDetectorTypeName extends $_BASE_CLASS {
|
||||||
final dynamic $_DISPATCHER_ACCESSOR;
|
final dynamic $_DISPATCHER_ACCESSOR;
|
||||||
final $_GEN_PREFIX.PipeRegistry $_PIPE_REGISTRY_ACCESSOR;
|
final $_GEN_PREFIX.PipeRegistry $_PIPE_REGISTRY_ACCESSOR;
|
||||||
final $_GEN_PREFIX.List<$_GEN_PREFIX.ProtoRecord> $_PROTOS_ACCESSOR;
|
final $_GEN_PREFIX.List<$_GEN_PREFIX.ProtoRecord> $_PROTOS_ACCESSOR;
|
||||||
final $_GEN_PREFIX.List<$_GEN_PREFIX.DirectiveRecord>
|
final $_GEN_PREFIX.List<$_GEN_PREFIX.DirectiveRecord>
|
||||||
$_DIRECTIVES_ACCESSOR;
|
$_DIRECTIVES_ACCESSOR;
|
||||||
dynamic $_LOCALS_ACCESSOR = null;
|
dynamic $_LOCALS_ACCESSOR = null;
|
||||||
${_allFields().map(
|
${_allFields().map((f) {
|
||||||
(f) => 'dynamic $f = $_UTIL.uninitialized();').join('')}
|
if (f == _CONTEXT_ACCESSOR) {
|
||||||
|
return '$_contextTypeName $f = null;';
|
||||||
|
}
|
||||||
|
return 'dynamic $f = $_UTIL.uninitialized();';
|
||||||
|
}).join('')}
|
||||||
|
|
||||||
$_typeName(
|
$_changeDetectorTypeName(
|
||||||
this.$_DISPATCHER_ACCESSOR,
|
this.$_DISPATCHER_ACCESSOR,
|
||||||
this.$_PIPE_REGISTRY_ACCESSOR,
|
this.$_PIPE_REGISTRY_ACCESSOR,
|
||||||
this.$_PROTOS_ACCESSOR,
|
this.$_PROTOS_ACCESSOR,
|
||||||
|
@ -116,7 +127,7 @@ class _CodegenState {
|
||||||
${_getCallOnAllChangesDoneBody()}
|
${_getCallOnAllChangesDoneBody()}
|
||||||
}
|
}
|
||||||
|
|
||||||
void hydrate(context, locals, directives) {
|
void hydrate($_contextTypeName context, locals, directives) {
|
||||||
$_MODE_ACCESSOR = '$_changeDetectionMode';
|
$_MODE_ACCESSOR = '$_changeDetectionMode';
|
||||||
$_CONTEXT_ACCESSOR = context;
|
$_CONTEXT_ACCESSOR = context;
|
||||||
$_LOCALS_ACCESSOR = locals;
|
$_LOCALS_ACCESSOR = locals;
|
||||||
|
@ -126,19 +137,22 @@ class _CodegenState {
|
||||||
|
|
||||||
void dehydrate() {
|
void dehydrate() {
|
||||||
${_genPipeOnDestroy()}
|
${_genPipeOnDestroy()}
|
||||||
${_allFields().map((f) => '$f = $_UTIL.uninitialized();').join('')}
|
${_allFields().map((f) {
|
||||||
|
return f == _CONTEXT_ACCESSOR
|
||||||
|
? '$f = null;'
|
||||||
|
: '$f = $_UTIL.uninitialized();';
|
||||||
|
}).join('')}
|
||||||
$_LOCALS_ACCESSOR = null;
|
$_LOCALS_ACCESSOR = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrated() => !$_IDENTICAL_CHECK_FN(
|
hydrated() => $_CONTEXT_ACCESSOR == null;
|
||||||
$_CONTEXT_ACCESSOR, $_UTIL.uninitialized());
|
|
||||||
|
|
||||||
static $_GEN_PREFIX.ProtoChangeDetector
|
static $_GEN_PREFIX.ProtoChangeDetector
|
||||||
$PROTO_CHANGE_DETECTOR_FACTORY_METHOD(
|
$PROTO_CHANGE_DETECTOR_FACTORY_METHOD(
|
||||||
$_GEN_PREFIX.PipeRegistry registry,
|
$_GEN_PREFIX.PipeRegistry registry,
|
||||||
$_GEN_PREFIX.ChangeDetectorDefinition def) {
|
$_GEN_PREFIX.ChangeDetectorDefinition def) {
|
||||||
return new $_GEN_PREFIX.PregenProtoChangeDetector(
|
return new $_GEN_PREFIX.PregenProtoChangeDetector(
|
||||||
(a, b, c, d) => new $_typeName(a, b, c, d),
|
(a, b, c, d) => new $_changeDetectorTypeName(a, b, c, d),
|
||||||
registry, def);
|
registry, def);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ Future<String> processTemplates(AssetReader reader, AssetId entryPoint,
|
||||||
var defs = getChangeDetectorDefinitions(viewDefEntry.hostMetadata,
|
var defs = getChangeDetectorDefinitions(viewDefEntry.hostMetadata,
|
||||||
result.protoView, viewDefEntry.viewDef.directives);
|
result.protoView, viewDefEntry.viewDef.directives);
|
||||||
for (var i = 0; i < defs.length; ++i) {
|
for (var i = 0; i < defs.length; ++i) {
|
||||||
changeDetectorClasses.generate(
|
changeDetectorClasses.generate('${rType.typeName}',
|
||||||
'_${rType.typeName}_ChangeDetector$i', defs[i]);
|
'_${rType.typeName}_ChangeDetector$i', defs[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ void main(List<String> args) {
|
||||||
var allDefs = getAllDefinitions('propName');
|
var allDefs = getAllDefinitions('propName');
|
||||||
for (var i = 0; i < allDefs.length; ++i) {
|
for (var i = 0; i < allDefs.length; ++i) {
|
||||||
var className = 'ChangeDetector${i}';
|
var className = 'ChangeDetector${i}';
|
||||||
codegen.generate(className, allDefs[i]);
|
codegen.generate('dynamic', className, allDefs[i]);
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
buf.write(',');
|
buf.write(',');
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,7 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||||
final _gen.List<_gen.ProtoRecord> _protos;
|
final _gen.List<_gen.ProtoRecord> _protos;
|
||||||
final _gen.List<_gen.DirectiveRecord> _directiveRecords;
|
final _gen.List<_gen.DirectiveRecord> _directiveRecords;
|
||||||
dynamic _locals = null;
|
dynamic _locals = null;
|
||||||
dynamic _context = _gen.ChangeDetectionUtil.uninitialized();
|
MyComponent _context = null;
|
||||||
|
|
||||||
_MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry,
|
_MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry,
|
||||||
this._protos, this._directiveRecords)
|
this._protos, this._directiveRecords)
|
||||||
|
@ -45,19 +45,18 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
|
||||||
|
|
||||||
void callOnAllChangesDone() {}
|
void callOnAllChangesDone() {}
|
||||||
|
|
||||||
void hydrate(context, locals, directives) {
|
void hydrate(MyComponent context, locals, directives) {
|
||||||
mode = 'ALWAYS_CHECK';
|
mode = 'ALWAYS_CHECK';
|
||||||
_context = context;
|
_context = context;
|
||||||
_locals = locals;
|
_locals = locals;
|
||||||
}
|
}
|
||||||
|
|
||||||
void dehydrate() {
|
void dehydrate() {
|
||||||
_context = _gen.ChangeDetectionUtil.uninitialized();
|
_context = null;
|
||||||
_locals = null;
|
_locals = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
hydrated() =>
|
hydrated() => _context == null;
|
||||||
!_gen.looseIdentical(_context, _gen.ChangeDetectionUtil.uninitialized());
|
|
||||||
|
|
||||||
static _gen.ProtoChangeDetector newProtoChangeDetector(
|
static _gen.ProtoChangeDetector newProtoChangeDetector(
|
||||||
_gen.PipeRegistry registry, _gen.ChangeDetectorDefinition def) {
|
_gen.PipeRegistry registry, _gen.ChangeDetectorDefinition def) {
|
||||||
|
|
Loading…
Reference in New Issue