| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 } | 60 } |
| 61 } | 61 } |
| 62 args = adjustList(args, required, required + optional); | 62 args = adjustList(args, required, required + optional); |
| 63 } | 63 } |
| 64 return receiverMirror.invoke(methodName, args, namedArgs).reflectee; | 64 return receiverMirror.invoke(methodName, args, namedArgs).reflectee; |
| 65 } | 65 } |
| 66 } | 66 } |
| 67 | 67 |
| 68 /// Implements [TypeInspectorService] using mirrors. | 68 /// Implements [TypeInspectorService] using mirrors. |
| 69 class ReflectiveTypeInspectorService implements TypeInspectorService { | 69 class ReflectiveTypeInspectorService implements TypeInspectorService { |
| 70 bool isSubclassOf(Type type, Type supertype) { |
| 71 if (type == supertype || supertype == Object) return true; |
| 72 // TODO(sigmund): change to mirror.isSubclassOf when it gets implemented in |
| 73 // dart2js. (dartbug.com/12439) |
| 74 var mirror = reflectClass(type); |
| 75 var top = reflectClass(supertype); |
| 76 while (mirror != _objectType) { |
| 77 mirror = _safeSuperclass(mirror); |
| 78 if (mirror == top) return true; |
| 79 } |
| 80 return false; |
| 81 } |
| 82 |
| 70 bool hasGetter(Type type, Symbol name) { | 83 bool hasGetter(Type type, Symbol name) { |
| 71 var mirror = reflectType(type); | 84 var mirror = reflectType(type); |
| 72 if (mirror is! ClassMirror) return false; | 85 if (mirror is! ClassMirror) return false; |
| 73 while (mirror != _objectType) { | 86 while (mirror != _objectType) { |
| 74 final members = mirror.declarations; | 87 final members = mirror.declarations; |
| 75 if (members.containsKey(name)) return true; | 88 if (members.containsKey(name)) return true; |
| 76 mirror = _safeSuperclass(mirror); | 89 mirror = _safeSuperclass(mirror); |
| 77 } | 90 } |
| 78 return false; | 91 return false; |
| 79 } | 92 } |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 return new _MirrorDeclaration(mirror, declaration); | 143 return new _MirrorDeclaration(mirror, declaration); |
| 131 } | 144 } |
| 132 | 145 |
| 133 List<Declaration> query(Type type, QueryOptions options) { | 146 List<Declaration> query(Type type, QueryOptions options) { |
| 134 var mirror = reflectType(type); | 147 var mirror = reflectType(type); |
| 135 if (mirror is! ClassMirror) return null; | 148 if (mirror is! ClassMirror) return null; |
| 136 return _query(mirror, options); | 149 return _query(mirror, options); |
| 137 } | 150 } |
| 138 | 151 |
| 139 List<Declaration> _query(ClassMirror cls, QueryOptions options) { | 152 List<Declaration> _query(ClassMirror cls, QueryOptions options) { |
| 140 var result = (!options.includeInherited || cls.superclass == _objectType) | 153 final visitParent = options.includeInherited && cls.superclass != null && |
| 141 ? [] : _query(cls.superclass, options); | 154 // TODO(sigmund): use _toType(cls.superclass) != options.includeUpTo |
| 155 // when dartbug.com/16925 gets fixed (_toType fails in dart2js if |
| 156 // applied to classes with type-arguments). |
| 157 cls.superclass != reflectClass(options.includeUpTo); |
| 158 var result = visitParent ? _query(cls.superclass, options) : []; |
| 142 for (var member in cls.declarations.values) { | 159 for (var member in cls.declarations.values) { |
| 143 if (member is! VariableMirror && member is! MethodMirror) continue; | 160 if (member is! VariableMirror && member is! MethodMirror) continue; |
| 144 if (member.isStatic || member.isPrivate) continue; | 161 if (member.isStatic || member.isPrivate) continue; |
| 145 var name = member.simpleName; | 162 var name = member.simpleName; |
| 146 bool isMethod = false; | 163 bool isMethod = false; |
| 147 if (member is VariableMirror) { | 164 if (member is VariableMirror) { |
| 148 if (!options.includeFields) continue; | 165 if (!options.includeFields) continue; |
| 149 if (options.excludeFinal && member.isFinal) continue; | 166 if (options.excludeFinal && member.isFinal) continue; |
| 150 } | 167 } |
| 151 | 168 |
| (...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 307 // dartbug.com/16078). | 324 // dartbug.com/16078). |
| 308 // * having [call] also allows `is` checks to work for functions of 0 | 325 // * having [call] also allows `is` checks to work for functions of 0 |
| 309 // through 3 arguments. We depend on this in | 326 // through 3 arguments. We depend on this in |
| 310 // `polymer_expressions/lib/eval.dart` to check whether a function is a | 327 // `polymer_expressions/lib/eval.dart` to check whether a function is a |
| 311 // filter (takes a single argument). (Note that it's possible to include | 328 // filter (takes a single argument). (Note that it's possible to include |
| 312 // both [call] and [noSuchMethod], which would make instance-of checks | 329 // both [call] and [noSuchMethod], which would make instance-of checks |
| 313 // work with the signature of [call], but will allow invoking the function | 330 // work with the signature of [call], but will allow invoking the function |
| 314 // using [noSuchMethod]. | 331 // using [noSuchMethod]. |
| 315 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); | 332 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); |
| 316 } | 333 } |
| OLD | NEW |