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