| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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:_js_runtime_data' as encoding; | |
| 8 import 'dart:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 9 ALL_CLASSES, | 8 ALL_CLASSES, |
| 10 LAZIES, | 9 LAZIES, |
| 11 LIBRARIES, | 10 LIBRARIES, |
| 12 STATICS, | 11 STATICS, |
| 13 TYPE_INFORMATION; | 12 TYPE_INFORMATION, |
| 13 TYPEDEF_PREDICATE_PROPERTY_NAME, |
| 14 TYPEDEF_TYPE_PROPERTY_NAME; |
| 14 | 15 |
| 15 import 'dart:collection' show | 16 import 'dart:collection' show |
| 16 UnmodifiableListView, | 17 UnmodifiableListView, |
| 17 UnmodifiableMapView; | 18 UnmodifiableMapView; |
| 18 | 19 |
| 19 import 'dart:mirrors'; | 20 import 'dart:mirrors'; |
| 20 | 21 |
| 21 import 'dart:_foreign_helper' show | 22 import 'dart:_foreign_helper' show |
| 22 JS, | 23 JS, |
| 23 JS_CURRENT_ISOLATE, | 24 JS_CURRENT_ISOLATE, |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 // Probably an intercepted class. | 628 // Probably an intercepted class. |
| 628 // TODO(ahe): How to handle intercepted classes? | 629 // TODO(ahe): How to handle intercepted classes? |
| 629 throw new UnsupportedError('Cannot find class for: ${n(symbol)}'); | 630 throw new UnsupportedError('Cannot find class for: ${n(symbol)}'); |
| 630 } | 631 } |
| 631 var descriptor = JS('', '#["@"]', constructor); | 632 var descriptor = JS('', '#["@"]', constructor); |
| 632 var fields; | 633 var fields; |
| 633 var fieldsMetadata; | 634 var fieldsMetadata; |
| 634 if (descriptor == null) { | 635 if (descriptor == null) { |
| 635 // This is a native class, or an intercepted class. | 636 // This is a native class, or an intercepted class. |
| 636 // TODO(ahe): Preserve descriptor for such classes. | 637 // TODO(ahe): Preserve descriptor for such classes. |
| 638 } else if (JS('bool', '# in #', |
| 639 TYPEDEF_PREDICATE_PROPERTY_NAME, descriptor)) { |
| 640 // Typedefs are represented as normal classes with two special properties: |
| 641 // TYPEDEF_PREDICATE_PROPERTY_NAME and TYPEDEF_TYPE_PROPERTY_NAME. |
| 642 // For example: |
| 643 // MyTypedef: { |
| 644 // "^": "Object;", |
| 645 // $typedefType: 58, |
| 646 // $$isTypedef: true |
| 647 // } |
| 648 // The typedefType is the index into the metadata table. |
| 649 int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME); |
| 650 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); |
| 637 } else { | 651 } else { |
| 638 fields = JS('', '#[#]', descriptor, | 652 fields = JS('', '#[#]', descriptor, |
| 639 JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY')); | 653 JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY')); |
| 640 if (fields is List) { | 654 if (fields is List) { |
| 641 fieldsMetadata = fields.getRange(1, fields.length).toList(); | 655 fieldsMetadata = fields.getRange(1, fields.length).toList(); |
| 642 fields = fields[0]; | 656 fields = fields[0]; |
| 643 } | 657 } |
| 644 if (fields is! String) { | 658 if (fields is! String) { |
| 645 // TODO(ahe): This is CSP mode. Find a way to determine the | 659 // TODO(ahe): This is CSP mode. Find a way to determine the |
| 646 // fields of this class. | 660 // fields of this class. |
| 647 fields = ''; | 661 fields = ''; |
| 648 } | 662 } |
| 649 } | 663 } |
| 650 | 664 |
| 651 if (encoding.isTypedefDescriptor(fields)) { | 665 if (mirror == null) { |
| 652 int index = encoding.getTypeFromTypedef(fields); | |
| 653 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); | |
| 654 } else { | |
| 655 var superclassName = fields.split(';')[0]; | 666 var superclassName = fields.split(';')[0]; |
| 656 var mixins = superclassName.split('+'); | 667 var mixins = superclassName.split('+'); |
| 657 if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) { | 668 if (mixins.length > 1 && mangledGlobalNames[mangledName] == null) { |
| 658 mirror = reflectMixinApplication(mixins, mangledName); | 669 mirror = reflectMixinApplication(mixins, mangledName); |
| 659 } else { | 670 } else { |
| 660 ClassMirror classMirror = new JsClassMirror( | 671 ClassMirror classMirror = new JsClassMirror( |
| 661 symbol, mangledName, constructor, fields, fieldsMetadata); | 672 symbol, mangledName, constructor, fields, fieldsMetadata); |
| 662 List typeVariables = | 673 List typeVariables = |
| 663 JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor); | 674 JS('JSExtendableArray|Null', '#.prototype["<>"]', constructor); |
| 664 if (typeVariables == null || typeVariables.length == 0) { | 675 if (typeVariables == null || typeVariables.length == 0) { |
| (...skipping 2349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3014 // have a part (following a '.') that starts with '_'. | 3025 // have a part (following a '.') that starts with '_'. |
| 3015 const int UNDERSCORE = 0x5f; | 3026 const int UNDERSCORE = 0x5f; |
| 3016 if (name.isEmpty) return true; | 3027 if (name.isEmpty) return true; |
| 3017 int index = -1; | 3028 int index = -1; |
| 3018 do { | 3029 do { |
| 3019 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; | 3030 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; |
| 3020 index = name.indexOf('.', index + 1); | 3031 index = name.indexOf('.', index + 1); |
| 3021 } while (index >= 0 && index + 1 < name.length); | 3032 } while (index >= 0 && index + 1 < name.length); |
| 3022 return true; | 3033 return true; |
| 3023 } | 3034 } |
| OLD | NEW |