From 5b29121af11b874ae0c0446d47b5fd6853978e13 Mon Sep 17 00:00:00 2001 From: Victor Date: Fri, 21 Mar 2014 19:23:01 +0100 Subject: [PATCH] fix(filters): pass filters to all evals closes #755 Ad support for '"s" + ("m"|filter) + "e"' --- bin/parser_generator_for_spec.dart | 1 + lib/core/parser/eval.dart | 16 ++++++++-------- lib/core/parser/eval_calls.dart | 12 ++++++------ lib/core/parser/utils.dart | 5 +++-- test/core/parser/parser_spec.dart | 1 + 5 files changed, 19 insertions(+), 16 deletions(-) diff --git a/bin/parser_generator_for_spec.dart b/bin/parser_generator_for_spec.dart index 4d12e2164..16904545c 100644 --- a/bin/parser_generator_for_spec.dart +++ b/bin/parser_generator_for_spec.dart @@ -175,6 +175,7 @@ main(arguments) { 'add(a,b)', 'notAProperty', "'Foo'|uppercase", + "'f' + ('o'|uppercase) + 'o'", "1|increment:2", "'abcd'|substring:1:offset", "'abcd'|substring:1:3|uppercase", diff --git a/lib/core/parser/eval.dart b/lib/core/parser/eval.dart index 3ca42723c..eb33bff9e 100644 --- a/lib/core/parser/eval.dart +++ b/lib/core/parser/eval.dart @@ -39,26 +39,26 @@ class Conditional extends syntax.Conditional { Conditional(syntax.Expression condition, syntax.Expression yes, syntax.Expression no) : super(condition, yes, no); - eval(scope, [FilterMap filters]) => toBool(condition.eval(scope)) - ? yes.eval(scope) - : no.eval(scope); + eval(scope, [FilterMap filters]) => toBool(condition.eval(scope, filters)) + ? yes.eval(scope, filters) + : no.eval(scope, filters); } class PrefixNot extends syntax.Prefix { PrefixNot(syntax.Expression expression) : super('!', expression); - eval(scope, [FilterMap filters]) => !toBool(expression.eval(scope)); + eval(scope, [FilterMap filters]) => !toBool(expression.eval(scope, filters)); } class Binary extends syntax.Binary { Binary(String operation, syntax.Expression left, syntax.Expression right): super(operation, left, right); eval(scope, [FilterMap filters]) { - var left = this.left.eval(scope); + var left = this.left.eval(scope, filters); switch (operation) { - case '&&': return toBool(left) && toBool(this.right.eval(scope)); - case '||': return toBool(left) || toBool(this.right.eval(scope)); + case '&&': return toBool(left) && toBool(this.right.eval(scope, filters)); + case '||': return toBool(left) || toBool(this.right.eval(scope, filters)); } - var right = this.right.eval(scope); + var right = this.right.eval(scope, filters); // Null check for the operations. if (left == null || right == null) { diff --git a/lib/core/parser/eval_calls.dart b/lib/core/parser/eval_calls.dart index 12d2f82bf..c55b6f21e 100644 --- a/lib/core/parser/eval_calls.dart +++ b/lib/core/parser/eval_calls.dart @@ -12,7 +12,7 @@ class CallScope extends syntax.CallScope with CallReflective { CallScope(name, arguments) : super(name, arguments), symbol = newSymbol(name); - eval(scope, [FilterMap filters]) => _eval(scope, scope); + eval(scope, [FilterMap filters]) => _eval(scope, scope, filters); } class CallMember extends syntax.CallMember with CallReflective { @@ -20,7 +20,8 @@ class CallMember extends syntax.CallMember with CallReflective { CallMember(object, name, arguments) : super(object, name, arguments), symbol = newSymbol(name); - eval(scope, [FilterMap filters]) => _eval(scope, object.eval(scope, filters)); + eval(scope, [FilterMap filters]) => _eval(scope, object.eval(scope, filters), + filters); } class CallScopeFast0 extends syntax.CallScope with CallFast { @@ -106,13 +107,12 @@ abstract class CallReflective { Symbol get symbol; syntax.CallArguments get arguments; - // TODO(kasperl): This seems broken -- it needs filters. - _eval(scope, holder) { - List positionals = evalList(scope, arguments.positionals); + _eval(scope, holder, FilterMap filters) { + List positionals = evalList(scope, arguments.positionals, filters); if (arguments.named.isNotEmpty) { var named = new Map(); arguments.named.forEach((String name, value) { - named[new Symbol(name)] = value.eval(scope); + named[new Symbol(name)] = value.eval(scope, filters); }); if (holder is Map) { var fn = ensureFunctionFromMap(holder, name); diff --git a/lib/core/parser/utils.dart b/lib/core/parser/utils.dart index 7943e7d4f..2c6e9a63e 100644 --- a/lib/core/parser/utils.dart +++ b/lib/core/parser/utils.dart @@ -21,8 +21,9 @@ class EvalError { /// Evaluate the [list] in context of the [scope]. List evalList(scope, List list, [FilterMap filters]) { - int length = list.length; - for (int cacheLength = _evalListCache.length; cacheLength <= length; cacheLength++) { + final length = list.length; + int cacheLength = _evalListCache.length; + for (; cacheLength <= length; cacheLength++) { _evalListCache.add(new List(cacheLength)); } List result = _evalListCache[length]; diff --git a/test/core/parser/parser_spec.dart b/test/core/parser/parser_spec.dart index 4d6709c62..29521ecba 100644 --- a/test/core/parser/parser_spec.dart +++ b/test/core/parser/parser_spec.dart @@ -1102,6 +1102,7 @@ main() { describe('filters', () { it('should call a filter', () { expect(eval("'Foo'|uppercase", filters)).toEqual("FOO"); + expect(eval("'f' + ('o'|uppercase) + 'o'", filters)).toEqual("fOo"); expect(eval("'fOo'|uppercase|lowercase", filters)).toEqual("foo"); });