| 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 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 | 197 |
| 198 int get hashCode { | 198 int get hashCode { |
| 199 int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode; | 199 int code = 0x3FFFFFFF & (JsTypeVariableMirror).hashCode; |
| 200 code ^= 17 * simpleName.hashCode; | 200 code ^= 17 * simpleName.hashCode; |
| 201 code ^= 19 * owner.hashCode; | 201 code ^= 19 * owner.hashCode; |
| 202 return code; | 202 return code; |
| 203 } | 203 } |
| 204 | 204 |
| 205 String get _prettyName => 'TypeVariableMirror'; | 205 String get _prettyName => 'TypeVariableMirror'; |
| 206 | 206 |
| 207 bool get isTopLevel => false; |
| 208 |
| 207 TypeMirror get upperBound { | 209 TypeMirror get upperBound { |
| 208 if (_cachedUpperBound != null) return _cachedUpperBound; | 210 if (_cachedUpperBound != null) return _cachedUpperBound; |
| 209 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( | 211 return _cachedUpperBound = typeMirrorFromRuntimeTypeRepresentation( |
| 210 owner, getMetadata(_typeVariable.bound)); | 212 owner, getMetadata(_typeVariable.bound)); |
| 211 } | 213 } |
| 212 } | 214 } |
| 213 | 215 |
| 214 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror { | 216 class JsTypeMirror extends JsDeclarationMirror implements TypeMirror { |
| 215 JsTypeMirror(Symbol simpleName) | 217 JsTypeMirror(Symbol simpleName) |
| 216 : super(simpleName); | 218 : super(simpleName); |
| (...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 548 Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) { | 550 Map<Symbol, MethodMirror> filterMethods(List<MethodMirror> methods) { |
| 549 var result = new Map(); | 551 var result = new Map(); |
| 550 for (JsMethodMirror method in methods) { | 552 for (JsMethodMirror method in methods) { |
| 551 if (!method.isConstructor && !method.isGetter && !method.isSetter) { | 553 if (!method.isConstructor && !method.isGetter && !method.isSetter) { |
| 552 result[method.simpleName] = method; | 554 result[method.simpleName] = method; |
| 553 } | 555 } |
| 554 } | 556 } |
| 555 return result; | 557 return result; |
| 556 } | 558 } |
| 557 | 559 |
| 560 Map<Symbol, MethodMirror> filterConstructors(methods) { |
| 561 var result = new Map(); |
| 562 for (JsMethodMirror method in methods) { |
| 563 if (method.isConstructor) { |
| 564 result[method.simpleName] = method; |
| 565 } |
| 566 } |
| 567 return result; |
| 568 } |
| 569 |
| 558 Map<Symbol, MethodMirror> filterGetters(List<MethodMirror> methods, | 570 Map<Symbol, MethodMirror> filterGetters(List<MethodMirror> methods, |
| 559 Map<Symbol, VariableMirror> fields) { | 571 Map<Symbol, VariableMirror> fields) { |
| 560 var result = new Map(); | 572 var result = new Map(); |
| 561 for (JsMethodMirror method in methods) { | 573 for (JsMethodMirror method in methods) { |
| 562 if (method.isGetter) { | 574 if (method.isGetter) { |
| 563 | 575 |
| 564 // TODO(ahe): This is a hack to remove getters corresponding to a field. | 576 // TODO(ahe): This is a hack to remove getters corresponding to a field. |
| 565 if (fields[method.simpleName] != null) continue; | 577 if (fields[method.simpleName] != null) continue; |
| 566 | 578 |
| 567 result[method.simpleName] = method; | 579 result[method.simpleName] = method; |
| 568 } | 580 } |
| 569 } | 581 } |
| 570 return result; | 582 return result; |
| 571 } | 583 } |
| 572 | 584 |
| 573 Map<Symbol, MethodMirror> filterSetters(List<MethodMirror> methods, | 585 Map<Symbol, MethodMirror> filterSetters(List<MethodMirror> methods, |
| 574 Map<Symbol, VariableMirror> fields) { | 586 Map<Symbol, VariableMirror> fields) { |
| 575 var result = new Map(); | 587 var result = new Map(); |
| 576 for (JsMethodMirror method in methods) { | 588 for (JsMethodMirror method in methods) { |
| 577 if (method.isSetter) { | 589 if (method.isSetter) { |
| 578 | 590 |
| 579 // TODO(ahe): This is a hack to remove setters corresponding to a field. | 591 // TODO(ahe): This is a hack to remove setters corresponding to a field. |
| 580 String name = n(method.simpleName); | 592 String name = n(method.simpleName); |
| 581 name = name.substring(0, name.length - 1); // Remove '='. | 593 name = name.substring(0, name.length - 1); // Remove '='. |
| 582 if (fields[s(name)] != null) continue; | 594 if (fields[s(name)] != null) continue; |
| 583 | 595 |
| 584 result[method.simpleName] = method; | 596 result[method.simpleName] = method; |
| 585 } | 597 } |
| 586 } | 598 } |
| 587 return result; | 599 return result; |
| 588 } | 600 } |
| 589 | 601 |
| 602 Map<Symbol, Mirror> filterMembers(List<MethodMirror> methods, |
| 603 Map<Symbol, VariableMirror> variables) { |
| 604 Map<Symbol, Mirror> result = new Map.from(variables); |
| 605 for (JsMethodMirror method in methods) { |
| 606 if (method.isSetter) { |
| 607 String name = n(method.simpleName); |
| 608 name = name.substring(0, name.length - 1); |
| 609 // Filter-out setters corresponding to variables. |
| 610 if (result[s(name)] is VariableMirror) continue; |
| 611 } |
| 612 // Constructors aren't 'members'. |
| 613 if (method.isConstructor) continue; |
| 614 // Use putIfAbsent to filter-out getters corresponding to variables. |
| 615 result.putIfAbsent(method.simpleName, () => method); |
| 616 } |
| 617 return result; |
| 618 } |
| 619 |
| 590 int counter = 0; | 620 int counter = 0; |
| 591 | 621 |
| 592 ClassMirror reflectMixinApplication(mixinNames, String mangledName) { | 622 ClassMirror reflectMixinApplication(mixinNames, String mangledName) { |
| 593 disableTreeShaking(); | 623 disableTreeShaking(); |
| 594 var mixins = []; | 624 var mixins = []; |
| 595 for (String mangledName in mixinNames) { | 625 for (String mangledName in mixinNames) { |
| 596 mixins.add(reflectClassByMangledName(mangledName)); | 626 mixins.add(reflectClassByMangledName(mangledName)); |
| 597 } | 627 } |
| 598 var it = mixins.iterator; | 628 var it = mixins.iterator; |
| 599 it.moveNext(); | 629 it.moveNext(); |
| (...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 854 * [_cachedTypeArguments]. Due to type substitution of, for instance, | 884 * [_cachedTypeArguments]. Due to type substitution of, for instance, |
| 855 * superclasses the mangled name of the class and hence this string is needed | 885 * superclasses the mangled name of the class and hence this string is needed |
| 856 * after [_cachedTypeArguments] has been computed. | 886 * after [_cachedTypeArguments] has been computed. |
| 857 * | 887 * |
| 858 * If an integer is encountered as a type argument, it represents the type | 888 * If an integer is encountered as a type argument, it represents the type |
| 859 * variable at the corresponding entry in [emitter.globalMetadata]. | 889 * variable at the corresponding entry in [emitter.globalMetadata]. |
| 860 */ | 890 */ |
| 861 String _typeArguments; | 891 String _typeArguments; |
| 862 | 892 |
| 863 UnmodifiableListView<TypeMirror> _cachedTypeArguments; | 893 UnmodifiableListView<TypeMirror> _cachedTypeArguments; |
| 894 UnmodifiableMapView<Symbol, DeclarationMirror> _cachedDeclarations; |
| 895 UnmodifiableMapView<Symbol, DeclarationMirror> _cachedMembers; |
| 896 UnmodifiableMapView<Symbol, MethodMirror> _cachedConstructors; |
| 864 Map<Symbol, VariableMirror> _cachedVariables; | 897 Map<Symbol, VariableMirror> _cachedVariables; |
| 865 Map<Symbol, MethodMirror> _cachedGetters; | 898 Map<Symbol, MethodMirror> _cachedGetters; |
| 866 Map<Symbol, MethodMirror> _cachedSetters; | 899 Map<Symbol, MethodMirror> _cachedSetters; |
| 867 Map<Symbol, MethodMirror> _cachedMethodsMap; | 900 Map<Symbol, MethodMirror> _cachedMethodsMap; |
| 868 List<JsMethodMirror> _cachedMethods; | 901 List<JsMethodMirror> _cachedMethods; |
| 869 ClassMirror _superclass; | 902 ClassMirror _superclass; |
| 870 List<ClassMirror> _cachedSuperinterfaces; | 903 List<ClassMirror> _cachedSuperinterfaces; |
| 871 | 904 |
| 872 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) | 905 JsTypeBoundClassMirror(JsClassMirror originalDeclaration, this._typeArguments) |
| 873 : _class = originalDeclaration, | 906 : _class = originalDeclaration, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 920 } | 953 } |
| 921 } else { | 954 } else { |
| 922 currentTypeArgument += character; | 955 currentTypeArgument += character; |
| 923 } | 956 } |
| 924 } | 957 } |
| 925 addTypeArgument(currentTypeArgument); | 958 addTypeArgument(currentTypeArgument); |
| 926 } | 959 } |
| 927 return _cachedTypeArguments = new UnmodifiableListView(result); | 960 return _cachedTypeArguments = new UnmodifiableListView(result); |
| 928 } | 961 } |
| 929 | 962 |
| 930 Map<Symbol, MethodMirror> get constructors => _class.constructors; | |
| 931 | |
| 932 List<JsMethodMirror> get _methods { | 963 List<JsMethodMirror> get _methods { |
| 933 if (_cachedMethods != null) return _cachedMethods; | 964 if (_cachedMethods != null) return _cachedMethods; |
| 934 return _cachedMethods =_class._getMethodsWithOwner(this); | 965 return _cachedMethods =_class._getMethodsWithOwner(this); |
| 935 } | 966 } |
| 936 | 967 |
| 937 Map<Symbol, MethodMirror> get methods { | 968 Map<Symbol, MethodMirror> get methods { |
| 938 if (_cachedMethodsMap != null) return _cachedMethodsMap; | 969 if (_cachedMethodsMap != null) return _cachedMethodsMap; |
| 939 return _cachedMethodsMap = new UnmodifiableMapView<Symbol, MethodMirror>( | 970 return _cachedMethodsMap = new UnmodifiableMapView<Symbol, MethodMirror>( |
| 940 filterMethods(_methods)); | 971 filterMethods(_methods)); |
| 941 } | 972 } |
| 942 | 973 |
| 974 Map<Symbol, MethodMirror> get constructors { |
| 975 if (_cachedConstructors != null) return _cachedConstructors; |
| 976 return _cachedConstructors = |
| 977 new UnmodifiableMapView<Symbol, MethodMirror>( |
| 978 filterConstructors(_methods)); |
| 979 } |
| 980 |
| 943 Map<Symbol, MethodMirror> get getters { | 981 Map<Symbol, MethodMirror> get getters { |
| 944 if (_cachedGetters != null) return _cachedGetters; | 982 if (_cachedGetters != null) return _cachedGetters; |
| 945 return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>( | 983 return _cachedGetters = new UnmodifiableMapView<Symbol, MethodMirror>( |
| 946 filterGetters(_methods, variables)); | 984 filterGetters(_methods, variables)); |
| 947 } | 985 } |
| 948 | 986 |
| 949 Map<Symbol, MethodMirror> get setters { | 987 Map<Symbol, MethodMirror> get setters { |
| 950 if (_cachedSetters != null) return _cachedSetters; | 988 if (_cachedSetters != null) return _cachedSetters; |
| 951 return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>( | 989 return _cachedSetters = new UnmodifiableMapView<Symbol, MethodMirror>( |
| 952 filterSetters(_methods, variables)); | 990 filterSetters(_methods, variables)); |
| 953 } | 991 } |
| 954 | 992 |
| 955 Map<Symbol, VariableMirror> get variables { | 993 Map<Symbol, VariableMirror> get variables { |
| 956 if (_cachedVariables != null) return _cachedVariables; | 994 if (_cachedVariables != null) return _cachedVariables; |
| 957 var result = new Map(); | 995 var result = new Map(); |
| 958 for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) { | 996 for (JsVariableMirror mirror in _class._getFieldsWithOwner(this)) { |
| 959 result[mirror.simpleName] = mirror; | 997 result[mirror.simpleName] = mirror; |
| 960 } | 998 } |
| 961 return _cachedVariables = | 999 return _cachedVariables = |
| 962 new UnmodifiableMapView<Symbol, VariableMirror>(result); | 1000 new UnmodifiableMapView<Symbol, VariableMirror>(result); |
| 963 } | 1001 } |
| 964 | 1002 |
| 965 Map<Symbol, Mirror> get members => _class.members; | 1003 Map<Symbol, DeclarationMirror> get members { |
| 1004 if (_cachedMembers != null) return _cachedMembers; |
| 1005 return _cachedMembers = new UnmodifiableMapView<Symbol, DeclarationMirror>( |
| 1006 filterMembers(_methods, variables)); |
| 1007 } |
| 1008 |
| 1009 Map<Symbol, DeclarationMirror> get declarations { |
| 1010 if (_cachedDeclarations != null) return _cachedDeclarations; |
| 1011 Map<Symbol, DeclarationMirror> result = |
| 1012 new Map<Symbol, DeclarationMirror>(); |
| 1013 result.addAll(members); |
| 1014 result.addAll(constructors); |
| 1015 typeVariables.forEach((tv) => result[tv.simpleName] = tv); |
| 1016 return _cachedDeclarations = |
| 1017 new UnmodifiableMapView<Symbol, DeclarationMirror>(result); |
| 1018 } |
| 966 | 1019 |
| 967 InstanceMirror setField(Symbol fieldName, Object arg) { | 1020 InstanceMirror setField(Symbol fieldName, Object arg) { |
| 968 return _class.setField(fieldName, arg); | 1021 return _class.setField(fieldName, arg); |
| 969 } | 1022 } |
| 970 | 1023 |
| 971 InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName); | 1024 InstanceMirror getField(Symbol fieldName) => _class.getField(fieldName); |
| 972 | 1025 |
| 973 InstanceMirror newInstance(Symbol constructorName, | 1026 InstanceMirror newInstance(Symbol constructorName, |
| 974 List positionalArguments, | 1027 List positionalArguments, |
| 975 [Map<Symbol, dynamic> namedArguments]) { | 1028 [Map<Symbol, dynamic> namedArguments]) { |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 get _jsConstructor { | 1114 get _jsConstructor { |
| 1062 if (_jsConstructorOrInterceptor is Interceptor) { | 1115 if (_jsConstructorOrInterceptor is Interceptor) { |
| 1063 return JS('', '#.constructor', _jsConstructorOrInterceptor); | 1116 return JS('', '#.constructor', _jsConstructorOrInterceptor); |
| 1064 } else { | 1117 } else { |
| 1065 return _jsConstructorOrInterceptor; | 1118 return _jsConstructorOrInterceptor; |
| 1066 } | 1119 } |
| 1067 } | 1120 } |
| 1068 | 1121 |
| 1069 Map<Symbol, MethodMirror> get constructors { | 1122 Map<Symbol, MethodMirror> get constructors { |
| 1070 if (_cachedConstructors != null) return _cachedConstructors; | 1123 if (_cachedConstructors != null) return _cachedConstructors; |
| 1071 var result = new Map(); | |
| 1072 for (JsMethodMirror method in _methods) { | |
| 1073 if (method.isConstructor) { | |
| 1074 result[method.simpleName] = method; | |
| 1075 } | |
| 1076 } | |
| 1077 return _cachedConstructors = | 1124 return _cachedConstructors = |
| 1078 new UnmodifiableMapView<Symbol, MethodMirror>(result); | 1125 new UnmodifiableMapView<Symbol, MethodMirror>( |
| 1126 filterConstructors(_methods)); |
| 1079 } | 1127 } |
| 1080 | 1128 |
| 1081 List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) { | 1129 List<JsMethodMirror> _getMethodsWithOwner(DeclarationMirror methodOwner) { |
| 1082 var prototype = JS('', '#.prototype', _jsConstructor); | 1130 var prototype = JS('', '#.prototype', _jsConstructor); |
| 1083 List<String> keys = extractKeys(prototype); | 1131 List<String> keys = extractKeys(prototype); |
| 1084 var result = <JsMethodMirror>[]; | 1132 var result = <JsMethodMirror>[]; |
| 1085 for (String key in keys) { | 1133 for (String key in keys) { |
| 1086 if (isReflectiveDataInPrototype(key)) continue; | 1134 if (isReflectiveDataInPrototype(key)) continue; |
| 1087 String simpleName = mangledNames[key]; | 1135 String simpleName = mangledNames[key]; |
| 1088 // [simpleName] can be null if [key] represents an implementation | 1136 // [simpleName] can be null if [key] represents an implementation |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1182 var result = new Map(); | 1230 var result = new Map(); |
| 1183 for (JsVariableMirror mirror in _fields) { | 1231 for (JsVariableMirror mirror in _fields) { |
| 1184 result[mirror.simpleName] = mirror; | 1232 result[mirror.simpleName] = mirror; |
| 1185 } | 1233 } |
| 1186 return _cachedVariables = | 1234 return _cachedVariables = |
| 1187 new UnmodifiableMapView<Symbol, VariableMirror>(result); | 1235 new UnmodifiableMapView<Symbol, VariableMirror>(result); |
| 1188 } | 1236 } |
| 1189 | 1237 |
| 1190 Map<Symbol, Mirror> get members { | 1238 Map<Symbol, Mirror> get members { |
| 1191 if (_cachedMembers != null) return _cachedMembers; | 1239 if (_cachedMembers != null) return _cachedMembers; |
| 1192 Map<Symbol, Mirror> result = new Map.from(variables); | 1240 return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>( |
| 1193 for (JsMethodMirror method in _methods) { | 1241 filterMembers(_methods, variables)); |
| 1194 if (method.isSetter) { | |
| 1195 String name = n(method.simpleName); | |
| 1196 name = name.substring(0, name.length - 1); | |
| 1197 // Filter-out setters corresponding to variables. | |
| 1198 if (result[s(name)] is VariableMirror) continue; | |
| 1199 } | |
| 1200 // Constructors aren't 'members'. | |
| 1201 if (method.isConstructor) continue; | |
| 1202 // Use putIfAbsent to filter-out getters corresponding to variables. | |
| 1203 result.putIfAbsent(method.simpleName, () => method); | |
| 1204 } | |
| 1205 return _cachedMembers = new UnmodifiableMapView<Symbol, Mirror>(result); | |
| 1206 } | 1242 } |
| 1207 | 1243 |
| 1208 Map<Symbol, DeclarationMirror> get declarations { | 1244 Map<Symbol, DeclarationMirror> get declarations { |
| 1209 if (_cachedDeclarations != null) return _cachedDeclarations; | 1245 if (_cachedDeclarations != null) return _cachedDeclarations; |
| 1210 var result = new Map<Symbol, DeclarationMirror>(); | 1246 var result = new Map<Symbol, DeclarationMirror>(); |
| 1211 addToResult(Symbol key, Mirror value) { | 1247 addToResult(Symbol key, Mirror value) { |
| 1212 result[key] = value; | 1248 result[key] = value; |
| 1213 } | 1249 } |
| 1214 members.forEach(addToResult); | 1250 members.forEach(addToResult); |
| 1215 constructors.forEach(addToResult); | 1251 constructors.forEach(addToResult); |
| (...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2057 | 2093 |
| 2058 // TODO(ahe): Remove this class and call noSuchMethod instead. | 2094 // TODO(ahe): Remove this class and call noSuchMethod instead. |
| 2059 class UnimplementedNoSuchMethodError extends Error | 2095 class UnimplementedNoSuchMethodError extends Error |
| 2060 implements NoSuchMethodError { | 2096 implements NoSuchMethodError { |
| 2061 final String _message; | 2097 final String _message; |
| 2062 | 2098 |
| 2063 UnimplementedNoSuchMethodError(this._message); | 2099 UnimplementedNoSuchMethodError(this._message); |
| 2064 | 2100 |
| 2065 String toString() => "Unsupported operation: $_message"; | 2101 String toString() => "Unsupported operation: $_message"; |
| 2066 } | 2102 } |
| OLD | NEW |