| OLD | NEW |
| 1 import 'package:angular/core/parser/parser_library.dart'; | 1 import 'package:angular/core/parser/parser.dart'; |
| 2 import 'package:angular/tools/reserved_dart_keywords.dart'; | 2 import 'package:angular/tools/reserved_dart_keywords.dart'; |
| 3 import 'dart:math'; |
| 3 | 4 |
| 4 class _AST implements ParserAST { | 5 class DartGetterSetterGen extends ParserBackend { |
| 5 bool get assignable => true; | 6 final Set<String> properties = new Set<String>(); |
| 6 } | 7 final Map<String, Set<int>> calls = new Map<String, Set<int>>(); |
| 7 | 8 |
| 8 class DartGetterSetterGen implements ParserBackend { | 9 bool isAssignable(expression) => true; |
| 9 Map<String, bool> identifiers = {}; | |
| 10 | 10 |
| 11 profiled(value, perf, text) => new _AST(); | 11 registerAccess(String name) { |
| 12 | 12 if (isReserved(name)) return; |
| 13 binaryFn(left, String fn, right) => new _AST(); | 13 properties.add(name); |
| 14 unaryFn(String fn, right) => new _AST(); | |
| 15 ternaryFn(Expression cond, Expression _true, Expression _false) => new _AST(); | |
| 16 assignment(left, right, evalError) => new _AST(); | |
| 17 multipleStatements(List statements) => new _AST(); | |
| 18 arrayDeclaration(List elementFns) => new _AST(); | |
| 19 objectIndex(obj, indexFn, evalError) => new _AST(); | |
| 20 object(List keyValues) => new _AST(); | |
| 21 fromOperator(String op) => new _AST(); | |
| 22 value(v) => new _AST(); | |
| 23 zero() => new _AST(); | |
| 24 functionCall(fn, fnName, List argsFn, evalError) => new _AST(); | |
| 25 filter(String filterName, | |
| 26 Expression leftHandSide, | |
| 27 List<Expression> parameters, | |
| 28 Function evalError) => new _AST(); | |
| 29 | |
| 30 setter(String path) => throw new UnimplementedError(); | |
| 31 getter(String path) => throw new UnimplementedError(); | |
| 32 | |
| 33 | |
| 34 fieldAccess(object, String field) { | |
| 35 identifiers[field] = true; | |
| 36 return new _AST(); | |
| 37 } | 14 } |
| 38 | 15 |
| 39 getterSetter(String key) { | 16 registerCall(String name, List arguments) { |
| 40 key.split('.').forEach((i) => identifiers[i] = true); | 17 if (isReserved(name)) return; |
| 41 return new _AST(); | 18 Set<int> arities = calls.putIfAbsent(name, () => new Set<int>()); |
| 19 arities.add(arguments.length); |
| 42 } | 20 } |
| 21 |
| 22 newAccessScope(String name) |
| 23 => registerAccess(name); |
| 24 newAccessMember(var object, String name) |
| 25 => registerAccess(name); |
| 26 newCallScope(String name, List arguments) |
| 27 => registerCall(name, arguments); |
| 28 newCallMember(var object, String name, List arguments) |
| 29 => registerCall(name, arguments); |
| 43 } | 30 } |
| 44 | 31 |
| 45 class ParserGetterSetter { | 32 class ParserGetterSetter { |
| 46 | 33 final Parser parser; |
| 47 DynamicParser parser; | 34 final ParserBackend backend; |
| 48 DartGetterSetterGen backend; | |
| 49 | |
| 50 ParserGetterSetter(this.parser, this.backend); | 35 ParserGetterSetter(this.parser, this.backend); |
| 51 | 36 |
| 52 generateParser(List<String> exprs) { | 37 generateParser(List<String> exprs) { |
| 53 exprs.forEach((expr) { | 38 exprs.forEach((expr) { |
| 54 try { | 39 try { |
| 55 parser(expr); | 40 parser(expr); |
| 56 } catch (e) { } | 41 } catch (e) { |
| 42 // Ignore exceptions. |
| 43 } |
| 57 }); | 44 }); |
| 58 | 45 |
| 59 print(generateCode(backend.identifiers.keys.toList())); | 46 DartGetterSetterGen backend = this.backend; |
| 47 print(generateClosureMap(backend.properties, backend.calls)); |
| 60 } | 48 } |
| 61 | 49 |
| 62 generateCode(Iterable<String> keys) { | 50 generateClosureMap(Set<String> properties, Map<String, Set<int>> calls) { |
| 63 keys = keys.where((key) => !isReserved(key)); | |
| 64 return ''' | 51 return ''' |
| 65 class StaticGetterSetter extends GetterSetter { | 52 class StaticClosureMap extends ClosureMap { |
| 66 Map<String, Function> _getters = ${generateGetterMap(keys)}; | 53 Map<String, Getter> _getters = ${generateGetterMap(properties)}; |
| 67 Map<String, Function> _setters = ${generateSetterMap(keys)}; | 54 Map<String, Setter> _setters = ${generateSetterMap(properties)}; |
| 55 List<Map<String, Function>> _functions = ${generateFunctionMap(calls)}; |
| 68 | 56 |
| 69 Function getter(String key) { | 57 Getter lookupGetter(String name) |
| 70 return _getters.containsKey(key) ? _getters[key] : super.getter(key); | 58 => _getters[name]; |
| 71 } | 59 Setter lookupSetter(String name) |
| 72 | 60 => _setters[name]; |
| 73 Function setter(String key) { | 61 lookupFunction(String name, int arity) |
| 74 return _setters.containsKey(key) ? _setters[key] : super.setter(key); | 62 => (arity < _functions.length) ? _functions[arity][name] : null; |
| 75 } | |
| 76 | |
| 77 } | 63 } |
| 78 '''; | 64 '''; |
| 79 } | 65 } |
| 80 | 66 |
| 81 generateGetterMap(Iterable<String> keys) { | 67 generateGetterMap(Iterable<String> keys) { |
| 82 var lines = keys.map((key) => 'r"${key}": (s) => s.$key'); | 68 var lines = keys.map((key) => 'r"${key}": (o) => o.$key'); |
| 83 return '{\n ${lines.join(",\n ")}\n }'; | 69 return '{\n ${lines.join(",\n ")}\n }'; |
| 84 } | 70 } |
| 85 | 71 |
| 86 generateSetterMap(Iterable<String> keys) { | 72 generateSetterMap(Iterable<String> keys) { |
| 87 var lines = keys.map((key) => 'r"${key}": (s, v) => s.$key = v'); | 73 var lines = keys.map((key) => 'r"${key}": (o, v) => o.$key = v'); |
| 88 return '{\n ${lines.join(",\n ")}\n }'; | 74 return '{\n ${lines.join(",\n ")}\n }'; |
| 89 } | 75 } |
| 76 |
| 77 generateFunctionMap(Map<String, Set<int>> calls) { |
| 78 Map<int, Set<String>> arities = {}; |
| 79 calls.forEach((name, callArities) { |
| 80 callArities.forEach((arity){ |
| 81 arities.putIfAbsent(arity, () => new Set<String>()).add(name); |
| 82 }); |
| 83 }); |
| 84 |
| 85 var maxArity = arities.keys.reduce((x, y) => max(x, y)); |
| 86 |
| 87 var maps = new Iterable.generate(maxArity, (arity) { |
| 88 var names = arities[arity]; |
| 89 if (names == null) { |
| 90 return '{\n }'; |
| 91 } else { |
| 92 var args = new List.generate(arity, (e) => "a$e").join(','); |
| 93 var p = args.isEmpty ? '' : ', $args'; |
| 94 var lines = names.map((name) => 'r"$name": (o$p) => o.$name($args)'); |
| 95 return '{\n ${lines.join(",\n ")}\n }'; |
| 96 } |
| 97 }); |
| 98 |
| 99 return '[${maps.join(",")}]'; |
| 100 } |
| 90 } | 101 } |
| OLD | NEW |