|
| 1 | +part of angular.change_detector; |
| 2 | + |
| 3 | +/** |
| 4 | + * RULES: |
| 5 | + * - ASTs are reusable. Don't store scope/instance refs there |
| 6 | + * - Parent knows about children, not the other way around. |
| 7 | + */ |
| 8 | +abstract class AST { |
| 9 | + static final String _CONTEXT = '#'; |
| 10 | + final String expression; |
| 11 | + var parsedExp; // The parsed version of expression. |
| 12 | + |
| 13 | + AST(expression) |
| 14 | + : expression = expression.startsWith('#.') |
| 15 | + ? expression.substring(2) |
| 16 | + : expression |
| 17 | + { |
| 18 | + assert(expression != null); |
| 19 | + } |
| 20 | + |
| 21 | + Record setupRecord(WatchGroup watchGroup); |
| 22 | + |
| 23 | + String toString() => expression; |
| 24 | +} |
| 25 | + |
| 26 | +/** |
| 27 | + * SYNTAX: _context_ |
| 28 | + * |
| 29 | + * This represent the initial _context_ for evaluation. |
| 30 | + */ |
| 31 | +class ContextReferenceAST extends AST { |
| 32 | + ContextReferenceAST(): super(AST._CONTEXT); |
| 33 | + |
| 34 | + Record setupRecord(WatchGroup watchGroup) => |
| 35 | + watchGroup.addConstantRecord(expression, watchGroup._context); |
| 36 | +} |
| 37 | + |
| 38 | +/** |
| 39 | + * SYNTAX: _context_ |
| 40 | + * |
| 41 | + * This represent the initial _context_ for evaluation. |
| 42 | + */ |
| 43 | +class ConstantAST extends AST { |
| 44 | + final constant; |
| 45 | + |
| 46 | + ConstantAST(constant, [String expression]) |
| 47 | + : constant = constant, |
| 48 | + super(expression == null |
| 49 | + ? constant is String ? '"$constant"' : '$constant' |
| 50 | + : expression); |
| 51 | + |
| 52 | + Record setupRecord(WatchGroup watchGroup) => watchGroup.addConstantRecord(expression, constant); |
| 53 | +} |
| 54 | + |
| 55 | +/** |
| 56 | + * SYNTAX: lhs.name. |
| 57 | + * |
| 58 | + * This is the '.' dot operator. |
| 59 | + */ |
| 60 | +class FieldReadAST extends AST { |
| 61 | + AST lhsAST; |
| 62 | + final String name; |
| 63 | + |
| 64 | + FieldReadAST(lhsAST, name) |
| 65 | + : lhsAST = lhsAST, |
| 66 | + name = name, |
| 67 | + super('$lhsAST.$name'); |
| 68 | + |
| 69 | + Record setupRecord(WatchGroup watchGroup) => |
| 70 | + watchGroup.addFieldRecord(lhsAST, name, expression); |
| 71 | +} |
| 72 | + |
| 73 | +/** |
| 74 | + * SYNTAX: fn(arg0, arg1, ...) |
| 75 | + * |
| 76 | + * Invoke a pure function. Pure means that the function has no state, and |
| 77 | + * therefore it needs to be re-computed only if its args change. |
| 78 | + */ |
| 79 | +class PureFunctionAST extends AST { |
| 80 | + final String name; |
| 81 | + final /* dartbug.com/16401 Function */ fn; |
| 82 | + final List<AST> argsAST; |
| 83 | + |
| 84 | + PureFunctionAST(name, this.fn, argsAST) |
| 85 | + : argsAST = argsAST, |
| 86 | + name = name, |
| 87 | + super(_fnToString(name, argsAST)); |
| 88 | + |
| 89 | + Record setupRecord(WatchGroup watchGroup) => |
| 90 | + watchGroup.addFunctionRecord(fn, argsAST, const {}, expression, true); |
| 91 | +} |
| 92 | + |
| 93 | +/** |
| 94 | + * SYNTAX: fn(arg0, arg1, ...) |
| 95 | + * |
| 96 | + * Invoke a (non-pure) function. |
| 97 | + */ |
| 98 | +class ClosureAST extends AST { |
| 99 | + final String name; |
| 100 | + final /* dartbug.com/16401 Function */ fn; |
| 101 | + final List<AST> argsAST; |
| 102 | + |
| 103 | + ClosureAST(name, this.fn, argsAST) |
| 104 | + : argsAST = argsAST, |
| 105 | + name = name, |
| 106 | + super(_fnToString(name, argsAST)); |
| 107 | + |
| 108 | + Record setupRecord(WatchGroup watchGroup) => |
| 109 | + watchGroup.addFunctionRecord(fn, argsAST, const {}, expression, false); |
| 110 | +} |
| 111 | + |
| 112 | +/** |
| 113 | + * SYNTAX: lhs.method(arg0, arg1, ...) |
| 114 | + * |
| 115 | + * Invoke a method on [lhs] object. |
| 116 | + */ |
| 117 | +class MethodAST extends AST { |
| 118 | + final AST lhsAST; |
| 119 | + final String name; |
| 120 | + final List<AST> argsAST; |
| 121 | + final Map<Symbol, AST> namedArgsAST; |
| 122 | + |
| 123 | + MethodAST(lhsAST, name, argsAST, [this.namedArgsAST = const {}]) |
| 124 | + : lhsAST = lhsAST, |
| 125 | + name = name, |
| 126 | + argsAST = argsAST, |
| 127 | + super('$lhsAST.${_fnToString(name, argsAST)}'); |
| 128 | + |
| 129 | + Record setupRecord(WatchGroup watchGroup) => |
| 130 | + watchGroup.addMethodRecord(lhsAST, name, argsAST, namedArgsAST, expression); |
| 131 | +} |
| 132 | + |
| 133 | +class CollectionAST extends AST { |
| 134 | + final AST valueAST; |
| 135 | + |
| 136 | + CollectionAST(valueAST) |
| 137 | + : valueAST = valueAST, |
| 138 | + super('#collection($valueAST)'); |
| 139 | + |
| 140 | + Record setupRecord(WatchGroup watchGroup) => watchGroup.addCollectionRecord(this); |
| 141 | +} |
| 142 | + |
| 143 | +String _fnToString(String name, List<AST> items) => name + items.join(', '); |
| 144 | + |
| 145 | + |
| 146 | + |
0 commit comments