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 |