@@ -11,7 +11,7 @@ typedef void ChangeLog(String expression, current, previous);
11
11
12
12
/**
13
13
* Extend this class if you wish to pretend to be a function, but you don't know
14
- * number of arguments with which the function will get called.
14
+ * number of arguments with which the function will get called with .
15
15
*/
16
16
abstract class FunctionApply {
17
17
// dartbug.com/16401
@@ -183,11 +183,13 @@ class WatchGroup implements _EvalWatchList, _WatchGroupList {
183
183
* - [fn] function to evaluate.
184
184
* - [argsAST] list of [AST] es which represent arguments passed to function.
185
185
* - [expression] normalized expression used for caching.
186
+ * - [isPure] A pure function is one which holds no internal state. This implies that the
187
+ * function is idempotent.
186
188
*/
187
189
_EvalWatchRecord addFunctionWatch (/* dartbug.com/16401 Function */ fn, List <AST > argsAST,
188
190
Map <Symbol , AST > namedArgsAST,
189
- String expression) =>
190
- _addEvalWatch (null , fn, null , argsAST, namedArgsAST, expression);
191
+ String expression, bool isPure ) =>
192
+ _addEvalWatch (null , fn, null , argsAST, namedArgsAST, expression, isPure );
191
193
192
194
/**
193
195
* Watch a method [name] ed represented by an [expression] .
@@ -200,18 +202,18 @@ class WatchGroup implements _EvalWatchList, _WatchGroupList {
200
202
_EvalWatchRecord addMethodWatch (AST lhs, String name, List <AST > argsAST,
201
203
Map <Symbol , AST > namedArgsAST,
202
204
String expression) =>
203
- _addEvalWatch (lhs, null , name, argsAST, namedArgsAST, expression);
205
+ _addEvalWatch (lhs, null , name, argsAST, namedArgsAST, expression, false );
204
206
205
207
206
208
207
209
_EvalWatchRecord _addEvalWatch (AST lhsAST, /* dartbug.com/16401 Function */ fn, String name,
208
210
List <AST > argsAST,
209
211
Map <Symbol , AST > namedArgsAST,
210
- String expression) {
212
+ String expression, bool isPure ) {
211
213
_InvokeHandler invokeHandler = new _InvokeHandler (this , expression);
212
214
var evalWatchRecord = new _EvalWatchRecord (
213
215
_rootGroup._fieldGetterFactory, this , invokeHandler, fn, name,
214
- argsAST.length);
216
+ argsAST.length, isPure );
215
217
invokeHandler.watchRecord = evalWatchRecord;
216
218
217
219
if (lhsAST != null ) {
@@ -701,15 +703,17 @@ class _InvokeHandler extends _Handler implements _ArgHandlerList {
701
703
702
704
703
705
class _EvalWatchRecord implements WatchRecord <_Handler >, Record <_Handler > {
704
- static const int _MODE_DELETED_ = - 1 ;
705
- static const int _MODE_MARKER_ = 0 ;
706
- static const int _MODE_FUNCTION_ = 1 ;
707
- static const int _MODE_FUNCTION_APPLY_ = 2 ;
708
- static const int _MODE_NULL_ = 3 ;
709
- static const int _MODE_FIELD_CLOSURE_ = 4 ;
710
- static const int _MODE_MAP_CLOSURE_ = 5 ;
711
- static const int _MODE_METHOD_ = 6 ;
712
- static const int _MODE_METHOD_INVOKE_ = 7 ;
706
+ static const int _MODE_INVALID_ = - 2 ;
707
+ static const int _MODE_DELETED_ = - 1 ;
708
+ static const int _MODE_MARKER_ = 0 ;
709
+ static const int _MODE_PURE_FUNCTION_ = 1 ;
710
+ static const int _MODE_FUNCTION_ = 2 ;
711
+ static const int _MODE_PURE_FUNCTION_APPLY_ = 3 ;
712
+ static const int _MODE_NULL_ = 4 ;
713
+ static const int _MODE_FIELD_CLOSURE_ = 5 ;
714
+ static const int _MODE_MAP_CLOSURE_ = 6 ;
715
+ static const int _MODE_METHOD_ = 7 ;
716
+ static const int _MODE_METHOD_INVOKE_ = 8 ;
713
717
WatchGroup watchGrp;
714
718
final _Handler handler;
715
719
final List args;
@@ -724,13 +728,13 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
724
728
_EvalWatchRecord _prevEvalWatch, _nextEvalWatch;
725
729
726
730
_EvalWatchRecord (this ._fieldGetterFactory, this .watchGrp, this .handler,
727
- this .fn, this .name, int arity)
731
+ this .fn, this .name, int arity, bool pure )
728
732
: args = new List (arity)
729
733
{
730
734
if (fn is FunctionApply ) {
731
- mode = _MODE_FUNCTION_APPLY_ ;
735
+ mode = pure ? _MODE_PURE_FUNCTION_APPLY_ : _MODE_INVALID_ ;
732
736
} else if (fn is Function ) {
733
- mode = _MODE_FUNCTION_ ;
737
+ mode = pure ? _MODE_PURE_FUNCTION_ : _MODE_FUNCTION_ ;
734
738
} else {
735
739
mode = _MODE_NULL_ ;
736
740
}
@@ -763,7 +767,8 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
763
767
assert (mode != _MODE_DELETED_ );
764
768
assert (mode != _MODE_MARKER_ );
765
769
assert (mode != _MODE_FUNCTION_ );
766
- assert (mode != _MODE_FUNCTION_APPLY_ );
770
+ assert (mode != _MODE_PURE_FUNCTION_ );
771
+ assert (mode != _MODE_PURE_FUNCTION_APPLY_ );
767
772
_object = value;
768
773
769
774
if (value == null ) {
@@ -789,12 +794,16 @@ class _EvalWatchRecord implements WatchRecord<_Handler>, Record<_Handler> {
789
794
case _MODE_MARKER_ :
790
795
case _MODE_NULL_ :
791
796
return false ;
792
- case _MODE_FUNCTION_ :
797
+ case _MODE_PURE_FUNCTION_ :
793
798
if (! dirtyArgs) return false ;
794
799
value = Function .apply (fn, args, namedArgs);
795
800
dirtyArgs = false ;
796
801
break ;
797
- case _MODE_FUNCTION_APPLY_ :
802
+ case _MODE_FUNCTION_ :
803
+ value = Function .apply (fn, args, namedArgs);
804
+ dirtyArgs = false ;
805
+ break ;
806
+ case _MODE_PURE_FUNCTION_APPLY_ :
798
807
if (! dirtyArgs) return false ;
799
808
value = (fn as FunctionApply ).apply (args);
800
809
dirtyArgs = false ;
0 commit comments