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 /// Implementation of the smoke services using mirrors. | 5 /// Implementation of the smoke services using mirrors. |
6 library smoke.mirrors; | 6 library smoke.mirrors; |
7 | 7 |
8 import 'dart:mirrors'; | 8 import 'dart:mirrors'; |
9 import 'package:smoke/smoke.dart'; | 9 import 'package:smoke/smoke.dart'; |
10 import 'package:logging/logging.dart'; | 10 import 'package:logging/logging.dart'; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 if (member is MethodMirror && member.isGetter) { | 173 if (member is MethodMirror && member.isGetter) { |
174 if (!options.includeProperties) continue; | 174 if (!options.includeProperties) continue; |
175 if (options.excludeFinal && !_hasSetter(cls, member)) continue; | 175 if (options.excludeFinal && !_hasSetter(cls, member)) continue; |
176 } | 176 } |
177 | 177 |
178 if (member is MethodMirror && member.isRegularMethod) { | 178 if (member is MethodMirror && member.isRegularMethod) { |
179 if (!options.includeMethods) continue; | 179 if (!options.includeMethods) continue; |
180 isMethod = true; | 180 isMethod = true; |
181 } | 181 } |
182 | 182 |
| 183 if (options.matches != null && !options.matches(name)) continue; |
| 184 |
183 var annotations = | 185 var annotations = |
184 member.metadata.map((m) => m.reflectee).toList(); | 186 member.metadata.map((m) => m.reflectee).toList(); |
185 if (options.withAnnotations != null && | 187 if (options.withAnnotations != null && |
186 !matchesAnnotation(annotations, options.withAnnotations)) { | 188 !matchesAnnotation(annotations, options.withAnnotations)) { |
187 continue; | 189 continue; |
188 } | 190 } |
189 | 191 |
190 // TODO(sigmund): should we cache parts of this declaration so we don't | 192 // TODO(sigmund): should we cache parts of this declaration so we don't |
191 // compute them twice? For example, this chould be `new Declaration(name, | 193 // compute them twice? For example, this chould be `new Declaration(name, |
192 // type, ...)` and we could reuse what we computed above to implement the | 194 // type, ...)` and we could reuse what we computed above to implement the |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 : _original.returnType; | 293 : _original.returnType; |
292 return _toType(typeMirror); | 294 return _toType(typeMirror); |
293 } | 295 } |
294 | 296 |
295 /// Whether this symbol is static. | 297 /// Whether this symbol is static. |
296 bool get isStatic => _original.isStatic; | 298 bool get isStatic => _original.isStatic; |
297 | 299 |
298 /// List of annotations in this declaration. | 300 /// List of annotations in this declaration. |
299 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); | 301 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); |
300 | 302 |
301 String toString() { | 303 int get hashCode => name.hashCode; |
302 return (new StringBuffer() | 304 operator ==(other) => other is Declaration && name == other.name && |
303 ..write('[declaration ') | 305 kind == other.kind && isFinal == other.isFinal && |
304 ..write(name) | 306 type == other.type && isStatic == other.isStatic && |
305 ..write(isField ? ' (field) ' | 307 compareLists(annotations, other.annotations); |
306 : (isProperty ? ' (property) ' : ' (method) ')) | 308 String toString() => (new StringBuffer() |
307 ..write(isFinal ? 'final ' : '') | 309 ..write('(mirror-based-declaration ') |
308 ..write(isStatic ? 'static ' : '') | 310 ..write(name) |
309 ..write(annotations) | 311 ..write(isField ? ' (field) ' |
310 ..write(']')).toString(); | 312 : (isProperty ? ' (property) ' : ' (method) ')) |
311 } | 313 ..write(isFinal ? 'final ' : '') |
| 314 ..write(isStatic ? 'static ' : '') |
| 315 ..write(annotations) |
| 316 ..write(')')).toString(); |
312 } | 317 } |
313 | 318 |
314 class _MethodClosure extends Function { | 319 class _MethodClosure extends Function { |
315 final receiver; | 320 final receiver; |
316 final Symbol methodName; | 321 final Symbol methodName; |
317 | 322 |
318 _MethodClosure(this.receiver, this.methodName); | 323 _MethodClosure(this.receiver, this.methodName); |
319 | 324 |
320 // Technically we could just use noSuchMethod to implement [call], but we | 325 // Technically we could just use noSuchMethod to implement [call], but we |
321 // don't for 3 reasons: | 326 // don't for 3 reasons: |
322 // * noSuchMethod makes the code a lot bigger. | 327 // * noSuchMethod makes the code a lot bigger. |
323 // * even with noSuchMethod, an analyzer bug requires to declare [call] (see | 328 // * even with noSuchMethod, an analyzer bug requires to declare [call] (see |
324 // dartbug.com/16078). | 329 // dartbug.com/16078). |
325 // * having [call] also allows `is` checks to work for functions of 0 | 330 // * having [call] also allows `is` checks to work for functions of 0 |
326 // through 3 arguments. We depend on this in | 331 // through 3 arguments. We depend on this in |
327 // `polymer_expressions/lib/eval.dart` to check whether a function is a | 332 // `polymer_expressions/lib/eval.dart` to check whether a function is a |
328 // filter (takes a single argument). (Note that it's possible to include | 333 // filter (takes a single argument). (Note that it's possible to include |
329 // both [call] and [noSuchMethod], which would make instance-of checks | 334 // both [call] and [noSuchMethod], which would make instance-of checks |
330 // work with the signature of [call], but will allow invoking the function | 335 // work with the signature of [call], but will allow invoking the function |
331 // using [noSuchMethod]. | 336 // using [noSuchMethod]. |
332 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); | 337 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); |
333 } | 338 } |
OLD | NEW |