| 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:async'; | 7 import 'dart:async'; |
| 8 import 'dart:collection' show UnmodifiableListView; | 8 import 'dart:collection' show UnmodifiableListView; |
| 9 import 'dart:mirrors'; | 9 import 'dart:mirrors'; |
| 10 | 10 |
| (...skipping 400 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 411 | 411 |
| 412 InstanceMirror reflect(Object reflectee) { | 412 InstanceMirror reflect(Object reflectee) { |
| 413 if (reflectee is Closure) { | 413 if (reflectee is Closure) { |
| 414 return new JsClosureMirror(reflectee); | 414 return new JsClosureMirror(reflectee); |
| 415 } else { | 415 } else { |
| 416 return new JsInstanceMirror(reflectee); | 416 return new JsInstanceMirror(reflectee); |
| 417 } | 417 } |
| 418 } | 418 } |
| 419 | 419 |
| 420 ClassMirror reflectType(Type key) { | 420 ClassMirror reflectType(Type key) { |
| 421 // TODO(ahe): Don't discard type arguments to support | 421 return reflectClassByMangledName(getMangledTypeName(key)); |
| 422 // [ClassMirror.isOriginalDeclaration] and [ClassMirror.originalDeclaration] | |
| 423 // correctly. | |
| 424 return reflectClassByMangledName(getMangledTypeName(key).split('<')[0]); | |
| 425 } | 422 } |
| 426 | 423 |
| 427 ClassMirror reflectClassByMangledName(String mangledName) { | 424 ClassMirror reflectClassByMangledName(String mangledName) { |
| 428 String unmangledName = mangledGlobalNames[mangledName]; | 425 String unmangledName = mangledGlobalNames[mangledName]; |
| 429 if (unmangledName == null) unmangledName = mangledName; | 426 if (unmangledName == null) unmangledName = mangledName; |
| 430 return reflectClassByName(s(unmangledName), mangledName); | 427 return reflectClassByName(s(unmangledName), mangledName); |
| 431 } | 428 } |
| 432 | 429 |
| 433 var classMirrors; | 430 var classMirrors; |
| 434 | 431 |
| 435 ClassMirror reflectClassByName(Symbol symbol, String mangledName) { | 432 ClassMirror reflectClassByName(Symbol symbol, String mangledName) { |
| 436 if (classMirrors == null) classMirrors = JsCache.allocate(); | 433 if (classMirrors == null) classMirrors = JsCache.allocate(); |
| 437 var mirror = JsCache.fetch(classMirrors, mangledName); | 434 var mirror = JsCache.fetch(classMirrors, mangledName); |
| 438 if (mirror != null) return mirror; | 435 if (mirror != null) return mirror; |
| 439 disableTreeShaking(); | 436 disableTreeShaking(); |
| 437 int typeArgIndex = mangledName.indexOf("<"); |
| 438 if (typeArgIndex != -1) { |
| 439 mirror = new JsTypeBoundClassMirror( |
| 440 reflectClassByMangledName(mangledName.substring(0, typeArgIndex)), |
| 441 // Remove the angle brackets enclosing the type arguments. |
| 442 mangledName.substring(typeArgIndex + 1, mangledName.length - 1)); |
| 443 JsCache.update(classMirrors, mangledName, mirror); |
| 444 return mirror; |
| 445 } |
| 440 var constructorOrInterceptor = | 446 var constructorOrInterceptor = |
| 441 Primitives.getConstructorOrInterceptor(mangledName); | 447 Primitives.getConstructorOrInterceptor(mangledName); |
| 442 if (constructorOrInterceptor == null) { | 448 if (constructorOrInterceptor == null) { |
| 443 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); | 449 int index = JS('int|Null', 'init.functionAliases[#]', mangledName); |
| 444 if (index != null) { | 450 if (index != null) { |
| 445 mirror = new JsTypedefMirror( | 451 mirror = new JsTypedefMirror( |
| 446 symbol, mangledName, JS('=Object', 'init.metadata[#]', index)); | 452 symbol, mangledName, JS('=Object', 'init.metadata[#]', index)); |
| 447 JsCache.update(classMirrors, mangledName, mirror); | 453 JsCache.update(classMirrors, mangledName, mirror); |
| 448 return mirror; | 454 return mirror; |
| 449 } | 455 } |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 574 [Map<Symbol, dynamic> namedArguments]) { | 580 [Map<Symbol, dynamic> namedArguments]) { |
| 575 return new Future<InstanceMirror>( | 581 return new Future<InstanceMirror>( |
| 576 () => this.newInstance( | 582 () => this.newInstance( |
| 577 constructorName, positionalArguments, namedArguments)); | 583 constructorName, positionalArguments, namedArguments)); |
| 578 } | 584 } |
| 579 | 585 |
| 580 bool get isOriginalDeclaration => true; | 586 bool get isOriginalDeclaration => true; |
| 581 | 587 |
| 582 ClassMirror get originalDeclaration => this; | 588 ClassMirror get originalDeclaration => this; |
| 583 | 589 |
| 584 // TODO(ahe): Implement these. | 590 // TODO(ahe): Implement this. |
| 585 Map<Symbol, TypeVariableMirror> get typeVariables { | 591 List<TypeVariableMirror> get typeVariables { |
| 586 throw new UnimplementedError(); | 592 throw new UnimplementedError(); |
| 587 } | 593 } |
| 588 Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); | 594 |
| 595 List<TypeMirror> get typeArguments => new List(); |
| 589 } | 596 } |
| 590 | 597 |
| 591 abstract class JsObjectMirror implements ObjectMirror { | 598 abstract class JsObjectMirror implements ObjectMirror { |
| 592 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { | 599 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { |
| 593 return new Future<InstanceMirror>(() => this.setField(fieldName, value)); | 600 return new Future<InstanceMirror>(() => this.setField(fieldName, value)); |
| 594 } | 601 } |
| 595 | 602 |
| 596 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { | 603 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { |
| 597 return new Future<InstanceMirror>(() => this.getField(fieldName)); | 604 return new Future<InstanceMirror>(() => this.getField(fieldName)); |
| 598 } | 605 } |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 702 return other is JsInstanceMirror && | 709 return other is JsInstanceMirror && |
| 703 identical(reflectee, other.reflectee); | 710 identical(reflectee, other.reflectee); |
| 704 } | 711 } |
| 705 | 712 |
| 706 int get hashCode { | 713 int get hashCode { |
| 707 // If the reflectee is a built-in type, use the base-level hashCode to | 714 // If the reflectee is a built-in type, use the base-level hashCode to |
| 708 // preserve the illusion that, e.g. doubles, with the same value are | 715 // preserve the illusion that, e.g. doubles, with the same value are |
| 709 // identical. Otherwise, use the primitive identity hash to maintain | 716 // identical. Otherwise, use the primitive identity hash to maintain |
| 710 // correctness even if a user-defined hashCode returns different values for | 717 // correctness even if a user-defined hashCode returns different values for |
| 711 // successive invocations. | 718 // successive invocations. |
| 712 var h = ((JS('bool', 'typeof # != "object"', reflectee)) || | 719 var h = ((JS('bool', 'typeof # != "object"', reflectee)) || |
| 713 (reflectee == null)) | 720 (reflectee == null)) |
| 714 ? reflectee.hashCode | 721 ? reflectee.hashCode |
| 715 : Primitives.objectHashCode(reflectee); | 722 : Primitives.objectHashCode(reflectee); |
| 716 // Avoid hash collisions with the reflectee. This constant is in Smi range | 723 // Avoid hash collisions with the reflectee. This constant is in Smi range |
| 717 // and happens to be the inner padding from RFC 2104. | 724 // and happens to be the inner padding from RFC 2104. |
| 718 return h ^ 0x36363636; | 725 return h ^ 0x36363636; |
| 719 } | 726 } |
| 720 | 727 |
| 721 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}'; | 728 String toString() => 'InstanceMirror on ${Error.safeToString(reflectee)}'; |
| 722 | 729 |
| 723 // TODO(ahe): Remove this method from the API. | 730 // TODO(ahe): Remove this method from the API. |
| 724 MirrorSystem get mirrors => currentJsMirrorSystem; | 731 MirrorSystem get mirrors => currentJsMirrorSystem; |
| 725 } | 732 } |
| 726 | 733 |
| 734 /** |
| 735 * ClassMirror for generic classes where the type parameters are bound. |
| 736 * |
| 737 * [typeArguments] will return a list of the type arguments, in constrast |
| 738 * to JsCLassMirror that returns an empty list since it represents original |
| 739 * declarations and classes that are not generic. |
| 740 */ |
| 741 class JsTypeBoundClassMirror implements ClassMirror { |
| 742 final JsClassMirror _class; |
| 743 |
| 744 /** |
| 745 * When instantiated this field will hold a string representing the list of |
| 746 * type arguments for the class, i.e. what is inside the outermost angle |
| 747 * brackets. Then, when get typeArguments is called the first time, the string |
| 748 * is parsed into the actual list of TypeMirrors, and the field is overridden |
| 749 * with this value. |
| 750 */ |
| 751 var _typeArgs; |
| 752 |
| 753 JsTypeBoundClassMirror(this._class, this._typeArgs); |
| 754 |
| 755 List<TypeVariableMirror> get typeVariables => _class.typeVariables; |
| 756 |
| 757 List<TypeMirror> get typeArguments { |
| 758 if (_typeArgs is! String) return _typeArgs; |
| 759 List result = new List(); |
| 760 if (_typeArgs.indexOf('<') == -1) { |
| 761 for (String s in _typeArgs.split(',')) { |
| 762 result.add(reflectClassByMangledName(s.trim())); |
| 763 } |
| 764 } else { |
| 765 int level = 0; |
| 766 StringBuffer currentTypeArg = new StringBuffer(); |
| 767 |
| 768 addCurrentTypeArg() { |
| 769 var classMirror = reflectClassByMangledName(currentTypeArg.toString()); |
| 770 result.add(classMirror); |
| 771 currentTypeArg.clear(); |
| 772 } |
| 773 |
| 774 for (int i = 0; i < _typeArgs.length; i++) { |
| 775 var character = _typeArgs[i]; |
| 776 if (character == ' ') { |
| 777 continue; |
| 778 } else if (character == '<') { |
| 779 currentTypeArg.write(character); |
| 780 level++; |
| 781 } else if (character == '>') { |
| 782 currentTypeArg.write(character); |
| 783 level--; |
| 784 } else if (character == ',') { |
| 785 if (level > 0) { |
| 786 currentTypeArg.write(character); |
| 787 } else { |
| 788 addCurrentTypeArg(); |
| 789 } |
| 790 } else { |
| 791 currentTypeArg.write(character); |
| 792 } |
| 793 } |
| 794 addCurrentTypeArg(); |
| 795 } |
| 796 return _typeArgs = new UnmodifiableListView(result); |
| 797 } |
| 798 |
| 799 Map<Symbol, MethodMirror> get constructors => _class.constructors; |
| 800 |
| 801 Map<Symbol, MethodMirror> get methods => _class.methods; |
| 802 |
| 803 Map<Symbol, MethodMirror> get getters => _class.getters; |
| 804 |
| 805 Map<Symbol, MethodMirror> get setters => _class.setters; |
| 806 |
| 807 Map<Symbol, VariableMirror> get variables => _class.variables; |
| 808 |
| 809 Map<Symbol, Mirror> get members => _class.members; |
| 810 |
| 811 InstanceMirror setField(Symbol fieldName, Object arg) { |
| 812 return _class.setField(fieldName, arg); |
| 813 } |
| 814 |
| 815 InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName); |
| 816 |
| 817 InstanceMirror newInstance(Symbol constructorName, |
| 818 List positionalArguments, |
| 819 [Map<Symbol, dynamic> namedArguments]) { |
| 820 return _class.newInstance(constructorName, |
| 821 positionalArguments, |
| 822 namedArguments); |
| 823 } |
| 824 |
| 825 Future<InstanceMirror> newInstanceAsync( |
| 826 Symbol constructorName, |
| 827 List positionalArguments, |
| 828 [Map<Symbol, dynamic> namedArguments]) { |
| 829 return _class.newInstanceAsync(constructorName, |
| 830 positionalArguments, |
| 831 namedArguments); |
| 832 } |
| 833 |
| 834 JsLibraryMirror get owner => _class.owner; |
| 835 |
| 836 List<InstanceMirror> get metadata => _class.metadata; |
| 837 |
| 838 ClassMirror get superclass => _class.superclass; |
| 839 |
| 840 InstanceMirror invoke(Symbol memberName, |
| 841 List positionalArguments, |
| 842 [Map<Symbol,dynamic> namedArguments]) { |
| 843 return _class.invoke(memberName, positionalArguments, namedArguments); |
| 844 } |
| 845 |
| 846 bool get isOriginalDeclaration => false; |
| 847 |
| 848 ClassMirror get originalDeclaration => _class; |
| 849 |
| 850 List<ClassMirror> get superinterfaces => _class.superinterfaces; |
| 851 |
| 852 Future<InstanceMirror> getFieldAsync(Symbol fieldName) { |
| 853 return _class.getFieldAsync(fieldName); |
| 854 } |
| 855 |
| 856 bool get hasReflectedType => _class.hasReflectedType; |
| 857 |
| 858 Future<InstanceMirror> invokeAsync(Symbol memberName, |
| 859 List positionalArguments, |
| 860 [Map<Symbol, dynamic> namedArguments]) { |
| 861 return _class.invokeAsync(memberName, positionalArguments, namedArguments); |
| 862 } |
| 863 |
| 864 bool get isPrivate => _class.isPrivate; |
| 865 |
| 866 bool get isTopLevel => _class.isTopLevel; |
| 867 |
| 868 SourceLocation get location => _class.location; |
| 869 |
| 870 MirrorSystem get mirrors => _class.mirrors; |
| 871 |
| 872 Symbol get qualifiedName => _class.qualifiedName; |
| 873 |
| 874 Type get reflectedType => _class.reflectedType; |
| 875 |
| 876 Future<InstanceMirror> setFieldAsync(Symbol fieldName, Object value) { |
| 877 return _class.setFieldAsync(fieldName, value); |
| 878 } |
| 879 |
| 880 Symbol get simpleName => _class.simpleName; |
| 881 } |
| 882 |
| 727 class JsClassMirror extends JsTypeMirror with JsObjectMirror | 883 class JsClassMirror extends JsTypeMirror with JsObjectMirror |
| 728 implements ClassMirror { | 884 implements ClassMirror { |
| 729 final String _mangledName; | 885 final String _mangledName; |
| 730 final _jsConstructorOrInterceptor; | 886 final _jsConstructorOrInterceptor; |
| 731 final String _fieldsDescriptor; | 887 final String _fieldsDescriptor; |
| 732 final List _fieldsMetadata; | 888 final List _fieldsMetadata; |
| 733 final _jsConstructorCache = JsCache.allocate(); | 889 final _jsConstructorCache = JsCache.allocate(); |
| 734 List _metadata; | 890 List _metadata; |
| 735 ClassMirror _superclass; | 891 ClassMirror _superclass; |
| 736 List<JsMethodMirror> _cachedMethods; | 892 List<JsMethodMirror> _cachedMethods; |
| (...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1081 var type = JS('=Object', 'init.metadata[#]', i); | 1237 var type = JS('=Object', 'init.metadata[#]', i); |
| 1082 return typeMirrorFromRuntimeTypeRepresentation(type); | 1238 return typeMirrorFromRuntimeTypeRepresentation(type); |
| 1083 } | 1239 } |
| 1084 result = interfaces.map(lookupType).toList(); | 1240 result = interfaces.map(lookupType).toList(); |
| 1085 } | 1241 } |
| 1086 return _cachedSuperinterfaces = | 1242 return _cachedSuperinterfaces = |
| 1087 new UnmodifiableListView<ClassMirror>(result); | 1243 new UnmodifiableListView<ClassMirror>(result); |
| 1088 } | 1244 } |
| 1089 | 1245 |
| 1090 // TODO(ahe): Implement these. | 1246 // TODO(ahe): Implement these. |
| 1091 Map<Symbol, TypeVariableMirror> get typeVariables | 1247 List<TypeVariableMirror> get typeVariables |
| 1092 => throw new UnimplementedError(); | 1248 => throw new UnimplementedError(); |
| 1093 Map<Symbol, TypeMirror> get typeArguments => throw new UnimplementedError(); | 1249 List<TypeMirror> get typeArguments => new List(); |
| 1094 } | 1250 } |
| 1095 | 1251 |
| 1096 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { | 1252 class JsVariableMirror extends JsDeclarationMirror implements VariableMirror { |
| 1097 static final int REFLECTION_MARKER = 45; | 1253 static final int REFLECTION_MARKER = 45; |
| 1098 | 1254 |
| 1099 // TODO(ahe): The values in these fields are virtually untested. | 1255 // TODO(ahe): The values in these fields are virtually untested. |
| 1100 final String _jsName; | 1256 final String _jsName; |
| 1101 final bool isFinal; | 1257 final bool isFinal; |
| 1102 final bool isStatic; | 1258 final bool isStatic; |
| 1103 final _metadataFunction; | 1259 final _metadataFunction; |
| (...skipping 349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1453 final String _mangledName; | 1609 final String _mangledName; |
| 1454 final JsFunctionTypeMirror referent; | 1610 final JsFunctionTypeMirror referent; |
| 1455 | 1611 |
| 1456 JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData) | 1612 JsTypedefMirror(Symbol simpleName, this._mangledName, _typeData) |
| 1457 : referent = new JsFunctionTypeMirror(_typeData), | 1613 : referent = new JsFunctionTypeMirror(_typeData), |
| 1458 super(simpleName); | 1614 super(simpleName); |
| 1459 | 1615 |
| 1460 JsFunctionTypeMirror get value => referent; | 1616 JsFunctionTypeMirror get value => referent; |
| 1461 | 1617 |
| 1462 String get _prettyName => 'TypedefMirror'; | 1618 String get _prettyName => 'TypedefMirror'; |
| 1619 |
| 1620 // TODO(zarah): This method doesn't belong here, since TypedefMirror shouldn't |
| 1621 // be a subtype of ClassMirror. |
| 1622 ClassMirror get originalDeclaration => this; |
| 1463 } | 1623 } |
| 1464 | 1624 |
| 1465 class JsFunctionTypeMirror implements FunctionTypeMirror { | 1625 class JsFunctionTypeMirror implements FunctionTypeMirror { |
| 1466 final _typeData; | 1626 final _typeData; |
| 1467 String _cachedToString; | 1627 String _cachedToString; |
| 1468 TypeMirror _cachedReturnType; | 1628 TypeMirror _cachedReturnType; |
| 1469 UnmodifiableListView<ParameterMirror> _cachedParameters; | 1629 UnmodifiableListView<ParameterMirror> _cachedParameters; |
| 1470 | 1630 |
| 1471 JsFunctionTypeMirror(this._typeData); | 1631 JsFunctionTypeMirror(this._typeData); |
| 1472 | 1632 |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1684 void operator []=(K key, V value) => _throw(); | 1844 void operator []=(K key, V value) => _throw(); |
| 1685 | 1845 |
| 1686 V putIfAbsent(K key, V ifAbsent()) { _throw(); } | 1846 V putIfAbsent(K key, V ifAbsent()) { _throw(); } |
| 1687 | 1847 |
| 1688 void addAll(Map<K, V> other) => _throw(); | 1848 void addAll(Map<K, V> other) => _throw(); |
| 1689 | 1849 |
| 1690 V remove(K key) { _throw(); } | 1850 V remove(K key) { _throw(); } |
| 1691 | 1851 |
| 1692 void clear() => _throw(); | 1852 void clear() => _throw(); |
| 1693 } | 1853 } |
| OLD | NEW |