Skip to content

Commit 1f3b858

Browse files
committed
refactor(parser): pass FilterMap to expression eval instead of parser constructor
1 parent 5d544c0 commit 1f3b858

15 files changed

+127
-68
lines changed

bin/parser_generator_for_spec.dart

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ main(arguments) {
224224
"n",
225225
"1|nonexistent",
226226
"publicField",
227-
"_privateField"
227+
"_privateField",
228+
"'World'|hello"
228229
]);
229230
}

lib/core/parser/dynamic_parser.dart

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import 'package:angular/core/module.dart' show FilterMap, NgInjectableService;
55
import 'package:angular/core/parser/parser.dart';
66
import 'package:angular/core/parser/lexer.dart';
77
import 'package:angular/core/parser/dynamic_parser_impl.dart';
8+
import 'package:angular/core/parser/syntax.dart' show defaultFilterMap;
89

910
import 'package:angular/core/parser/eval.dart';
1011
import 'package:angular/core/parser/utils.dart' show EvalError;
@@ -45,9 +46,9 @@ class DynamicExpression extends Expression {
4546
accept(Visitor visitor) => _expression.accept(visitor);
4647
toString() => _expression.toString();
4748

48-
eval(scope) {
49+
eval(scope, [FilterMap filters = defaultFilterMap]) {
4950
try {
50-
return _expression.eval(scope);
51+
return _expression.eval(scope, filters);
5152
} on EvalError catch (e, s) {
5253
throw e.unwrap("$this", s);
5354
}
@@ -64,19 +65,17 @@ class DynamicExpression extends Expression {
6465

6566
@NgInjectableService()
6667
class DynamicParserBackend extends ParserBackend {
67-
final FilterMap _filters;
6868
final ClosureMap _closures;
69-
DynamicParserBackend(this._filters, this._closures);
69+
DynamicParserBackend(this._closures);
7070

7171
bool isAssignable(Expression expression)
7272
=> expression.isAssignable;
7373

7474
Expression newFilter(expression, name, arguments) {
75-
Function filter = _filters(name);
7675
List allArguments = new List(arguments.length + 1);
7776
allArguments[0] = expression;
7877
allArguments.setAll(1, arguments);
79-
return new Filter(expression, name, arguments, filter, allArguments);
78+
return new Filter(expression, name, arguments, allArguments);
8079
}
8180

8281
Expression newChain(expressions)

lib/core/parser/eval.dart

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,53 +2,57 @@ library angular.core.parser.eval;
22

33
import 'package:angular/core/parser/syntax.dart' as syntax;
44
import 'package:angular/core/parser/utils.dart';
5+
import 'package:angular/core/module.dart';
6+
import 'package:angular/core/parser/syntax.dart';
57

68
export 'package:angular/core/parser/eval_access.dart';
79
export 'package:angular/core/parser/eval_calls.dart';
810

911
class Chain extends syntax.Chain {
1012
Chain(List<syntax.Expression> expressions) : super(expressions);
11-
eval(scope) {
13+
eval(scope, [FilterMap filters]) {
1214
var result;
1315
for (int i = 0, length = expressions.length; i < length; i++) {
14-
var last = expressions[i].eval(scope);
16+
var last = expressions[i].eval(scope, filters);
1517
if (last != null) result = last;
1618
}
1719
return result;
1820
}
1921
}
2022

2123
class Filter extends syntax.Filter {
22-
final Function function;
2324
final List allArguments;
2425
Filter(syntax.Expression expression, String name, List<syntax.Expression> arguments,
25-
Function this.function, List<syntax.Expression> this.allArguments)
26+
List<syntax.Expression> this.allArguments)
2627
: super(expression, name, arguments);
27-
eval(scope) => Function.apply(function, evalList(scope, allArguments));
28+
29+
eval(scope, [FilterMap filters]) =>
30+
Function.apply(filters(name), evalList(scope, allArguments, filters));
2831
}
2932

3033
class Assign extends syntax.Assign {
3134
Assign(syntax.Expression target, value) : super(target, value);
32-
eval(scope) => target.assign(scope, value.eval(scope));
35+
eval(scope, [FilterMap filters]) =>
36+
target.assign(scope, value.eval(scope, filters));
3337
}
3438

3539
class Conditional extends syntax.Conditional {
3640
Conditional(syntax.Expression condition,
3741
syntax.Expression yes, syntax.Expression no): super(condition, yes, no);
38-
eval(scope) => toBool(condition.eval(scope))
42+
eval(scope, [FilterMap filters]) => toBool(condition.eval(scope))
3943
? yes.eval(scope)
4044
: no.eval(scope);
4145
}
4246

4347
class PrefixNot extends syntax.Prefix {
4448
PrefixNot(syntax.Expression expression) : super('!', expression);
45-
eval(scope) => !toBool(expression.eval(scope));
49+
eval(scope, [FilterMap filters]) => !toBool(expression.eval(scope));
4650
}
4751

4852
class Binary extends syntax.Binary {
4953
Binary(String operation, syntax.Expression left, syntax.Expression right):
5054
super(operation, left, right);
51-
eval(scope) {
55+
eval(scope, [FilterMap filters]) {
5256
var left = this.left.eval(scope);
5357
switch (operation) {
5458
case '&&': return toBool(left) && toBool(this.right.eval(scope));
@@ -77,20 +81,22 @@ class Binary extends syntax.Binary {
7781

7882
class LiteralPrimitive extends syntax.LiteralPrimitive {
7983
LiteralPrimitive(dynamic value) : super(value);
80-
eval(scope) => value;
84+
eval(scope, [FilterMap filters]) => value;
8185
}
8286

8387
class LiteralString extends syntax.LiteralString {
8488
LiteralString(String value) : super(value);
85-
eval(scope) => value;
89+
eval(scope, [FilterMap filters]) => value;
8690
}
8791

8892
class LiteralArray extends syntax.LiteralArray {
8993
LiteralArray(List<syntax.Expression> elements) : super(elements);
90-
eval(scope) => elements.map((e) => e.eval(scope)).toList();
94+
eval(scope, [FilterMap filters]) =>
95+
elements.map((e) => e.eval(scope, filters)).toList();
9196
}
9297

9398
class LiteralObject extends syntax.LiteralObject {
9499
LiteralObject(List<String> keys, List<syntax.Expression>values) : super(keys, values);
95-
eval(scope) => new Map.fromIterables(keys, values.map((e) => e.eval(scope)));
100+
eval(scope, [FilterMap filters]) =>
101+
new Map.fromIterables(keys, values.map((e) => e.eval(scope, filters)));
96102
}

lib/core/parser/eval_access.dart

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,26 +4,28 @@ import 'dart:mirrors';
44
import 'package:angular/core/parser/parser.dart';
55
import 'package:angular/core/parser/syntax.dart' as syntax;
66
import 'package:angular/core/parser/utils.dart';
7+
import 'package:angular/core/module.dart';
78

89
class AccessScope extends syntax.AccessScope with AccessReflective {
910
final Symbol symbol;
1011
AccessScope(String name) : super(name), symbol = new Symbol(name);
11-
eval(scope) => _eval(scope);
12+
eval(scope, [FilterMap filters]) => _eval(scope);
1213
assign(scope, value) => _assign(scope, scope, value);
1314
}
1415

1516
class AccessScopeFast extends syntax.AccessScope with AccessFast {
1617
final Getter getter;
1718
final Setter setter;
1819
AccessScopeFast(String name, this.getter, this.setter) : super(name);
19-
eval(scope) => _eval(scope);
20+
eval(scope, [FilterMap filters]) => _eval(scope);
2021
assign(scope, value) => _assign(scope, scope, value);
2122
}
2223

2324
class AccessMember extends syntax.AccessMember with AccessReflective {
2425
final Symbol symbol;
25-
AccessMember(object, String name) : super(object, name), symbol = new Symbol(name);
26-
eval(scope) => _eval(object.eval(scope));
26+
AccessMember(object, String name)
27+
: super(object, name), symbol = new Symbol(name);
28+
eval(scope, [FilterMap filters]) => _eval(object.eval(scope, filters));
2729
assign(scope, value) => _assign(scope, object.eval(scope), value);
2830
_assignToNonExisting(scope, value) => object.assign(scope, { name: value });
2931
}
@@ -33,14 +35,15 @@ class AccessMemberFast extends syntax.AccessMember with AccessFast {
3335
final Setter setter;
3436
AccessMemberFast(object, String name, this.getter, this.setter)
3537
: super(object, name);
36-
eval(scope) => _eval(object.eval(scope));
38+
eval(scope, [FilterMap filters]) => _eval(object.eval(scope, filters));
3739
assign(scope, value) => _assign(scope, object.eval(scope), value);
3840
_assignToNonExisting(scope, value) => object.assign(scope, { name: value });
3941
}
4042

4143
class AccessKeyed extends syntax.AccessKeyed {
4244
AccessKeyed(object, key) : super(object, key);
43-
eval(scope) => getKeyed(object.eval(scope), key.eval(scope));
45+
eval(scope, [FilterMap filters]) =>
46+
getKeyed(object.eval(scope, filters), key.eval(scope, filters));
4447
assign(scope, value) => setKeyed(object.eval(scope), key.eval(scope), value);
4548
}
4649

lib/core/parser/eval_calls.dart

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,58 +3,59 @@ library angular.core.parser.eval_calls;
33
import 'dart:mirrors';
44
import 'package:angular/core/parser/syntax.dart' as syntax;
55
import 'package:angular/core/parser/utils.dart';
6+
import 'package:angular/core/module.dart';
67

78
class CallScope extends syntax.CallScope with CallReflective {
89
final Symbol symbol;
910
CallScope(name, arguments)
1011
: super(name, arguments)
1112
, symbol = new Symbol(name);
12-
eval(scope) => _eval(scope, scope);
13+
eval(scope, [FilterMap filters]) => _eval(scope, scope);
1314
}
1415

1516
class CallMember extends syntax.CallMember with CallReflective {
1617
final Symbol symbol;
1718
CallMember(object, name, arguments)
1819
: super(object, name, arguments)
1920
, symbol = new Symbol(name);
20-
eval(scope) => _eval(scope, object.eval(scope));
21+
eval(scope, [FilterMap filters]) => _eval(scope, object.eval(scope, filters));
2122
}
2223

2324
class CallScopeFast0 extends syntax.CallScope with CallFast {
2425
final Function function;
2526
CallScopeFast0(name, arguments, this.function) : super(name, arguments);
26-
eval(scope) => _evaluate0(scope);
27+
eval(scope, [FilterMap filters]) => _evaluate0(scope);
2728
}
2829

2930
class CallScopeFast1 extends syntax.CallScope with CallFast {
3031
final Function function;
3132
CallScopeFast1(name, arguments, this.function) : super(name, arguments);
32-
eval(scope) => _evaluate1(scope, arguments[0].eval(scope));
33+
eval(scope, [FilterMap filters]) => _evaluate1(scope, arguments[0].eval(scope, filters));
3334
}
3435

3536
class CallMemberFast0 extends syntax.CallMember with CallFast {
3637
final Function function;
3738
CallMemberFast0(object, name, arguments, this.function)
3839
: super(object, name, arguments);
39-
eval(scope) => _evaluate0(object.eval(scope));
40+
eval(scope, [FilterMap filters]) => _evaluate0(object.eval(scope, filters));
4041
}
4142

4243
class CallMemberFast1 extends syntax.CallMember with CallFast {
4344
final Function function;
4445
CallMemberFast1(object, name, arguments, this.function)
4546
: super(object, name, arguments);
46-
eval(scope) => _evaluate1(object.eval(scope),
47-
arguments[0].eval(scope));
47+
eval(scope, [FilterMap filters]) => _evaluate1(object.eval(scope, filters),
48+
arguments[0].eval(scope, filters));
4849
}
4950

5051
class CallFunction extends syntax.CallFunction {
5152
CallFunction(function, arguments) : super(function, arguments);
52-
eval(scope) {
53-
var function = this.function.eval(scope);
53+
eval(scope, [FilterMap filters]) {
54+
var function = this.function.eval(scope, filters);
5455
if (function is !Function) {
5556
throw new EvalError('${this.function} is not a function');
5657
} else {
57-
return relaxFnApply(function, evalList(scope, arguments));
58+
return relaxFnApply(function, evalList(scope, arguments, filters));
5859
}
5960
}
6061
}

lib/core/parser/static_parser.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
library angular.core.parser.static_parser;
22

3-
import 'package:angular/core/module.dart' show NgInjectableService;
3+
import 'package:angular/core/module.dart' show FilterMap, NgInjectableService;
44
import 'package:angular/core/parser/parser.dart';
55
import 'package:angular/core/parser/utils.dart' show EvalError;
6+
import 'package:angular/core/parser/syntax.dart';
67

78
class StaticParserFunctions {
89
final Map<String, Function> eval;
@@ -41,9 +42,9 @@ class StaticExpression extends Expression {
4142
accept(Visitor visitor) => throw "Cannot visit static expression $this";
4243
toString() => _input;
4344

44-
eval(scope) {
45+
eval(scope, [FilterMap filters = defaultFilterMap]) {
4546
try {
46-
return _eval(scope);
47+
return _eval(scope, filters);
4748
} on EvalError catch (e, s) {
4849
throw e.unwrap("$this", s);
4950
}

lib/core/parser/syntax.dart

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ library angular.core.parser.syntax;
33
import 'package:angular/core/parser/parser.dart' show LocalsWrapper;
44
import 'package:angular/core/parser/unparser.dart' show Unparser;
55
import 'package:angular/core/parser/utils.dart' show EvalError;
6+
import 'package:angular/core/module.dart';
67

78
abstract class Visitor {
89
visit(Expression expression)
@@ -56,7 +57,7 @@ abstract class Expression {
5657
bool get isAssignable => false;
5758
bool get isChain => false;
5859

59-
eval(scope)
60+
eval(scope, [FilterMap filters = defaultFilterMap])
6061
=> throw new EvalError("Cannot evaluate $this");
6162
assign(scope, value)
6263
=> throw new EvalError("Cannot assign to $this");
@@ -200,3 +201,14 @@ class LiteralObject extends Literal {
200201
LiteralObject(this.keys, this.values);
201202
accept(Visitor visitor) => visitor.visitLiteralObject(this);
202203
}
204+
205+
const defaultFilterMap = const _DefaultFilterMap();
206+
207+
class _DefaultFilterMap implements FilterMap {
208+
const _DefaultFilterMap();
209+
210+
call(name) => throw 'No NgFilter: $name found!';
211+
Type operator[](annotation) => null;
212+
forEach(fn) { }
213+
annotationsFor(type) => null;
214+
}

lib/core/parser/utils.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
library angular.core.parser.utils;
22

33
import 'package:angular/core/parser/syntax.dart' show Expression;
4+
import 'package:angular/core/module.dart';
45
export 'package:angular/utils.dart' show relaxFnApply, relaxFnArgs, toBool;
56

67
/// Marker for an uninitialized value.
@@ -18,14 +19,14 @@ class EvalError {
1819
}
1920

2021
/// Evaluate the [list] in context of the [scope].
21-
List evalList(scope, List<Expression> list) {
22+
List evalList(scope, List<Expression> list, [FilterMap filters]) {
2223
int length = list.length;
2324
for(int cacheLength = _evalListCache.length; cacheLength <= length; cacheLength++) {
2425
_evalListCache.add(new List(cacheLength));
2526
}
2627
List result = _evalListCache[length];
2728
for (int i = 0; i < length; i++) {
28-
result[i] = list[i].eval(scope);
29+
result[i] = list[i].eval(scope, filters);
2930
}
3031
return result;
3132
}

0 commit comments

Comments
 (0)