| OLD | NEW |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /// Static implementation of smoke services using code-generated data. | 5 /// Static implementation of smoke services using code-generated data. |
| 6 library smoke.static; | 6 library smoke.static; |
| 7 | 7 |
| 8 import 'dart:math' as math; | 8 import 'dart:math' as math; |
| 9 | 9 |
| 10 import 'package:logging/logging.dart'; | 10 import 'package:logging/logging.dart'; |
| 11 import 'package:smoke/smoke.dart'; | 11 import 'package:smoke/smoke.dart'; |
| 12 | 12 |
| 13 import 'src/common.dart'; | 13 import 'src/common.dart'; |
| 14 | 14 |
| 15 typedef T Getter<T>(object); | 15 typedef T Getter<T>(object); |
| 16 typedef void Setter<T>(object, value); | 16 typedef void Setter<T>(object, value); |
| 17 | 17 |
| 18 class StaticConfiguration { | 18 class StaticConfiguration { |
| 19 /// Maps symbol to a function that reads that symbol of an object. For | 19 /// Maps symbol to a function that reads that symbol of an object. For |
| 20 /// instance, `#i: (o) => o.i`. | 20 /// instance, `#i: (o) => o.i`. |
| 21 final Map<Symbol, Getter> getters; | 21 final Map<Symbol, Getter> getters; |
| 22 | 22 |
| 23 /// Maps symbol to a function that updates that symbol of an object. For | 23 /// Maps symbol to a function that updates that symbol of an object. For |
| 24 /// instance, `#i: (o, v) { o.i = v; }`. | 24 /// instance, `#i: (o, v) { o.i = v; }`. |
| 25 final Map<Symbol, Setter> setters; | 25 final Map<Symbol, Setter> setters; |
| 26 | 26 |
| 27 /// Maps a type to it's super class. For example, String: Object. | 27 /// Maps a type to its super class. For example, String: Object. |
| 28 final Map<Type, Type> parents; | 28 final Map<Type, Type> parents; |
| 29 | 29 |
| 30 /// For each type, a map of declarations per symbol (property or method). | 30 /// For each type, a map of declarations per symbol (property or method). |
| 31 final Map<Type, Map<Symbol, Declaration>> declarations; | 31 final Map<Type, Map<Symbol, Declaration>> declarations; |
| 32 | 32 |
| 33 /// Static methods for each type. |
| 34 // TODO(sigmund): should we add static getters & setters too? |
| 35 final Map<Type, Map<Symbol, Function>> staticMethods; |
| 36 |
| 33 /// A map from symbol to strings. | 37 /// A map from symbol to strings. |
| 34 final Map<Symbol, String> names; | 38 final Map<Symbol, String> names; |
| 35 | 39 |
| 36 /// Whether to check for missing declarations, otherwise, return default | 40 /// Whether to check for missing declarations, otherwise, return default |
| 37 /// values (for example a missing parent class can be treated as Object) | 41 /// values (for example a missing parent class can be treated as Object) |
| 38 final bool checkedMode; | 42 final bool checkedMode; |
| 39 | 43 |
| 40 StaticConfiguration({ | 44 StaticConfiguration({ |
| 41 this.getters: const {}, this.setters: const {}, this.parents: const {}, | 45 this.getters: const {}, this.setters: const {}, this.parents: const {}, |
| 42 this.declarations: const {}, this.names: const {}, | 46 this.declarations: const {}, this.staticMethods: const {}, |
| 43 this.checkedMode: true}); | 47 this.names: const {}, this.checkedMode: true}); |
| 44 } | 48 } |
| 45 | 49 |
| 46 /// Set up the smoke package to use a static implementation based on the given | 50 /// Set up the smoke package to use a static implementation based on the given |
| 47 /// [configuration]. | 51 /// [configuration]. |
| 48 useGeneratedCode(StaticConfiguration configuration) { | 52 useGeneratedCode(StaticConfiguration configuration) { |
| 49 configure(new GeneratedObjectAccessorService(configuration), | 53 configure(new GeneratedObjectAccessorService(configuration), |
| 50 new GeneratedTypeInspectorService(configuration), | 54 new GeneratedTypeInspectorService(configuration), |
| 51 new GeneratedSymbolConverterService(configuration)); | 55 new GeneratedSymbolConverterService(configuration)); |
| 52 } | 56 } |
| 53 | 57 |
| 54 /// Implements [ObjectAccessorService] using a static configuration. | 58 /// Implements [ObjectAccessorService] using a static configuration. |
| 55 class GeneratedObjectAccessorService implements ObjectAccessorService { | 59 class GeneratedObjectAccessorService implements ObjectAccessorService { |
| 56 final Map<Symbol, Getter> _getters; | 60 final Map<Symbol, Getter> _getters; |
| 57 final Map<Symbol, Setter> _setters; | 61 final Map<Symbol, Setter> _setters; |
| 62 final Map<Type, Map<Symbol, Function>> _staticMethods; |
| 58 | 63 |
| 59 GeneratedObjectAccessorService(StaticConfiguration configuration) | 64 GeneratedObjectAccessorService(StaticConfiguration configuration) |
| 60 : _getters = configuration.getters, | 65 : _getters = configuration.getters, |
| 61 _setters = configuration.setters; | 66 _setters = configuration.setters, |
| 67 _staticMethods = configuration.staticMethods; |
| 62 | 68 |
| 63 read(Object object, Symbol name) { | 69 read(Object object, Symbol name) { |
| 64 var getter = _getters[name]; | 70 var getter = _getters[name]; |
| 65 if (getter == null) { | 71 if (getter == null) { |
| 66 throw new MissingCodeException('getter "$name" in $object'); | 72 throw new MissingCodeException('getter "$name" in $object'); |
| 67 } | 73 } |
| 68 return getter(object); | 74 return getter(object); |
| 69 } | 75 } |
| 76 |
| 70 void write(Object object, Symbol name, value) { | 77 void write(Object object, Symbol name, value) { |
| 71 var setter = _setters[name]; | 78 var setter = _setters[name]; |
| 72 if (setter == null) { | 79 if (setter == null) { |
| 73 throw new MissingCodeException('setter "$name" in $object'); | 80 throw new MissingCodeException('setter "$name" in $object'); |
| 74 } | 81 } |
| 75 setter(object, value); | 82 setter(object, value); |
| 76 } | 83 } |
| 77 | 84 |
| 78 invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) { | 85 invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) { |
| 79 var method; | 86 var method; |
| 80 if (object is Type) { | 87 if (object is Type) { |
| 88 var classMethods = _staticMethods[object]; |
| 89 method = classMethods == null ? null : classMethods[name]; |
| 81 } else { | 90 } else { |
| 82 var getter = _getters[name]; | 91 var getter = _getters[name]; |
| 83 method = getter == null ? null : getter(object); | 92 method = getter == null ? null : getter(object); |
| 84 } | 93 } |
| 85 if (method == null) { | 94 if (method == null) { |
| 86 throw new MissingCodeException('method "$name" in $object'); | 95 throw new MissingCodeException('method "$name" in $object'); |
| 87 } | 96 } |
| 88 var tentativeError; | 97 var tentativeError; |
| 89 if (adjust) { | 98 if (adjust) { |
| 90 var min = minArgs(method); | 99 var min = minArgs(method); |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 | 255 |
| 247 /// Exception thrown when trynig to access something that should be there, but | 256 /// Exception thrown when trynig to access something that should be there, but |
| 248 /// the code generator didn't include it. | 257 /// the code generator didn't include it. |
| 249 class MissingCodeException implements Exception { | 258 class MissingCodeException implements Exception { |
| 250 final String description; | 259 final String description; |
| 251 MissingCodeException(this.description); | 260 MissingCodeException(this.description); |
| 252 | 261 |
| 253 String toString() => 'Missing $description. ' | 262 String toString() => 'Missing $description. ' |
| 254 'Code generation for the smoke package seems incomplete.'; | 263 'Code generation for the smoke package seems incomplete.'; |
| 255 } | 264 } |
| OLD | NEW |