Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(37)

Side by Side Diff: pkg/smoke/lib/static.dart

Issue 204143002: Changes in smoke in preparation of polymer's codegen: (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « pkg/smoke/lib/src/common.dart ('k') | pkg/smoke/lib/static_debug.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 StaticConfiguration _configuration;
19
20 class StaticConfiguration { 18 class StaticConfiguration {
21 /// 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
22 /// instance, `#i: (o) => o.i`. 20 /// instance, `#i: (o) => o.i`.
23 final Map<Symbol, Getter> getters; 21 final Map<Symbol, Getter> getters;
24 22
25 /// 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
26 /// instance, `#i: (o, v) { o.i = v; }`. 24 /// instance, `#i: (o, v) { o.i = v; }`.
27 final Map<Symbol, Setter> setters; 25 final Map<Symbol, Setter> setters;
28 26
29 /// Maps a type to it's super class. For example, String: Object. 27 /// Maps a type to it's super class. For example, String: Object.
30 final Map<Type, Type> parents; 28 final Map<Type, Type> parents;
31 29
32 /// 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).
33 final Map<Type, Map<Symbol, Declaration>> declarations; 31 final Map<Type, Map<Symbol, Declaration>> declarations;
34 32
35 /// A map from symbol to strings. 33 /// A map from symbol to strings.
36 final Map<Symbol, String> names; 34 final Map<Symbol, String> names;
37 35
38 /// A map from strings to symbols (the reverse of [names]).
39 final Map<String, Symbol> symbols;
40
41 /// Whether to check for missing declarations, otherwise, return default 36 /// Whether to check for missing declarations, otherwise, return default
42 /// values (for example a missing parent class can be treated as Object) 37 /// values (for example a missing parent class can be treated as Object)
43 final bool checkedMode; 38 final bool checkedMode;
44 39
45 StaticConfiguration({ 40 StaticConfiguration({
46 this.getters: const {}, this.setters: const {}, this.parents: const {}, 41 this.getters: const {}, this.setters: const {}, this.parents: const {},
47 this.declarations: const {}, this.names: const {}, 42 this.declarations: const {}, this.names: const {},
48 this.checkedMode: true}) 43 this.checkedMode: true});
49 : this.symbols = {} {
50 names.forEach((k, v) { symbols[v] = k; });
51 }
52 } 44 }
53 45
54 /// Set up the smoke package to use a static implementation based on the given 46 /// Set up the smoke package to use a static implementation based on the given
55 /// [configuration]. 47 /// [configuration].
56 useGeneratedCode(StaticConfiguration configuration) { 48 useGeneratedCode(StaticConfiguration configuration) {
57 _configuration = configuration; 49 configure(new GeneratedObjectAccessorService(configuration),
58 configure(new _GeneratedObjectAccessorService(), 50 new GeneratedTypeInspectorService(configuration),
59 new _GeneratedTypeInspectorService(), 51 new GeneratedSymbolConverterService(configuration));
60 new _GeneratedSymbolConverterService());
61 } 52 }
62 53
63 /// Implements [ObjectAccessorService] using a static configuration. 54 /// Implements [ObjectAccessorService] using a static configuration.
64 class _GeneratedObjectAccessorService implements ObjectAccessorService { 55 class GeneratedObjectAccessorService implements ObjectAccessorService {
56 final Map<Symbol, Getter> _getters;
57 final Map<Symbol, Setter> _setters;
58
59 GeneratedObjectAccessorService(StaticConfiguration configuration)
60 : _getters = configuration.getters,
61 _setters = configuration.setters;
62
65 read(Object object, Symbol name) { 63 read(Object object, Symbol name) {
66 var getter = _configuration.getters[name]; 64 var getter = _getters[name];
67 if (getter == null) { 65 if (getter == null) {
68 throw new MissingCodeException('getter "$name" in $object'); 66 throw new MissingCodeException('getter "$name" in $object');
69 } 67 }
70 return getter(object); 68 return getter(object);
71 } 69 }
72 void write(Object object, Symbol name, value) { 70 void write(Object object, Symbol name, value) {
73 var setter = _configuration.setters[name]; 71 var setter = _setters[name];
74 if (setter == null) { 72 if (setter == null) {
75 throw new MissingCodeException('setter "$name" in $object'); 73 throw new MissingCodeException('setter "$name" in $object');
76 } 74 }
77 setter(object, value); 75 setter(object, value);
78 } 76 }
79 77
80 invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) { 78 invoke(object, Symbol name, List args, {Map namedArgs, bool adjust: false}) {
81 var method; 79 var method;
82 if (object is Type) { 80 if (object is Type) {
83 } else { 81 } else {
84 var getter = _configuration.getters[name]; 82 var getter = _getters[name];
85 method = getter == null ? null : getter(object); 83 method = getter == null ? null : getter(object);
86 } 84 }
87 if (method == null) { 85 if (method == null) {
88 throw new MissingCodeException('method "$name" in $object'); 86 throw new MissingCodeException('method "$name" in $object');
89 } 87 }
90 var tentativeError; 88 var tentativeError;
91 if (adjust) { 89 if (adjust) {
92 var min = minArgs(method); 90 var min = minArgs(method);
93 if (min > SUPPORTED_ARGS) { 91 if (min > SUPPORTED_ARGS) {
94 tentativeError = 'we tried to adjust the arguments for calling "$name"' 92 tentativeError = 'we tried to adjust the arguments for calling "$name"'
(...skipping 17 matching lines...) Expand all
112 // TODO(sigmund): consider whether this should just be in a logger or if 110 // TODO(sigmund): consider whether this should just be in a logger or if
113 // we should wrap `e` as a new exception (what's the best way to let users 111 // we should wrap `e` as a new exception (what's the best way to let users
114 // know about this tentativeError?) 112 // know about this tentativeError?)
115 if (tentativeError != null) print(tentativeError); 113 if (tentativeError != null) print(tentativeError);
116 rethrow; 114 rethrow;
117 } 115 }
118 } 116 }
119 } 117 }
120 118
121 /// Implements [TypeInspectorService] using a static configuration. 119 /// Implements [TypeInspectorService] using a static configuration.
122 class _GeneratedTypeInspectorService implements TypeInspectorService { 120 class GeneratedTypeInspectorService implements TypeInspectorService {
121 final Map<Type, Type> _parents;
122 final Map<Type, Map<Symbol, Declaration>> _declarations;
123 final bool _checkedMode;
124
125 GeneratedTypeInspectorService(StaticConfiguration configuration)
126 : _parents = configuration.parents,
127 _declarations = configuration.declarations,
128 _checkedMode = configuration.checkedMode;
123 bool isSubclassOf(Type type, Type supertype) { 129 bool isSubclassOf(Type type, Type supertype) {
124 if (type == supertype || supertype == Object) return true; 130 if (type == supertype || supertype == Object) return true;
125 while (type != Object) { 131 while (type != Object) {
126 var parentType = _configuration.parents[type]; 132 var parentType = _parents[type];
127 if (parentType == supertype) return true; 133 if (parentType == supertype) return true;
128 if (parentType == null) { 134 if (parentType == null) {
129 if (!_configuration.checkedMode) return false; 135 if (!_checkedMode) return false;
130 throw new MissingCodeException('superclass of "$type" ($parentType)'); 136 throw new MissingCodeException('superclass of "$type" ($parentType)');
131 } 137 }
132 type = parentType; 138 type = parentType;
133 } 139 }
134 return false; 140 return false;
135 } 141 }
136 142
137 bool hasGetter(Type type, Symbol name) { 143 bool hasGetter(Type type, Symbol name) {
138 var decl = _findDeclaration(type, name); 144 var decl = _findDeclaration(type, name);
139 // No need to check decl.isProperty because methods are also automatically 145 // No need to check decl.isProperty because methods are also automatically
140 // considered getters (auto-closures). 146 // considered getters (auto-closures).
141 return decl != null && !decl.isStatic; 147 return decl != null && !decl.isStatic;
142 } 148 }
143 149
144 bool hasSetter(Type type, Symbol name) { 150 bool hasSetter(Type type, Symbol name) {
145 var decl = _findDeclaration(type, name); 151 var decl = _findDeclaration(type, name);
146 return decl != null && !decl.isMethod && !decl.isFinal && !decl.isStatic; 152 return decl != null && !decl.isMethod && !decl.isFinal && !decl.isStatic;
147 } 153 }
148 154
149 bool hasInstanceMethod(Type type, Symbol name) { 155 bool hasInstanceMethod(Type type, Symbol name) {
150 var decl = _findDeclaration(type, name); 156 var decl = _findDeclaration(type, name);
151 return decl != null && decl.isMethod && !decl.isStatic; 157 return decl != null && decl.isMethod && !decl.isStatic;
152 } 158 }
153 159
154 bool hasStaticMethod(Type type, Symbol name) { 160 bool hasStaticMethod(Type type, Symbol name) {
155 final map = _configuration.declarations[type]; 161 final map = _declarations[type];
156 if (map == null) { 162 if (map == null) {
157 if (!_configuration.checkedMode) return false; 163 if (!_checkedMode) return false;
158 throw new MissingCodeException('declarations for $type'); 164 throw new MissingCodeException('declarations for $type');
159 } 165 }
160 final decl = map[name]; 166 final decl = map[name];
161 return decl != null && decl.isMethod && decl.isStatic; 167 return decl != null && decl.isMethod && decl.isStatic;
162 } 168 }
163 169
164 Declaration getDeclaration(Type type, Symbol name) { 170 Declaration getDeclaration(Type type, Symbol name) {
165 var decl = _findDeclaration(type, name); 171 var decl = _findDeclaration(type, name);
166 if (decl == null) { 172 if (decl == null) {
167 if (!_configuration.checkedMode) return null; 173 if (!_checkedMode) return null;
168 throw new MissingCodeException('declaration for $type.$name'); 174 throw new MissingCodeException('declaration for $type.$name');
169 } 175 }
170 return decl; 176 return decl;
171 } 177 }
172 178
173 List<Declaration> query(Type type, QueryOptions options) { 179 List<Declaration> query(Type type, QueryOptions options) {
174 var result = []; 180 var result = [];
175 if (options.includeInherited) { 181 if (options.includeInherited) {
176 var superclass = _configuration.parents[type]; 182 var superclass = _parents[type];
177 if (superclass == null) { 183 if (superclass == null) {
178 if (_configuration.checkedMode) { 184 if (_checkedMode) {
179 throw new MissingCodeException('superclass of "$type"'); 185 throw new MissingCodeException('superclass of "$type"');
180 } 186 }
181 } else if (superclass != options.includeUpTo) { 187 } else if (superclass != options.includeUpTo) {
182 result = query(superclass, options); 188 result = query(superclass, options);
183 } 189 }
184 } 190 }
185 var map = _configuration.declarations[type]; 191 var map = _declarations[type];
186 if (map == null) { 192 if (map == null) {
187 if (!_configuration.checkedMode) return result; 193 if (!_checkedMode) return result;
188 throw new MissingCodeException('declarations for $type'); 194 throw new MissingCodeException('declarations for $type');
189 } 195 }
190 for (var decl in map.values) { 196 for (var decl in map.values) {
191 if (!options.includeFields && decl.isField) continue; 197 if (!options.includeFields && decl.isField) continue;
192 if (!options.includeProperties && decl.isProperty) continue; 198 if (!options.includeProperties && decl.isProperty) continue;
193 if (options.excludeFinal && decl.isFinal) continue; 199 if (options.excludeFinal && decl.isFinal) continue;
194 if (!options.includeMethods && decl.isMethod) continue; 200 if (!options.includeMethods && decl.isMethod) continue;
201 if (options.matches != null && !options.matches(decl.name)) continue;
195 if (options.withAnnotations != null && 202 if (options.withAnnotations != null &&
196 !matchesAnnotation(decl.annotations, options.withAnnotations)) { 203 !matchesAnnotation(decl.annotations, options.withAnnotations)) {
197 continue; 204 continue;
198 } 205 }
199 result.add(decl); 206 result.add(decl);
200 } 207 }
201 return result; 208 return result;
202 } 209 }
210
211 Declaration _findDeclaration(Type type, Symbol name) {
212 while (type != Object) {
213 final declarations = _declarations[type];
214 if (declarations != null) {
215 final declaration = declarations[name];
216 if (declaration != null) return declaration;
217 }
218 var parentType = _parents[type];
219 if (parentType == null) {
220 if (!_checkedMode) return null;
221 throw new MissingCodeException('superclass of "$type"');
222 }
223 type = parentType;
224 }
225 return null;
226 }
203 } 227 }
204 228
205 /// Implements [SymbolConverterService] using a static configuration. 229 /// Implements [SymbolConverterService] using a static configuration.
206 class _GeneratedSymbolConverterService implements SymbolConverterService { 230 class GeneratedSymbolConverterService implements SymbolConverterService {
207 String symbolToName(Symbol symbol) => _configuration.names[symbol]; 231 Map<Symbol, String> _names;
208 Symbol nameToSymbol(String name) => _configuration.symbols[name]; 232
233 /// A map from strings to symbols (the reverse of [names]).
234 final Map<String, Symbol> _symbols;
235
236 GeneratedSymbolConverterService(StaticConfiguration configuration)
237 : _names = configuration.names,
238 _symbols = {} {
239 _names.forEach((k, v) { _symbols[v] = k; });
240 }
241
242 String symbolToName(Symbol symbol) => _names[symbol];
243 Symbol nameToSymbol(String name) => _symbols[name];
209 } 244 }
210 245
211 246
212 /// Exception thrown when trynig to access something that should be there, but 247 /// Exception thrown when trynig to access something that should be there, but
213 /// the code generator didn't include it. 248 /// the code generator didn't include it.
214 class MissingCodeException implements Exception { 249 class MissingCodeException implements Exception {
215 final String description; 250 final String description;
216 MissingCodeException(this.description); 251 MissingCodeException(this.description);
217 252
218 String toString() => 'Missing $description. ' 253 String toString() => 'Missing $description. '
219 'Code generation for the smoke package seems incomplete.'; 254 'Code generation for the smoke package seems incomplete.';
220 } 255 }
221
222 Declaration _findDeclaration(Type type, Symbol name) {
223 while (type != Object) {
224 final declarations = _configuration.declarations[type];
225 if (declarations != null) {
226 final declaration = declarations[name];
227 if (declaration != null) return declaration;
228 }
229 var parentType = _configuration.parents[type];
230 if (parentType == null) {
231 if (!_configuration.checkedMode) return null;
232 throw new MissingCodeException('superclass of "$type"');
233 }
234 type = parentType;
235 }
236 return null;
237 }
OLDNEW
« no previous file with comments | « pkg/smoke/lib/src/common.dart ('k') | pkg/smoke/lib/static_debug.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698