| 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 JsGetName, |
| 9 ALL_CLASSES, | 9 ALL_CLASSES, |
| 10 LAZIES, | 10 LAZIES, |
| (...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 String _computeReflectiveName(Symbol symbolName, int type, | 984 String _computeReflectiveName(Symbol symbolName, int type, |
| 985 List positionalArguments, | 985 List positionalArguments, |
| 986 Map<Symbol, dynamic> namedArguments) { | 986 Map<Symbol, dynamic> namedArguments) { |
| 987 String name = n(symbolName); | 987 String name = n(symbolName); |
| 988 switch (type) { | 988 switch (type) { |
| 989 case JSInvocationMirror.GETTER: return name; | 989 case JSInvocationMirror.GETTER: return name; |
| 990 case JSInvocationMirror.SETTER: return '$name='; | 990 case JSInvocationMirror.SETTER: return '$name='; |
| 991 case JSInvocationMirror.METHOD: | 991 case JSInvocationMirror.METHOD: |
| 992 if (namedArguments.isNotEmpty) return '$name*'; | 992 if (namedArguments.isNotEmpty) return '$name*'; |
| 993 int nbArgs = positionalArguments.length as int; | 993 int nbArgs = positionalArguments.length as int; |
| 994 return "$name:$nbArgs:0"; | 994 return "$name:$nbArgs"; |
| 995 } | 995 } |
| 996 throw new RuntimeError("Could not compute reflective name for $name"); | 996 throw new RuntimeError("Could not compute reflective name for $name"); |
| 997 } | 997 } |
| 998 | 998 |
| 999 /** | 999 /** |
| 1000 * Returns a `CachedInvocation` or `CachedNoSuchMethodInvocation` for the | 1000 * Returns a `CachedInvocation` or `CachedNoSuchMethodInvocation` for the |
| 1001 * given member. | 1001 * given member. |
| 1002 * | 1002 * |
| 1003 * Caches the result. | 1003 * Caches the result. |
| 1004 */ | 1004 */ |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 var result = <JsMethodMirror>[]; | 1678 var result = <JsMethodMirror>[]; |
| 1679 for (String key in keys) { | 1679 for (String key in keys) { |
| 1680 if (isReflectiveDataInPrototype(key)) continue; | 1680 if (isReflectiveDataInPrototype(key)) continue; |
| 1681 String simpleName = mangledNames[key]; | 1681 String simpleName = mangledNames[key]; |
| 1682 // [simpleName] can be null if [key] represents an implementation | 1682 // [simpleName] can be null if [key] represents an implementation |
| 1683 // detail, for example, a bailout method, or runtime type support. | 1683 // detail, for example, a bailout method, or runtime type support. |
| 1684 // It might also be null if the user has limited what is reified for | 1684 // It might also be null if the user has limited what is reified for |
| 1685 // reflection with metadata. | 1685 // reflection with metadata. |
| 1686 if (simpleName == null) continue; | 1686 if (simpleName == null) continue; |
| 1687 var function = JS('', '#[#]', prototype, key); | 1687 var function = JS('', '#[#]', prototype, key); |
| 1688 if (isNoSuchMethodStub(function)) continue; | 1688 if (!isOrdinaryReflectableMethod(function)) continue; |
| 1689 if (isAliasedSuperMethod(function, key)) continue; | 1689 if (isAliasedSuperMethod(function, key)) continue; |
| 1690 var mirror = | 1690 var mirror = |
| 1691 new JsMethodMirror.fromUnmangledName( | 1691 new JsMethodMirror.fromUnmangledName( |
| 1692 simpleName, function, false, false); | 1692 simpleName, function, false, false); |
| 1693 result.add(mirror); | 1693 result.add(mirror); |
| 1694 mirror._owner = methodOwner; | 1694 mirror._owner = methodOwner; |
| 1695 } | 1695 } |
| 1696 | 1696 |
| 1697 var statics = JS_EMBEDDED_GLOBAL('', STATICS); | 1697 var statics = JS_EMBEDDED_GLOBAL('', STATICS); |
| 1698 keys = extractKeys(JS('', '#[#]', statics, _mangledName)); | 1698 keys = extractKeys(JS('', '#[#]', statics, _mangledName)); |
| (...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 int optionalParameterCount = 0; | 2324 int optionalParameterCount = 0; |
| 2325 bool isGetter = false; | 2325 bool isGetter = false; |
| 2326 if (info.length == 1) { | 2326 if (info.length == 1) { |
| 2327 if (isSetter) { | 2327 if (isSetter) { |
| 2328 requiredParameterCount = 1; | 2328 requiredParameterCount = 1; |
| 2329 } else { | 2329 } else { |
| 2330 isGetter = true; | 2330 isGetter = true; |
| 2331 requiredParameterCount = 0; | 2331 requiredParameterCount = 0; |
| 2332 } | 2332 } |
| 2333 } else { | 2333 } else { |
| 2334 requiredParameterCount = int.parse(info[1]); | 2334 ReflectionInfo reflectionInfo = new ReflectionInfo(jsFunction); |
| 2335 optionalParameterCount = int.parse(info[2]); | 2335 requiredParameterCount = reflectionInfo.requiredParameterCount; |
| 2336 optionalParameterCount = reflectionInfo.optionalParameterCount; |
| 2337 assert(int.parse(info[1]) == requiredParameterCount |
| 2338 + optionalParameterCount); |
| 2336 } | 2339 } |
| 2337 return new JsMethodMirror( | 2340 return new JsMethodMirror( |
| 2338 s(name), jsFunction, requiredParameterCount, optionalParameterCount, | 2341 s(name), jsFunction, requiredParameterCount, optionalParameterCount, |
| 2339 isGetter, isSetter, isStatic, isConstructor, isOperator); | 2342 isGetter, isSetter, isStatic, isConstructor, isOperator); |
| 2340 } | 2343 } |
| 2341 | 2344 |
| 2342 String get _prettyName => 'MethodMirror'; | 2345 String get _prettyName => 'MethodMirror'; |
| 2343 | 2346 |
| 2344 int get _parameterCount => _requiredParameterCount + _optionalParameterCount; | 2347 int get _parameterCount => _requiredParameterCount + _optionalParameterCount; |
| 2345 | 2348 |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2952 /// method. | 2955 /// method. |
| 2953 bool isReflectiveDataInPrototype(String key) { | 2956 bool isReflectiveDataInPrototype(String key) { |
| 2954 if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) || | 2957 if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) || |
| 2955 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { | 2958 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { |
| 2956 return true; | 2959 return true; |
| 2957 } | 2960 } |
| 2958 String firstChar = key[0]; | 2961 String firstChar = key[0]; |
| 2959 return firstChar == '*' || firstChar == '+'; | 2962 return firstChar == '*' || firstChar == '+'; |
| 2960 } | 2963 } |
| 2961 | 2964 |
| 2962 bool isNoSuchMethodStub(var jsFunction) { | 2965 /// Returns `true` if [jsFunction] is an ordinary reflectable method and |
| 2963 return JS('bool', r'#.$reflectable == 2', jsFunction); | 2966 /// not a (potentially reflectable) stub or otherwise non-reflectable method. |
| 2967 bool isOrdinaryReflectableMethod(var jsFunction) { |
| 2968 return JS('bool', r'#.$reflectable === 1', jsFunction); |
| 2964 } | 2969 } |
| 2965 | 2970 |
| 2966 /// Returns true if [key] is only an aliased entry for [function] in the | 2971 /// Returns true if [key] is only an aliased entry for [function] in the |
| 2967 /// prototype. | 2972 /// prototype. |
| 2968 bool isAliasedSuperMethod(var jsFunction, String key) { | 2973 bool isAliasedSuperMethod(var jsFunction, String key) { |
| 2969 var stubName = JS('String|Null', r'#.$stubName', jsFunction); | 2974 var stubName = JS('String|Null', r'#.$stubName', jsFunction); |
| 2970 return stubName != null && key != stubName; | 2975 return stubName != null && key != stubName; |
| 2971 } | 2976 } |
| 2972 | 2977 |
| 2973 class NoSuchStaticMethodError extends Error implements NoSuchMethodError { | 2978 class NoSuchStaticMethodError extends Error implements NoSuchMethodError { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3033 // have a part (following a '.') that starts with '_'. | 3038 // have a part (following a '.') that starts with '_'. |
| 3034 const int UNDERSCORE = 0x5f; | 3039 const int UNDERSCORE = 0x5f; |
| 3035 if (name.isEmpty) return true; | 3040 if (name.isEmpty) return true; |
| 3036 int index = -1; | 3041 int index = -1; |
| 3037 do { | 3042 do { |
| 3038 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; | 3043 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; |
| 3039 index = name.indexOf('.', index + 1); | 3044 index = name.indexOf('.', index + 1); |
| 3040 } while (index >= 0 && index + 1 < name.length); | 3045 } while (index >= 0 && index + 1 < name.length); |
| 3041 return true; | 3046 return true; |
| 3042 } | 3047 } |
| OLD | NEW |