feat(ChangeDetector): Add support for short-circuiting
This commit is contained in:
@ -14,6 +14,7 @@ import 'package:angular2/src/core/change_detection/binding_record.dart';
|
||||
import 'package:angular2/src/core/change_detection/codegen_facade.dart'
|
||||
show codify;
|
||||
import 'package:angular2/src/core/facade/exceptions.dart' show BaseException;
|
||||
import 'package:angular2/src/core/facade/collection.dart' show ListWrapper;
|
||||
|
||||
/// Responsible for generating change detector classes for Angular 2.
|
||||
///
|
||||
@ -90,6 +91,7 @@ class _CodegenState {
|
||||
final CodegenNameUtil _names;
|
||||
final ChangeDetectorGenConfig _genConfig;
|
||||
final List<BindingTarget> _propertyBindingTargets;
|
||||
final List<int> _endOfBlockIdxs = [];
|
||||
|
||||
String get _changeDetectionStrategyAsCode => _changeDetectionStrategy == null
|
||||
? 'null'
|
||||
@ -156,7 +158,7 @@ class _CodegenState {
|
||||
var $_IS_CHANGED_LOCAL = false;
|
||||
var $_CHANGES_LOCAL = null;
|
||||
|
||||
${_records.map(_genRecord).join('')}
|
||||
${_genAllRecords()}
|
||||
}
|
||||
|
||||
${_maybeGenHandleEventInternal()}
|
||||
@ -186,6 +188,15 @@ class _CodegenState {
|
||||
''');
|
||||
}
|
||||
|
||||
String _genAllRecords() {
|
||||
_endOfBlockIdxs.clear();
|
||||
List<String> res = [];
|
||||
for (int i = 0; i < _records.length; i++) {
|
||||
res.add(_genRecord(_records[i], i));
|
||||
}
|
||||
return res.join('');
|
||||
}
|
||||
|
||||
String _genPropertyBindingTargets() {
|
||||
var targets = _logic.genPropertyBindingTargets(
|
||||
_propertyBindingTargets, this._genConfig.genDebugInfo);
|
||||
@ -215,10 +226,29 @@ class _CodegenState {
|
||||
}
|
||||
|
||||
String _genEventBinding(EventBinding eb) {
|
||||
var recs = eb.records.map((r) => _genEventBindingEval(eb, r)).join("\n");
|
||||
List<String> codes = [];
|
||||
_endOfBlockIdxs.clear();
|
||||
|
||||
ListWrapper.forEachWithIndex(eb.records, (r, i) {
|
||||
var code;
|
||||
var r = eb.records[i];
|
||||
|
||||
if (r.isConditionalSkipRecord()) {
|
||||
code = _genConditionalSkip(r, _names.getEventLocalName(eb, i));
|
||||
} else if (r.isUnconditionalSkipRecord()) {
|
||||
code = _genUnconditionalSkip(r);
|
||||
} else {
|
||||
code = _genEventBindingEval(eb, r);
|
||||
}
|
||||
|
||||
code += this._genEndOfSkipBlock(i);
|
||||
|
||||
codes.add(code);
|
||||
});
|
||||
|
||||
return '''
|
||||
if (eventName == "${eb.eventName}" && elIndex == ${eb.elIndex}) {
|
||||
${recs}
|
||||
${codes.join("\n")}
|
||||
}''';
|
||||
}
|
||||
|
||||
@ -315,20 +345,53 @@ class _CodegenState {
|
||||
return 'var ${declareNames.join(', ')};';
|
||||
}
|
||||
|
||||
String _genRecord(ProtoRecord r) {
|
||||
var rec = null;
|
||||
String _genRecord(ProtoRecord r, int index) {
|
||||
var code = null;
|
||||
if (r.isLifeCycleRecord()) {
|
||||
rec = _genDirectiveLifecycle(r);
|
||||
code = _genDirectiveLifecycle(r);
|
||||
} else if (r.isPipeRecord()) {
|
||||
rec = _genPipeCheck(r);
|
||||
code = _genPipeCheck(r);
|
||||
} else if (r.isConditionalSkipRecord()) {
|
||||
code = _genConditionalSkip(r, _names.getLocalName(r.contextIndex));
|
||||
} else if (r.isUnconditionalSkipRecord()) {
|
||||
code = _genUnconditionalSkip(r);
|
||||
} else {
|
||||
rec = _genReferenceCheck(r);
|
||||
code = _genReferenceCheck(r);
|
||||
}
|
||||
return '''
|
||||
|
||||
code = '''
|
||||
${this._maybeFirstInBinding(r)}
|
||||
${rec}
|
||||
${code}
|
||||
${this._maybeGenLastInDirective(r)}
|
||||
${this._genEndOfSkipBlock(index)}
|
||||
''';
|
||||
|
||||
return code;
|
||||
}
|
||||
|
||||
String _genConditionalSkip(ProtoRecord r, String condition) {
|
||||
var maybeNegate = r.mode == RecordType.SkipRecordsIf ? '!' : '';
|
||||
_endOfBlockIdxs.add(r.fixedArgs[0] - 1);
|
||||
|
||||
return 'if ($maybeNegate$condition) {';
|
||||
}
|
||||
|
||||
String _genUnconditionalSkip(ProtoRecord r) {
|
||||
_endOfBlockIdxs.removeLast();
|
||||
_endOfBlockIdxs.add(r.fixedArgs[0] - 1);
|
||||
return '} else {';
|
||||
}
|
||||
|
||||
String _genEndOfSkipBlock(int protoIndex) {
|
||||
if (!ListWrapper.isEmpty(this._endOfBlockIdxs)) {
|
||||
var endOfBlock = ListWrapper.last(this._endOfBlockIdxs);
|
||||
if (protoIndex == endOfBlock) {
|
||||
this._endOfBlockIdxs.removeLast();
|
||||
return '}';
|
||||
}
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
String _genDirectiveLifecycle(ProtoRecord r) {
|
||||
|
Reference in New Issue
Block a user