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_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 8 JsGetName, |
8 ALL_CLASSES, | 9 ALL_CLASSES, |
9 LAZIES, | 10 LAZIES, |
10 LIBRARIES, | 11 LIBRARIES, |
11 STATICS, | 12 STATICS, |
12 TYPE_INFORMATION, | 13 TYPE_INFORMATION, |
13 TYPEDEF_PREDICATE_PROPERTY_NAME, | 14 TYPEDEF_PREDICATE_PROPERTY_NAME, |
14 TYPEDEF_TYPE_PROPERTY_NAME; | 15 TYPEDEF_TYPE_PROPERTY_NAME; |
15 | 16 |
16 import 'dart:collection' show | 17 import 'dart:collection' show |
17 UnmodifiableListView, | 18 UnmodifiableListView, |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
64 Interceptor, | 65 Interceptor, |
65 JSArray, | 66 JSArray, |
66 JSExtendableArray, | 67 JSExtendableArray, |
67 getInterceptor; | 68 getInterceptor; |
68 | 69 |
69 import 'dart:_js_names'; | 70 import 'dart:_js_names'; |
70 | 71 |
71 const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments'; | 72 const String METHODS_WITH_OPTIONAL_ARGUMENTS = r'$methodsWithOptionalArguments'; |
72 | 73 |
73 bool hasReflectableProperty(var jsFunction) { | 74 bool hasReflectableProperty(var jsFunction) { |
74 return JS('bool', '# in #', JS_GET_NAME("REFLECTABLE"), jsFunction); | 75 return JS('bool', '# in #', JS_GET_NAME(JsGetName.REFLECTABLE), jsFunction); |
75 } | 76 } |
76 | 77 |
77 /// No-op method that is called to inform the compiler that tree-shaking needs | 78 /// No-op method that is called to inform the compiler that tree-shaking needs |
78 /// to be disabled. | 79 /// to be disabled. |
79 disableTreeShaking() => preserveNames(); | 80 disableTreeShaking() => preserveNames(); |
80 | 81 |
81 /// No-op method that is called to inform the compiler that metadata must be | 82 /// No-op method that is called to inform the compiler that metadata must be |
82 /// preserved at runtime. | 83 /// preserved at runtime. |
83 preserveMetadata() {} | 84 preserveMetadata() {} |
84 | 85 |
(...skipping 558 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
643 // MyTypedef: { | 644 // MyTypedef: { |
644 // "^": "Object;", | 645 // "^": "Object;", |
645 // $typedefType: 58, | 646 // $typedefType: 58, |
646 // $$isTypedef: true | 647 // $$isTypedef: true |
647 // } | 648 // } |
648 // The typedefType is the index into the metadata table. | 649 // The typedefType is the index into the metadata table. |
649 int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME); | 650 int index = JS('int', '#[#]', descriptor, TYPEDEF_TYPE_PROPERTY_NAME); |
650 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); | 651 mirror = new JsTypedefMirror(symbol, mangledName, getMetadata(index)); |
651 } else { | 652 } else { |
652 fields = JS('', '#[#]', descriptor, | 653 fields = JS('', '#[#]', descriptor, |
653 JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY')); | 654 JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY)); |
654 if (fields is List) { | 655 if (fields is List) { |
655 fieldsMetadata = fields.getRange(1, fields.length).toList(); | 656 fieldsMetadata = fields.getRange(1, fields.length).toList(); |
656 fields = fields[0]; | 657 fields = fields[0]; |
657 } | 658 } |
658 if (fields is! String) { | 659 if (fields is! String) { |
659 // TODO(ahe): This is CSP mode. Find a way to determine the | 660 // TODO(ahe): This is CSP mode. Find a way to determine the |
660 // fields of this class. | 661 // fields of this class. |
661 fields = ''; | 662 fields = ''; |
662 } | 663 } |
663 } | 664 } |
(...skipping 1075 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1739 } | 1740 } |
1740 parseCompactFieldSpecification( | 1741 parseCompactFieldSpecification( |
1741 fieldOwner, instanceFieldSpecfication, false, result); | 1742 fieldOwner, instanceFieldSpecfication, false, result); |
1742 | 1743 |
1743 var statics = JS_EMBEDDED_GLOBAL('', STATICS); | 1744 var statics = JS_EMBEDDED_GLOBAL('', STATICS); |
1744 var staticDescriptor = JS('', '#[#]', statics, _mangledName); | 1745 var staticDescriptor = JS('', '#[#]', statics, _mangledName); |
1745 if (staticDescriptor != null) { | 1746 if (staticDescriptor != null) { |
1746 parseCompactFieldSpecification( | 1747 parseCompactFieldSpecification( |
1747 fieldOwner, | 1748 fieldOwner, |
1748 JS('', '#[#]', | 1749 JS('', '#[#]', |
1749 staticDescriptor, JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY')), | 1750 staticDescriptor, |
| 1751 JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY)), |
1750 true, result); | 1752 true, result); |
1751 } | 1753 } |
1752 return result; | 1754 return result; |
1753 } | 1755 } |
1754 | 1756 |
1755 List<VariableMirror> get _fields { | 1757 List<VariableMirror> get _fields { |
1756 if (_cachedFields != null) return _cachedFields; | 1758 if (_cachedFields != null) return _cachedFields; |
1757 return _cachedFields = _getFieldsWithOwner(this); | 1759 return _cachedFields = _getFieldsWithOwner(this); |
1758 } | 1760 } |
1759 | 1761 |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2145 String accessorName = jsName = field.substring(0, length); | 2147 String accessorName = jsName = field.substring(0, length); |
2146 int divider = field.indexOf(':'); | 2148 int divider = field.indexOf(':'); |
2147 if (divider > 0) { | 2149 if (divider > 0) { |
2148 accessorName = accessorName.substring(0, divider); | 2150 accessorName = accessorName.substring(0, divider); |
2149 jsName = field.substring(divider + 1); | 2151 jsName = field.substring(divider + 1); |
2150 } | 2152 } |
2151 var unmangledName; | 2153 var unmangledName; |
2152 if (isStatic) { | 2154 if (isStatic) { |
2153 unmangledName = mangledGlobalNames[accessorName]; | 2155 unmangledName = mangledGlobalNames[accessorName]; |
2154 } else { | 2156 } else { |
2155 String getterPrefix = JS_GET_NAME('GETTER_PREFIX'); | 2157 String getterPrefix = JS_GET_NAME(JsGetName.GETTER_PREFIX); |
2156 unmangledName = mangledNames['$getterPrefix$accessorName']; | 2158 unmangledName = mangledNames['$getterPrefix$accessorName']; |
2157 } | 2159 } |
2158 if (unmangledName == null) unmangledName = accessorName; | 2160 if (unmangledName == null) unmangledName = accessorName; |
2159 if (!hasSetter) { | 2161 if (!hasSetter) { |
2160 // TODO(ahe): This is a hack to handle checked setters in checked mode. | 2162 // TODO(ahe): This is a hack to handle checked setters in checked mode. |
2161 var setterName = s('$unmangledName='); | 2163 var setterName = s('$unmangledName='); |
2162 for (JsMethodMirror method in owner._methods) { | 2164 for (JsMethodMirror method in owner._methods) { |
2163 if (method.simpleName == setterName) { | 2165 if (method.simpleName == setterName) { |
2164 isFinal = false; | 2166 isFinal = false; |
2165 break; | 2167 break; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2224 : super(reflectee); | 2226 : super(reflectee); |
2225 | 2227 |
2226 MethodMirror get function { | 2228 MethodMirror get function { |
2227 String cacheName = Primitives.mirrorFunctionCacheName; | 2229 String cacheName = Primitives.mirrorFunctionCacheName; |
2228 JsMethodMirror cachedFunction; | 2230 JsMethodMirror cachedFunction; |
2229 // TODO(ahe): Restore caching. | 2231 // TODO(ahe): Restore caching. |
2230 //= JS('JsMethodMirror|Null', r'#.constructor[#]', reflectee, cacheName); | 2232 //= JS('JsMethodMirror|Null', r'#.constructor[#]', reflectee, cacheName); |
2231 if (cachedFunction != null) return cachedFunction; | 2233 if (cachedFunction != null) return cachedFunction; |
2232 disableTreeShaking(); | 2234 disableTreeShaking(); |
2233 // TODO(ahe): What about optional parameters (named or not). | 2235 // TODO(ahe): What about optional parameters (named or not). |
2234 String callPrefix = "${JS_GET_NAME("CALL_PREFIX")}\$"; | 2236 String callPrefix = "${JS_GET_NAME(JsGetName.CALL_PREFIX)}\$"; |
2235 var extractCallName = JS('', r''' | 2237 var extractCallName = JS('', r''' |
2236 function(reflectee) { | 2238 function(reflectee) { |
2237 for (var property in reflectee) { | 2239 for (var property in reflectee) { |
2238 if (# == property.substring(0, #) && | 2240 if (# == property.substring(0, #) && |
2239 property[#] >= '0' && | 2241 property[#] >= '0' && |
2240 property[#] <= '9') return property; | 2242 property[#] <= '9') return property; |
2241 } | 2243 } |
2242 return null; | 2244 return null; |
2243 } | 2245 } |
2244 ''', callPrefix, callPrefix.length, callPrefix.length, callPrefix.length); | 2246 ''', callPrefix, callPrefix.length, callPrefix.length, callPrefix.length); |
(...skipping 691 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2936 case '~': | 2938 case '~': |
2937 return true; | 2939 return true; |
2938 default: | 2940 default: |
2939 return false; | 2941 return false; |
2940 } | 2942 } |
2941 } | 2943 } |
2942 | 2944 |
2943 /// Returns true if the key represent ancillary reflection data, that is, not a | 2945 /// Returns true if the key represent ancillary reflection data, that is, not a |
2944 /// method. | 2946 /// method. |
2945 bool isReflectiveDataInPrototype(String key) { | 2947 bool isReflectiveDataInPrototype(String key) { |
2946 if (key == JS_GET_NAME('CLASS_DESCRIPTOR_PROPERTY') || | 2948 if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) || |
2947 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { | 2949 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { |
2948 return true; | 2950 return true; |
2949 } | 2951 } |
2950 String firstChar = key[0]; | 2952 String firstChar = key[0]; |
2951 return firstChar == '*' || firstChar == '+'; | 2953 return firstChar == '*' || firstChar == '+'; |
2952 } | 2954 } |
2953 | 2955 |
2954 bool isNoSuchMethodStub(var jsFunction) { | 2956 bool isNoSuchMethodStub(var jsFunction) { |
2955 return JS('bool', r'#.$reflectable == 2', jsFunction); | 2957 return JS('bool', r'#.$reflectable == 2', jsFunction); |
2956 } | 2958 } |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3025 // have a part (following a '.') that starts with '_'. | 3027 // have a part (following a '.') that starts with '_'. |
3026 const int UNDERSCORE = 0x5f; | 3028 const int UNDERSCORE = 0x5f; |
3027 if (name.isEmpty) return true; | 3029 if (name.isEmpty) return true; |
3028 int index = -1; | 3030 int index = -1; |
3029 do { | 3031 do { |
3030 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; | 3032 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; |
3031 index = name.indexOf('.', index + 1); | 3033 index = name.indexOf('.', index + 1); |
3032 } while (index >= 0 && index + 1 < name.length); | 3034 } while (index >= 0 && index + 1 < name.length); |
3033 return true; | 3035 return true; |
3034 } | 3036 } |
OLD | NEW |