| 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"; | 994 return "$name:$nbArgs:0"; |
| 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 (isStubMethod(function)) continue; | 1688 if (isNoSuchMethodStub(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 ReflectionInfo reflectionInfo = new ReflectionInfo(jsFunction); | 2334 requiredParameterCount = int.parse(info[1]); |
| 2335 requiredParameterCount = reflectionInfo.requiredParameterCount; | 2335 optionalParameterCount = int.parse(info[2]); |
| 2336 optionalParameterCount = reflectionInfo.optionalParameterCount; | |
| 2337 assert(int.parse(info[1]) == requiredParameterCount | |
| 2338 + optionalParameterCount); | |
| 2339 } | 2336 } |
| 2340 return new JsMethodMirror( | 2337 return new JsMethodMirror( |
| 2341 s(name), jsFunction, requiredParameterCount, optionalParameterCount, | 2338 s(name), jsFunction, requiredParameterCount, optionalParameterCount, |
| 2342 isGetter, isSetter, isStatic, isConstructor, isOperator); | 2339 isGetter, isSetter, isStatic, isConstructor, isOperator); |
| 2343 } | 2340 } |
| 2344 | 2341 |
| 2345 String get _prettyName => 'MethodMirror'; | 2342 String get _prettyName => 'MethodMirror'; |
| 2346 | 2343 |
| 2347 int get _parameterCount => _requiredParameterCount + _optionalParameterCount; | 2344 int get _parameterCount => _requiredParameterCount + _optionalParameterCount; |
| 2348 | 2345 |
| (...skipping 606 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2955 /// method. | 2952 /// method. |
| 2956 bool isReflectiveDataInPrototype(String key) { | 2953 bool isReflectiveDataInPrototype(String key) { |
| 2957 if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) || | 2954 if (key == JS_GET_NAME(JsGetName.CLASS_DESCRIPTOR_PROPERTY) || |
| 2958 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { | 2955 key == METHODS_WITH_OPTIONAL_ARGUMENTS) { |
| 2959 return true; | 2956 return true; |
| 2960 } | 2957 } |
| 2961 String firstChar = key[0]; | 2958 String firstChar = key[0]; |
| 2962 return firstChar == '*' || firstChar == '+'; | 2959 return firstChar == '*' || firstChar == '+'; |
| 2963 } | 2960 } |
| 2964 | 2961 |
| 2965 bool isStubMethod(var jsFunction) { | 2962 bool isNoSuchMethodStub(var jsFunction) { |
| 2966 return JS('bool', r'#.$reflectable == 2', jsFunction); | 2963 return JS('bool', r'#.$reflectable == 2', jsFunction); |
| 2967 } | 2964 } |
| 2968 | 2965 |
| 2969 /// Returns true if [key] is only an aliased entry for [function] in the | 2966 /// Returns true if [key] is only an aliased entry for [function] in the |
| 2970 /// prototype. | 2967 /// prototype. |
| 2971 bool isAliasedSuperMethod(var jsFunction, String key) { | 2968 bool isAliasedSuperMethod(var jsFunction, String key) { |
| 2972 var stubName = JS('String|Null', r'#.$stubName', jsFunction); | 2969 var stubName = JS('String|Null', r'#.$stubName', jsFunction); |
| 2973 return stubName != null && key != stubName; | 2970 return stubName != null && key != stubName; |
| 2974 } | 2971 } |
| 2975 | 2972 |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3036 // have a part (following a '.') that starts with '_'. | 3033 // have a part (following a '.') that starts with '_'. |
| 3037 const int UNDERSCORE = 0x5f; | 3034 const int UNDERSCORE = 0x5f; |
| 3038 if (name.isEmpty) return true; | 3035 if (name.isEmpty) return true; |
| 3039 int index = -1; | 3036 int index = -1; |
| 3040 do { | 3037 do { |
| 3041 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; | 3038 if (name.codeUnitAt(index + 1) == UNDERSCORE) return false; |
| 3042 index = name.indexOf('.', index + 1); | 3039 index = name.indexOf('.', index + 1); |
| 3043 } while (index >= 0 && index + 1 < name.length); | 3040 } while (index >= 0 && index + 1 < name.length); |
| 3044 return true; | 3041 return true; |
| 3045 } | 3042 } |
| OLD | NEW |