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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
138 | 138 |
139 List<Declaration> _query(ClassMirror cls, QueryOptions options) { | 139 List<Declaration> _query(ClassMirror cls, QueryOptions options) { |
140 var result = (!options.includeInherited || cls.superclass == _objectType) | 140 var result = (!options.includeInherited || cls.superclass == _objectType) |
141 ? [] : _query(cls.superclass, options); | 141 ? [] : _query(cls.superclass, options); |
142 for (var member in cls.declarations.values) { | 142 for (var member in cls.declarations.values) { |
143 if (member is! VariableMirror && member is! MethodMirror) continue; | 143 if (member is! VariableMirror && member is! MethodMirror) continue; |
144 if (member.isStatic || member.isPrivate) continue; | 144 if (member.isStatic || member.isPrivate) continue; |
145 var name = member.simpleName; | 145 var name = member.simpleName; |
146 bool isMethod = false; | 146 bool isMethod = false; |
147 if (member is VariableMirror) { | 147 if (member is VariableMirror) { |
148 if (!options.includeProperties) continue; | 148 if (!options.includeFields) continue; |
149 if (options.excludeFinal && member.isFinal) continue; | 149 if (options.excludeFinal && member.isFinal) continue; |
150 } | 150 } |
151 | 151 |
152 // TODO(sigmund): what if we have a setter but no getter? | 152 // TODO(sigmund): what if we have a setter but no getter? |
153 if (member is MethodMirror && member.isSetter) continue; | 153 if (member is MethodMirror && member.isSetter) continue; |
154 if (member is MethodMirror && member.isConstructor) continue; | 154 if (member is MethodMirror && member.isConstructor) continue; |
155 | 155 |
156 if (member is MethodMirror && member.isGetter) { | 156 if (member is MethodMirror && member.isGetter) { |
157 if (!options.includeProperties) continue; | 157 if (!options.includeProperties) continue; |
158 if (options.excludeFinal && !_hasSetter(cls, member)) continue; | 158 if (options.excludeFinal && !_hasSetter(cls, member)) continue; |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
241 } | 241 } |
242 | 242 |
243 class _MirrorDeclaration implements Declaration { | 243 class _MirrorDeclaration implements Declaration { |
244 final ClassMirror _cls; | 244 final ClassMirror _cls; |
245 final _original; | 245 final _original; |
246 | 246 |
247 _MirrorDeclaration(this._cls, DeclarationMirror this._original); | 247 _MirrorDeclaration(this._cls, DeclarationMirror this._original); |
248 | 248 |
249 Symbol get name => _original.simpleName; | 249 Symbol get name => _original.simpleName; |
250 | 250 |
251 /// Whether the symbol is a property (either this or [isMethod] is true). | 251 bool get isField => _original is VariableMirror; |
252 bool get isProperty => _original is VariableMirror || | |
253 (_original is MethodMirror && !_original.isRegularMethod); | |
254 | 252 |
255 /// Whether the symbol is a method (either this or [isProperty] is true) | 253 bool get isProperty => |
256 bool get isMethod => !isProperty; | 254 _original is MethodMirror && !_original.isRegularMethod; |
| 255 |
| 256 bool get isMethod => !isField && !isProperty; |
257 | 257 |
258 /// If this is a property, whether it's read only (final fields or properties | 258 /// If this is a property, whether it's read only (final fields or properties |
259 /// with no setter). | 259 /// with no setter). |
260 bool get isFinal => | 260 bool get isFinal => |
261 (_original is VariableMirror && _original.isFinal) || | 261 (_original is VariableMirror && _original.isFinal) || |
262 (_original is MethodMirror && _original.isGetter && | 262 (_original is MethodMirror && _original.isGetter && |
263 !_hasSetter(_cls, _original)); | 263 !_hasSetter(_cls, _original)); |
264 | 264 |
265 /// If this is a property, it's declared type (including dynamic if it's not | 265 /// If this is a property, it's declared type (including dynamic if it's not |
266 /// declared). For methods, the returned type. | 266 /// declared). For methods, the returned type. |
267 Type get type { | 267 Type get type { |
268 if (_original is MethodMirror && _original.isRegularMethod) { | 268 if (_original is MethodMirror && _original.isRegularMethod) { |
269 return Function; | 269 return Function; |
270 } | 270 } |
271 var typeMirror = _original is VariableMirror ? _original.type | 271 var typeMirror = _original is VariableMirror ? _original.type |
272 : _original.returnType; | 272 : _original.returnType; |
273 return _toType(typeMirror); | 273 return _toType(typeMirror); |
274 } | 274 } |
275 | 275 |
276 /// Whether this symbol is static. | 276 /// Whether this symbol is static. |
277 bool get isStatic => _original.isStatic; | 277 bool get isStatic => _original.isStatic; |
278 | 278 |
279 /// List of annotations in this declaration. | 279 /// List of annotations in this declaration. |
280 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); | 280 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); |
281 | 281 |
282 String toString() { | 282 String toString() { |
283 return (new StringBuffer() | 283 return (new StringBuffer() |
284 ..write('[declaration ') | 284 ..write('[declaration ') |
285 ..write(name) | 285 ..write(name) |
286 ..write(isProperty ? ' (property) ' : ' (method) ') | 286 ..write(isField ? ' (field) ' |
| 287 : (isProperty ? ' (property) ' : ' (method) ')) |
287 ..write(isFinal ? 'final ' : '') | 288 ..write(isFinal ? 'final ' : '') |
288 ..write(isStatic ? 'static ' : '') | 289 ..write(isStatic ? 'static ' : '') |
289 ..write(annotations) | 290 ..write(annotations) |
290 ..write(']')).toString(); | 291 ..write(']')).toString(); |
291 } | 292 } |
292 } | 293 } |
293 | 294 |
294 class _MethodClosure extends Function { | 295 class _MethodClosure extends Function { |
295 final receiver; | 296 final receiver; |
296 final Symbol methodName; | 297 final Symbol methodName; |
297 | 298 |
298 _MethodClosure(this.receiver, this.methodName); | 299 _MethodClosure(this.receiver, this.methodName); |
299 | 300 |
300 // We shouldn't need to include [call] here, but we do to work around an | 301 // We shouldn't need to include [call] here, but we do to work around an |
301 // analyzer bug (see dartbug.com/16078). Interestingly, if [call] is invoked | 302 // analyzer bug (see dartbug.com/16078). Interestingly, if [call] is invoked |
302 // with the wrong number of arguments, then noSuchMethod is anyways invoked | 303 // with the wrong number of arguments, then noSuchMethod is anyways invoked |
303 // instead. | 304 // instead. |
304 call() => invoke(receiver, methodName, const []); | 305 call() => invoke(receiver, methodName, const []); |
305 | 306 |
306 noSuchMethod(Invocation inv) { | 307 noSuchMethod(Invocation inv) { |
307 if (inv.memberName != #call) return null; | 308 if (inv.memberName != #call) return null; |
308 return invoke(receiver, methodName, | 309 return invoke(receiver, methodName, |
309 inv.positionalArguments, namedArgs: inv.namedArguments); | 310 inv.positionalArguments, namedArgs: inv.namedArguments); |
310 } | 311 } |
311 } | 312 } |
OLD | NEW |