OLD | NEW |
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library dart._js_mirrors; | 5 library dart._js_mirrors; |
6 | 6 |
7 import 'dart:mirrors'; | 7 import 'dart:mirrors'; |
8 import 'dart:_foreign_helper' show JS; | 8 import 'dart:_foreign_helper' show JS; |
9 import 'dart:_internal' as _internal; | 9 import 'dart:_internal' as _internal; |
10 | 10 |
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 // TODO(vsm): Do this properly | 274 // TODO(vsm): Do this properly |
275 final ClassMirror mixin = null; | 275 final ClassMirror mixin = null; |
276 List<TypeMirror> _typeArguments; | 276 List<TypeMirror> _typeArguments; |
277 | 277 |
278 List<InstanceMirror> _metadata; | 278 List<InstanceMirror> _metadata; |
279 Map<Symbol, DeclarationMirror> _declarations; | 279 Map<Symbol, DeclarationMirror> _declarations; |
280 | 280 |
281 List<InstanceMirror> get metadata { | 281 List<InstanceMirror> get metadata { |
282 if (_metadata == null) { | 282 if (_metadata == null) { |
283 // Load metadata. | 283 // Load metadata. |
284 var fn = JS('Function', '#[dart.metadata]', _unwrap(_cls)); | 284 var unwrapped = _unwrap(_cls); |
| 285 // Only get metadata directly embedded on this class, not its |
| 286 // superclasses. |
| 287 var fn = JS('Function', |
| 288 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null'
, |
| 289 unwrapped, unwrapped); |
285 _metadata = (fn == null) | 290 _metadata = (fn == null) |
286 ? const <InstanceMirror>[] | 291 ? const <InstanceMirror>[] |
287 : new List<InstanceMirror>.unmodifiable( | 292 : new List<InstanceMirror>.unmodifiable( |
288 fn().map((i) => reflect(i))); | 293 fn().map((i) => reflect(i))); |
289 } | 294 } |
290 return _metadata; | 295 return _metadata; |
291 } | 296 } |
292 | 297 |
293 Map<Symbol, DeclarationMirror> get declarations { | 298 Map<Symbol, DeclarationMirror> get declarations { |
294 if (_declarations == null) { | 299 if (_declarations == null) { |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 List<ParameterMirror> get parameters => _params; | 518 List<ParameterMirror> get parameters => _params; |
514 List<InstanceMirror> get metadata => _metadata; | 519 List<InstanceMirror> get metadata => _metadata; |
515 | 520 |
516 void _createParameterMirrorList(ftype) { | 521 void _createParameterMirrorList(ftype) { |
517 if (ftype == null) { | 522 if (ftype == null) { |
518 // TODO(vsm): No explicit constructor. Verify this. | 523 // TODO(vsm): No explicit constructor. Verify this. |
519 _params = const []; | 524 _params = const []; |
520 _metadata = const []; | 525 _metadata = const []; |
521 return; | 526 return; |
522 } | 527 } |
523 if (ftype is List) { | 528 |
| 529 // TODO(vsm): Why does generic function type trigger true for List? |
| 530 if (ftype is! Function && ftype is List) { |
524 // Record metadata | 531 // Record metadata |
525 _metadata = new List<InstanceMirror>.unmodifiable( | 532 _metadata = new List<InstanceMirror>.unmodifiable( |
526 ftype.skip(1).map((a) => reflect(a))); | 533 ftype.skip(1).map((a) => reflect(a))); |
527 ftype = ftype[0]; | 534 ftype = ftype[0]; |
528 } else { | 535 } else { |
529 _metadata = const []; | 536 _metadata = const []; |
530 } | 537 } |
531 | 538 |
| 539 // TODO(vsm): Handle generic function types properly. Or deprecate mirrors |
| 540 // before we need to! |
| 541 if (JS('bool', 'typeof(#) == "function"', ftype)) { |
| 542 // Instantiate the generic version. |
| 543 // TODO(vsm): Can't use arguments.length on arrow function. |
| 544 ftype = JS('', '#.apply(null, #)', ftype, [dynamic, dynamic, dynamic]); |
| 545 } |
| 546 |
532 // TODO(vsm): Add named args. | 547 // TODO(vsm): Add named args. |
533 List args = ftype.args; | 548 List args = ftype.args; |
534 List opts = ftype.optionals; | 549 List opts = ftype.optionals; |
535 var params = new List<ParameterMirror>(args.length + opts.length); | 550 var params = new List<ParameterMirror>(args.length + opts.length); |
536 | 551 |
537 for (var i = 0; i < args.length; ++i) { | 552 for (var i = 0; i < args.length; ++i) { |
538 var type = args[i]; | 553 var type = args[i]; |
539 var metadata = ftype.metadata[i]; | 554 var metadata = ftype.metadata[i]; |
540 // TODO(vsm): Recover the param name. | 555 // TODO(vsm): Recover the param name. |
541 var param = new JsParameterMirror._('', _wrap(type), metadata); | 556 var param = new JsParameterMirror._('', _wrap(type), metadata); |
542 params[i] = param; | 557 params[i] = param; |
543 } | 558 } |
544 | 559 |
545 for (var i = 0; i < opts.length; ++i) { | 560 for (var i = 0; i < opts.length; ++i) { |
546 var type = opts[i]; | 561 var type = opts[i]; |
547 var metadata = ftype.metadata[args.length + i]; | 562 var metadata = ftype.metadata[args.length + i]; |
548 // TODO(vsm): Recover the param name. | 563 // TODO(vsm): Recover the param name. |
549 var param = new JsParameterMirror._('', _wrap(type), metadata); | 564 var param = new JsParameterMirror._('', _wrap(type), metadata); |
550 params[i + args.length] = param; | 565 params[i + args.length] = param; |
551 } | 566 } |
552 | 567 |
553 _params = new List.unmodifiable(params); | 568 _params = new List.unmodifiable(params); |
554 } | 569 } |
555 | 570 |
556 String toString() => "MethodMirror on '$_name'"; | 571 String toString() => "MethodMirror on '$_name'"; |
557 } | 572 } |
OLD | NEW |