feat(pipes): add support for pure pipes

By default, pipes are pure. This means that an instance of a pipe will be reused and the pipe will be called only when its arguments change.

BREAKING CHANGE

Before:

@Pipe({name: 'date'}) class DatePipe {} defines an impure pipe.

After:

@Pipe({name: 'date'}) class DatePipe {} defines a pure pipe.
@Pipe({name: 'date', pure: false}) class DatePipe {} defines an impure pipe.

Closes #3966
This commit is contained in:
vsavkin
2015-09-08 09:17:58 -07:00
committed by Victor Savkin
parent 5a59e8be82
commit a8bdb693b9
16 changed files with 167 additions and 74 deletions

View File

@ -335,13 +335,20 @@ class _CodegenState {
var pipe = _names.getPipeName(r.selfIndex);
var pipeType = r.name;
var read = '''
var init = '''
if ($_IDENTICAL_CHECK_FN($pipe, $_UTIL.uninitialized)) {
$pipe = ${_names.getPipesAccessorName()}.get('$pipeType');
}
$newValue = $pipe.transform($context, [$argString]);
''';
var read = '''
$newValue = $pipe.pipe.transform($context, [$argString]);
''';
var contexOrArgCheck = r.args.map((a) => _names.getChangeName(a)).toList();
contexOrArgCheck.add(_names.getChangeName(r.contextIndex));
var condition = '''!${pipe}.pure || (${contexOrArgCheck.join(" || ")})''';
var check = '''
if ($_NOT_IDENTICAL_CHECK_FN($oldValue, $newValue)) {
$newValue = $_UTIL.unwrapValue($newValue);
@ -352,7 +359,13 @@ class _CodegenState {
}
''';
return r.shouldBeChecked() ? "${read}${check}" : read;
var genCode = r.shouldBeChecked() ? '''${read}${check}''' : read;
if (r.isUsedByOtherRecord()) {
return '''${init} if (${condition}) { ${genCode} } else { ${newValue} = ${oldValue}; }''';
} else {
return '''${init} if (${condition}) { ${genCode} }''';
}
}
String _genReferenceCheck(ProtoRecord r) {