feat(dart/transform): Add onInit and onCheck hooks in Dart

Implement `onInit` and `onCheck` hooks in pre-generated Dart change
detectors. This mirrors the changes made to the JIT change detector in
c39c8ebcd0.
This commit is contained in:
Tim Blasi 2015-06-09 15:39:48 -07:00
parent 633cf63682
commit 17c6d6a92d
3 changed files with 51 additions and 18 deletions

View File

@ -236,7 +236,7 @@ export class ChangeDetectorJITGenerator {
} else { } else {
rec = this._genReferenceCheck(r); rec = this._genReferenceCheck(r);
} }
return `${rec}${this._genLastInDirective(r)}`; return `${rec}${this._maybeGenLastInDirective(r)}`;
} }
_genDirectiveLifecycle(r: ProtoRecord) { _genDirectiveLifecycle(r: ProtoRecord) {
@ -419,7 +419,7 @@ export class ChangeDetectorJITGenerator {
`; `;
} }
_genLastInDirective(r: ProtoRecord): string { _maybeGenLastInDirective(r: ProtoRecord): string {
if (!r.lastInDirective) return ""; if (!r.lastInDirective) return "";
return ` return `
${CHANGES_LOCAL} = null; ${CHANGES_LOCAL} = null;

View File

@ -7,6 +7,7 @@ import 'package:angular2/src/change_detection/directive_record.dart';
import 'package:angular2/src/change_detection/interfaces.dart'; import 'package:angular2/src/change_detection/interfaces.dart';
import 'package:angular2/src/change_detection/proto_change_detector.dart'; import 'package:angular2/src/change_detection/proto_change_detector.dart';
import 'package:angular2/src/change_detection/proto_record.dart'; import 'package:angular2/src/change_detection/proto_record.dart';
import 'package:angular2/src/facade/lang.dart' show BaseException;
/// Responsible for generating change detector classes for Angular 2. /// Responsible for generating change detector classes for Angular 2.
/// ///
@ -99,6 +100,7 @@ class _CodegenState {
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;
dynamic $_ALREADY_CHECKED_ACCESSOR = false;
${_allFields().map((f) { ${_allFields().map((f) {
if (f == _CONTEXT_ACCESSOR) { if (f == _CONTEXT_ACCESSOR) {
return '$_contextTypeName $f = null;'; return '$_contextTypeName $f = null;';
@ -124,6 +126,8 @@ class _CodegenState {
context = $_CONTEXT_ACCESSOR; context = $_CONTEXT_ACCESSOR;
${_records.map(_genRecord).join('')} ${_records.map(_genRecord).join('')}
$_ALREADY_CHECKED_ACCESSOR = true;
} }
void callOnAllChangesDone() { void callOnAllChangesDone() {
@ -136,6 +140,7 @@ class _CodegenState {
$_LOCALS_ACCESSOR = locals; $_LOCALS_ACCESSOR = locals;
${_genHydrateDirectives()} ${_genHydrateDirectives()}
${_genHydrateDetectors()} ${_genHydrateDetectors()}
$_ALREADY_CHECKED_ACCESSOR = false;
} }
void dehydrate() { void dehydrate() {
@ -234,10 +239,26 @@ class _CodegenState {
_changeNames.map((name) => 'var $name = false;').join(''); _changeNames.map((name) => 'var $name = false;').join('');
String _genRecord(ProtoRecord r) { String _genRecord(ProtoRecord r) {
if (r.mode == RECORD_TYPE_PIPE || r.mode == RECORD_TYPE_BINDING_PIPE) { var rec = null;
return _genPipeCheck(r); if (r.isLifeCycleRecord()) {
rec = _genDirectiveLifecycle(r);
} else if (r.isPipeRecord()) {
rec = _genPipeCheck(r);
} else { } else {
return _genReferenceCheck(r); rec = _genReferenceCheck(r);
}
return '$rec${_maybeGenLastInDirective(r)}';
}
String _genDirectiveLifecycle(ProtoRecord r) {
if (r.name == 'onCheck') {
return _genOnCheck(r);
} else if (r.name == 'onInit') {
return _genOnInit(r);
} else if (r.name == 'onChange') {
return _genOnChange(r);
} else {
throw new BaseException("Unknown lifecycle event '${r.name}'");
} }
} }
@ -269,7 +290,6 @@ class _CodegenState {
${_genAddToChanges(r)} ${_genAddToChanges(r)}
$oldValue = $newValue; $oldValue = $newValue;
} }
${_genLastInDirective(r)}
'''; ''';
} }
@ -287,7 +307,6 @@ class _CodegenState {
${_genAddToChanges(r)} ${_genAddToChanges(r)}
$oldValue = $newValue; $oldValue = $newValue;
} }
${_genLastInDirective(r)}
'''; ''';
if (r.isPureFunction()) { if (r.isPureFunction()) {
// Add an "if changed guard" // Add an "if changed guard"
@ -414,24 +433,32 @@ class _CodegenState {
'''; ''';
} }
String _genLastInDirective(ProtoRecord r) { String _maybeGenLastInDirective(ProtoRecord r) {
if (!r.lastInDirective) return '';
return ''' return '''
${_genNotifyOnChanges(r)} $_CHANGES_LOCAL = null;
${_genNotifyOnPushDetectors(r)} ${_genNotifyOnPushDetectors(r)}
$_IS_CHANGED_LOCAL = false; $_IS_CHANGED_LOCAL = false;
'''; ''';
} }
String _genNotifyOnChanges(ProtoRecord r) { String _genOnCheck(ProtoRecord r) {
var br = r.bindingRecord; var br = r.bindingRecord;
if (!r.lastInDirective || !br.callOnChange()) return ''; return 'if (!throwOnChange) '
return ''' '${_genGetDirective(br.directiveRecord.directiveIndex)}.onCheck();';
if($_CHANGES_LOCAL) {
${_genGetDirective(br.directiveRecord.directiveIndex)}
.onChange($_CHANGES_LOCAL);
$_CHANGES_LOCAL = null;
} }
''';
String _genOnInit(ProtoRecord r) {
var br = r.bindingRecord;
return 'if (!throwOnChange && !$_ALREADY_CHECKED_ACCESSOR) '
'${_genGetDirective(br.directiveRecord.directiveIndex)}.onInit();';
}
String _genOnChange(ProtoRecord r) {
var br = r.bindingRecord;
return 'if (!throwOnChange && $_CHANGES_LOCAL != null) '
'${_genGetDirective(br.directiveRecord.directiveIndex)}'
'.onChange($_CHANGES_LOCAL);';
} }
String _genNotifyOnPushDetectors(ProtoRecord r) { String _genNotifyOnPushDetectors(ProtoRecord r) {
@ -447,6 +474,7 @@ class _CodegenState {
const PROTO_CHANGE_DETECTOR_FACTORY_METHOD = 'newProtoChangeDetector'; const PROTO_CHANGE_DETECTOR_FACTORY_METHOD = 'newProtoChangeDetector';
const _ALREADY_CHECKED_ACCESSOR = '_alreadyChecked';
const _BASE_CLASS = '$_GEN_PREFIX.AbstractChangeDetector'; const _BASE_CLASS = '$_GEN_PREFIX.AbstractChangeDetector';
const _CHANGES_LOCAL = 'changes'; const _CHANGES_LOCAL = 'changes';
const _CONTEXT_ACCESSOR = '_context'; const _CONTEXT_ACCESSOR = '_context';

View File

@ -27,6 +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 _alreadyChecked = false;
MyComponent _context = null; MyComponent _context = null;
_MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry, _MyComponent_ChangeDetector0(this._dispatcher, this._pipeRegistry,
@ -44,6 +45,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
var changes = null; var changes = null;
context = _context; context = _context;
_alreadyChecked = true;
} }
void callOnAllChangesDone() {} void callOnAllChangesDone() {}
@ -52,6 +55,8 @@ class _MyComponent_ChangeDetector0 extends _gen.AbstractChangeDetector {
mode = 'ALWAYS_CHECK'; mode = 'ALWAYS_CHECK';
_context = context; _context = context;
_locals = locals; _locals = locals;
_alreadyChecked = false;
} }
void dehydrate() { void dehydrate() {