| 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 DeclarationKind get kind => isField ? FIELD : isProperty ? PROPERTY : METHOD; |
| 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 isField => _original is VariableMirror; |
| 256 bool get isMethod => !isProperty; | 254 |
| 255 bool get isProperty => |
| 256 _original is MethodMirror && !_original.isRegularMethod; |
| 257 |
| 258 bool get isMethod => !isField && !isProperty; |
| 257 | 259 |
| 258 /// If this is a property, whether it's read only (final fields or properties | 260 /// If this is a property, whether it's read only (final fields or properties |
| 259 /// with no setter). | 261 /// with no setter). |
| 260 bool get isFinal => | 262 bool get isFinal => |
| 261 (_original is VariableMirror && _original.isFinal) || | 263 (_original is VariableMirror && _original.isFinal) || |
| 262 (_original is MethodMirror && _original.isGetter && | 264 (_original is MethodMirror && _original.isGetter && |
| 263 !_hasSetter(_cls, _original)); | 265 !_hasSetter(_cls, _original)); |
| 264 | 266 |
| 265 /// If this is a property, it's declared type (including dynamic if it's not | 267 /// If this is a property, it's declared type (including dynamic if it's not |
| 266 /// declared). For methods, the returned type. | 268 /// declared). For methods, the returned type. |
| 267 Type get type { | 269 Type get type { |
| 268 if (_original is MethodMirror && _original.isRegularMethod) { | 270 if (_original is MethodMirror && _original.isRegularMethod) { |
| 269 return Function; | 271 return Function; |
| 270 } | 272 } |
| 271 var typeMirror = _original is VariableMirror ? _original.type | 273 var typeMirror = _original is VariableMirror ? _original.type |
| 272 : _original.returnType; | 274 : _original.returnType; |
| 273 return _toType(typeMirror); | 275 return _toType(typeMirror); |
| 274 } | 276 } |
| 275 | 277 |
| 276 /// Whether this symbol is static. | 278 /// Whether this symbol is static. |
| 277 bool get isStatic => _original.isStatic; | 279 bool get isStatic => _original.isStatic; |
| 278 | 280 |
| 279 /// List of annotations in this declaration. | 281 /// List of annotations in this declaration. |
| 280 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); | 282 List get annotations => _original.metadata.map((a) => a.reflectee).toList(); |
| 281 | 283 |
| 282 String toString() { | 284 String toString() { |
| 283 return (new StringBuffer() | 285 return (new StringBuffer() |
| 284 ..write('[declaration ') | 286 ..write('[declaration ') |
| 285 ..write(name) | 287 ..write(name) |
| 286 ..write(isProperty ? ' (property) ' : ' (method) ') | 288 ..write(isField ? ' (field) ' |
| 289 : (isProperty ? ' (property) ' : ' (method) ')) |
| 287 ..write(isFinal ? 'final ' : '') | 290 ..write(isFinal ? 'final ' : '') |
| 288 ..write(isStatic ? 'static ' : '') | 291 ..write(isStatic ? 'static ' : '') |
| 289 ..write(annotations) | 292 ..write(annotations) |
| 290 ..write(']')).toString(); | 293 ..write(']')).toString(); |
| 291 } | 294 } |
| 292 } | 295 } |
| 293 | 296 |
| 294 class _MethodClosure extends Function { | 297 class _MethodClosure extends Function { |
| 295 final receiver; | 298 final receiver; |
| 296 final Symbol methodName; | 299 final Symbol methodName; |
| 297 | 300 |
| 298 _MethodClosure(this.receiver, this.methodName); | 301 _MethodClosure(this.receiver, this.methodName); |
| 299 | 302 |
| 300 // Technically we could just use noSuchMethod to implement [call], but we | 303 // Technically we could just use noSuchMethod to implement [call], but we |
| 301 // don't for 3 reasons: | 304 // don't for 3 reasons: |
| 302 // * noSuchMethod makes the code a lot bigger. | 305 // * noSuchMethod makes the code a lot bigger. |
| 303 // * even with noSuchMethod, an analyzer bug requires to declare [call] (see | 306 // * even with noSuchMethod, an analyzer bug requires to declare [call] (see |
| 304 // dartbug.com/16078). | 307 // dartbug.com/16078). |
| 305 // * having [call] also allows `is` checks to work for functions of 0 | 308 // * having [call] also allows `is` checks to work for functions of 0 |
| 306 // through 3 arguments. We depend on this in | 309 // through 3 arguments. We depend on this in |
| 307 // `polymer_expressions/lib/eval.dart` to check whether a function is a | 310 // `polymer_expressions/lib/eval.dart` to check whether a function is a |
| 308 // filter (takes a single argument). (Note that it's possible to include | 311 // filter (takes a single argument). (Note that it's possible to include |
| 309 // both [call] and [noSuchMethod], which would make instance-of checks | 312 // both [call] and [noSuchMethod], which would make instance-of checks |
| 310 // work with the signature of [call], but will allow invoking the function | 313 // work with the signature of [call], but will allow invoking the function |
| 311 // using [noSuchMethod]. | 314 // using [noSuchMethod]. |
| 312 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); | 315 call([a, b, c]) => invoke(receiver, methodName, [a, b, c], adjust: true); |
| 313 } | 316 } |
| OLD | NEW |