| 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 |