| 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 _js_helper; | 5 library _js_helper; |
| 6 | 6 |
| 7 import 'dart:_async_await_error_codes' as async_error_codes; | 7 import 'dart:_async_await_error_codes' as async_error_codes; |
| 8 | 8 |
| 9 import 'dart:_js_embedded_names' show | 9 import 'dart:_js_embedded_names' show |
| 10 DEFERRED_LIBRARY_URIS, | 10 DEFERRED_LIBRARY_URIS, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 80 part 'regexp_helper.dart'; | 80 part 'regexp_helper.dart'; |
| 81 part 'string_helper.dart'; | 81 part 'string_helper.dart'; |
| 82 part 'js_rti.dart'; | 82 part 'js_rti.dart'; |
| 83 part 'linked_hash_map.dart'; | 83 part 'linked_hash_map.dart'; |
| 84 | 84 |
| 85 /// Marks the internal map in dart2js, so that internal libraries can is-check | 85 /// Marks the internal map in dart2js, so that internal libraries can is-check |
| 86 /// them. | 86 /// them. |
| 87 abstract class InternalMap { | 87 abstract class InternalMap { |
| 88 } | 88 } |
| 89 | 89 |
| 90 /// Extracts the classname from the isCheckProperty. | 90 /// Extracts the JavaScript-constructor name from the given isCheckProperty. |
| 91 // TODO(floitsch): move this to foreign_helper.dart or similar. | 91 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 92 @ForceInline() | 92 @ForceInline() |
| 93 String classNameFromIsCheckProperty(String isCheckProperty) { | 93 String isCheckPropertyToJsConstructorName(String isCheckProperty) { |
| 94 return JS_BUILTIN('returns:String;depends:none;effects:none', | 94 return JS_BUILTIN('returns:String;depends:none;effects:none', |
| 95 JsBuiltin.classNameFromIsCheckProperty, | 95 JsBuiltin.isCheckPropertyToJsConstructorName, |
| 96 isCheckProperty); | 96 isCheckProperty); |
| 97 } | 97 } |
| 98 | 98 |
| 99 /// Returns true if the given [type] is a function type object. | 99 /// Returns true if the given [type] is a function type object. |
| 100 // TODO(floitsch): move this to foreign_helper.dart or similar. | 100 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 101 @ForceInline() | 101 @ForceInline() |
| 102 bool isDartFunctionType(Object type) { | 102 bool isDartFunctionType(Object type) { |
| 103 return JS_BUILTIN('returns:bool;effects:none;depends:none', | 103 return JS_BUILTIN('returns:bool;effects:none;depends:none', |
| 104 JsBuiltin.isFunctionType, type); | 104 JsBuiltin.isFunctionType, type); |
| 105 } | 105 } |
| 106 | 106 |
| 107 | 107 |
| 108 /// Creates a function type object. | 108 /// Creates a function type object. |
| 109 // TODO(floitsch): move this to foreign_helper.dart or similar. | 109 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 110 @ForceInline() | 110 @ForceInline() |
| 111 createDartFunctionType() { | 111 createDartFunctionTypeRti() { |
| 112 return JS_BUILTIN('returns:=Object;effects:none;depends:none', | 112 return JS_BUILTIN('returns:=Object;effects:none;depends:none', |
| 113 JsBuiltin.createFunctionType); | 113 JsBuiltin.createFunctionTypeRti); |
| 114 } | 114 } |
| 115 | 115 |
| 116 /// Retrieves the class name from type information stored on the constructor of | 116 /// Retrieves the class name from type information stored on the constructor of |
| 117 /// [type]. | 117 /// [type]. |
| 118 // TODO(floitsch): move this to foreign_helper.dart or similar. | 118 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 119 @ForceInline() | 119 @ForceInline() |
| 120 String getDartTypeName(Object type) { | 120 String rawRtiToJsConstructorName(Object rti) { |
| 121 return JS_BUILTIN('String', JsBuiltin.typeName, type); | 121 return JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti); |
| 122 } |
| 123 |
| 124 /// Returns the rti from the given [constructorName]. |
| 125 // TODO(floitsch): make this a builtin. |
| 126 jsConstructorNameToRti(String constructorName) { |
| 127 var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME); |
| 128 return JS('', '#(#)', getTypeFromName, constructorName); |
| 122 } | 129 } |
| 123 | 130 |
| 124 /// Returns the raw runtime type of the given object [o]. | 131 /// Returns the raw runtime type of the given object [o]. |
| 125 /// | 132 /// |
| 126 /// The argument [o] must be the interceptor for primitive types. If | 133 /// The argument [o] must be the interceptor for primitive types. If |
| 127 /// necessary run it through [getInterceptor] first. | 134 /// necessary run it through [getInterceptor] first. |
| 128 // TODO(floitsch): move this to foreign_helper.dart or similar. | 135 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 129 // TODO(floitsch): we should call getInterceptor ourselves, but currently | 136 // TODO(floitsch): we should call getInterceptor ourselves, but currently |
| 130 // getInterceptor is not GVNed. | 137 // getInterceptor is not GVNed. |
| 131 @ForceInline() | 138 @ForceInline() |
| (...skipping 29 matching lines...) Expand all Loading... |
| 161 | 168 |
| 162 /// Returns whether the given type is _the_ null type. | 169 /// Returns whether the given type is _the_ null type. |
| 163 // TODO(floitsch): move this to foreign_helper.dart or similar. | 170 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 164 @ForceInline() | 171 @ForceInline() |
| 165 bool isNullTypeRti(type) { | 172 bool isNullTypeRti(type) { |
| 166 return JS_BUILTIN('returns:bool;effects:none;depends:none', | 173 return JS_BUILTIN('returns:bool;effects:none;depends:none', |
| 167 JsBuiltin.isNullTypeRti, type); | 174 JsBuiltin.isNullTypeRti, type); |
| 168 } | 175 } |
| 169 | 176 |
| 170 /// Returns the metadata of the given [index]. | 177 /// Returns the metadata of the given [index]. |
| 178 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 171 @ForceInline() | 179 @ForceInline() |
| 172 getMetadata(int index) { | 180 getMetadata(int index) { |
| 173 return JS_BUILTIN('returns:var;effects:none;depends:none', | 181 return JS_BUILTIN('returns:var;effects:none;depends:none', |
| 174 JsBuiltin.getMetadata, index); | 182 JsBuiltin.getMetadata, index); |
| 175 } | 183 } |
| 176 | 184 |
| 177 /// Returns the type of the given [index]. | 185 /// Returns the type of the given [index]. |
| 186 // TODO(floitsch): move this to foreign_helper.dart or similar. |
| 178 @ForceInline() | 187 @ForceInline() |
| 179 getType(int index) { | 188 getType(int index) { |
| 180 return JS_BUILTIN('returns:var;effects:none;depends:none', | 189 return JS_BUILTIN('returns:var;effects:none;depends:none', |
| 181 JsBuiltin.getType, index); | 190 JsBuiltin.getType, index); |
| 182 } | 191 } |
| 183 | 192 |
| 184 /// No-op method that is called to inform the compiler that preambles might | 193 /// No-op method that is called to inform the compiler that preambles might |
| 185 /// be needed when executing the resulting JS file in a command-line | 194 /// be needed when executing the resulting JS file in a command-line |
| 186 /// JS engine. | 195 /// JS engine. |
| 187 requiresPreamble() {} | 196 requiresPreamble() {} |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 784 return result; | 793 return result; |
| 785 } | 794 } |
| 786 | 795 |
| 787 /** [: r"$".codeUnitAt(0) :] */ | 796 /** [: r"$".codeUnitAt(0) :] */ |
| 788 static const int DOLLAR_CHAR_VALUE = 36; | 797 static const int DOLLAR_CHAR_VALUE = 36; |
| 789 | 798 |
| 790 /// Creates a string containing the complete type for the class [className] | 799 /// Creates a string containing the complete type for the class [className] |
| 791 /// with the given type arguments. | 800 /// with the given type arguments. |
| 792 /// | 801 /// |
| 793 /// In minified mode, uses the unminified names if available. | 802 /// In minified mode, uses the unminified names if available. |
| 803 /// |
| 804 /// The given [className] string generally contains the name of the JavaScript |
| 805 /// constructor of the given class. |
| 794 static String formatType(String className, List typeArguments) { | 806 static String formatType(String className, List typeArguments) { |
| 795 return unmangleAllIdentifiersIfPreservedAnyways | 807 return unmangleAllIdentifiersIfPreservedAnyways |
| 796 ('$className${joinArguments(typeArguments, 0)}'); | 808 ('$className${joinArguments(typeArguments, 0)}'); |
| 797 } | 809 } |
| 798 | 810 |
| 799 /// Returns the type of [object] as a string (including type arguments). | 811 /// Returns the type of [object] as a string (including type arguments). |
| 800 /// | 812 /// |
| 801 /// In minified mode, uses the unminified names if available. | 813 /// In minified mode, uses the unminified names if available. |
| 802 static String objectTypeName(Object object) { | 814 static String objectTypeName(Object object) { |
| 803 String name = constructorNameFallback(getInterceptor(object)); | 815 String name = constructorNameFallback(getInterceptor(object)); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 814 } | 826 } |
| 815 // TODO(kasperl): If the namer gave us a fresh global name, we may | 827 // TODO(kasperl): If the namer gave us a fresh global name, we may |
| 816 // want to remove the numeric suffix that makes it unique too. | 828 // want to remove the numeric suffix that makes it unique too. |
| 817 if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) { | 829 if (name.length > 1 && identical(name.codeUnitAt(0), DOLLAR_CHAR_VALUE)) { |
| 818 name = name.substring(1); | 830 name = name.substring(1); |
| 819 } | 831 } |
| 820 return formatType(name, getRuntimeTypeInfo(object)); | 832 return formatType(name, getRuntimeTypeInfo(object)); |
| 821 } | 833 } |
| 822 | 834 |
| 823 /// In minified mode, uses the unminified names if available. | 835 /// In minified mode, uses the unminified names if available. |
| 824 static String objectToString(Object object) { | 836 static String objectToHumanReadableString(Object object) { |
| 825 String name = objectTypeName(object); | 837 String name = objectTypeName(object); |
| 826 return "Instance of '$name'"; | 838 return "Instance of '$name'"; |
| 827 } | 839 } |
| 828 | 840 |
| 829 static num dateNow() => JS('int', r'Date.now()'); | 841 static num dateNow() => JS('int', r'Date.now()'); |
| 830 | 842 |
| 831 static void initTicker() { | 843 static void initTicker() { |
| 832 if (timerFrequency != null) return; | 844 if (timerFrequency != null) return; |
| 833 // Start with low-resolution. We overwrite the fields if we find better. | 845 // Start with low-resolution. We overwrite the fields if we find better. |
| 834 timerFrequency = 1000; | 846 timerFrequency = 1000; |
| (...skipping 503 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1338 } | 1350 } |
| 1339 }); | 1351 }); |
| 1340 if (bad) { | 1352 if (bad) { |
| 1341 return functionNoSuchMethod( | 1353 return functionNoSuchMethod( |
| 1342 function, positionalArguments, namedArguments); | 1354 function, positionalArguments, namedArguments); |
| 1343 } | 1355 } |
| 1344 positionalArguments.addAll(defaultArguments.values); | 1356 positionalArguments.addAll(defaultArguments.values); |
| 1345 return JS('', '#.apply(#, #)', jsFunction, function, positionalArguments); | 1357 return JS('', '#.apply(#, #)', jsFunction, function, positionalArguments); |
| 1346 } | 1358 } |
| 1347 | 1359 |
| 1348 static _mangledNameMatchesType(String mangledName, TypeImpl type) { | |
| 1349 return JS('bool', '# == #', mangledName, type._typeName); | |
| 1350 } | |
| 1351 | |
| 1352 static bool identicalImplementation(a, b) { | 1360 static bool identicalImplementation(a, b) { |
| 1353 return JS('bool', '# == null', a) | 1361 return JS('bool', '# == null', a) |
| 1354 ? JS('bool', '# == null', b) | 1362 ? JS('bool', '# == null', b) |
| 1355 : JS('bool', '# === #', a, b); | 1363 : JS('bool', '# === #', a, b); |
| 1356 } | 1364 } |
| 1357 | 1365 |
| 1358 static StackTrace extractStackTrace(Error error) { | 1366 static StackTrace extractStackTrace(Error error) { |
| 1359 return getTraceFromException(JS('', r'#.$thrownJsError', error)); | 1367 return getTraceFromException(JS('', r'#.$thrownJsError', error)); |
| 1360 } | 1368 } |
| 1361 } | 1369 } |
| (...skipping 603 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1965 return saveStackTrace( | 1973 return saveStackTrace( |
| 1966 new NullError('$message (Error $ieErrorCode)', null)); | 1974 new NullError('$message (Error $ieErrorCode)', null)); |
| 1967 } | 1975 } |
| 1968 } | 1976 } |
| 1969 } | 1977 } |
| 1970 | 1978 |
| 1971 if (JS('bool', r'# instanceof TypeError', ex)) { | 1979 if (JS('bool', r'# instanceof TypeError', ex)) { |
| 1972 var match; | 1980 var match; |
| 1973 // Using JS to give type hints to the compiler to help tree-shaking. | 1981 // Using JS to give type hints to the compiler to help tree-shaking. |
| 1974 // TODO(ahe): That should be unnecessary due to type inference. | 1982 // TODO(ahe): That should be unnecessary due to type inference. |
| 1975 var nsme = | 1983 var nsme = TypeErrorDecoder.noSuchMethodPattern; |
| 1976 JS('TypeErrorDecoder', '#', TypeErrorDecoder.noSuchMethodPattern); | 1984 var notClosure = TypeErrorDecoder.notClosurePattern; |
| 1977 var notClosure = | 1985 var nullCall = TypeErrorDecoder.nullCallPattern; |
| 1978 JS('TypeErrorDecoder', '#', TypeErrorDecoder.notClosurePattern); | 1986 var nullLiteralCall = TypeErrorDecoder.nullLiteralCallPattern; |
| 1979 var nullCall = | 1987 var undefCall = TypeErrorDecoder.undefinedCallPattern; |
| 1980 JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullCallPattern); | 1988 var undefLiteralCall = TypeErrorDecoder.undefinedLiteralCallPattern; |
| 1981 var nullLiteralCall = | 1989 var nullProperty = TypeErrorDecoder.nullPropertyPattern; |
| 1982 JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullLiteralCallPattern); | 1990 var nullLiteralProperty = TypeErrorDecoder.nullLiteralPropertyPattern; |
| 1983 var undefCall = | 1991 var undefProperty = TypeErrorDecoder.undefinedPropertyPattern; |
| 1984 JS('TypeErrorDecoder', '#', TypeErrorDecoder.undefinedCallPattern); | |
| 1985 var undefLiteralCall = | |
| 1986 JS('TypeErrorDecoder', '#', | |
| 1987 TypeErrorDecoder.undefinedLiteralCallPattern); | |
| 1988 var nullProperty = | |
| 1989 JS('TypeErrorDecoder', '#', TypeErrorDecoder.nullPropertyPattern); | |
| 1990 var nullLiteralProperty = | |
| 1991 JS('TypeErrorDecoder', '#', | |
| 1992 TypeErrorDecoder.nullLiteralPropertyPattern); | |
| 1993 var undefProperty = | |
| 1994 JS('TypeErrorDecoder', '#', TypeErrorDecoder.undefinedPropertyPattern); | |
| 1995 var undefLiteralProperty = | 1992 var undefLiteralProperty = |
| 1996 JS('TypeErrorDecoder', '#', | 1993 TypeErrorDecoder.undefinedLiteralPropertyPattern; |
| 1997 TypeErrorDecoder.undefinedLiteralPropertyPattern); | |
| 1998 if ((match = nsme.matchTypeError(message)) != null) { | 1994 if ((match = nsme.matchTypeError(message)) != null) { |
| 1999 return saveStackTrace(new JsNoSuchMethodError(message, match)); | 1995 return saveStackTrace(new JsNoSuchMethodError(message, match)); |
| 2000 } else if ((match = notClosure.matchTypeError(message)) != null) { | 1996 } else if ((match = notClosure.matchTypeError(message)) != null) { |
| 2001 // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we | 1997 // notClosure may match "({c:null}).c()" or "({c:1}).c()", so we |
| 2002 // cannot tell if this an attempt to invoke call on null or a | 1998 // cannot tell if this an attempt to invoke call on null or a |
| 2003 // non-function object. | 1999 // non-function object. |
| 2004 // But we do know the method name is "call". | 2000 // But we do know the method name is "call". |
| 2005 JS('', '#.method = "call"', match); | 2001 JS('', '#.method = "call"', match); |
| 2006 return saveStackTrace(new JsNoSuchMethodError(message, match)); | 2002 return saveStackTrace(new JsNoSuchMethodError(message, match)); |
| 2007 } else if ((match = nullCall.matchTypeError(message)) != null || | 2003 } else if ((match = nullCall.matchTypeError(message)) != null || |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2209 BoundClosure.receiverOf(JS('BoundClosure', 'void 0')); | 2205 BoundClosure.receiverOf(JS('BoundClosure', 'void 0')); |
| 2210 BoundClosure.selfOf(JS('BoundClosure', 'void 0')); | 2206 BoundClosure.selfOf(JS('BoundClosure', 'void 0')); |
| 2211 }); | 2207 }); |
| 2212 // TODO(ahe): All the place below using \$ should be rewritten to go | 2208 // TODO(ahe): All the place below using \$ should be rewritten to go |
| 2213 // through the namer. | 2209 // through the namer. |
| 2214 var function = JS('', '#[#]', functions, 0); | 2210 var function = JS('', '#[#]', functions, 0); |
| 2215 String name = JS('String|Null', '#.\$stubName', function); | 2211 String name = JS('String|Null', '#.\$stubName', function); |
| 2216 String callName = JS('String|Null', '#[#]', function, | 2212 String callName = JS('String|Null', '#[#]', function, |
| 2217 JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); | 2213 JS_GET_NAME(JsGetName.CALL_NAME_PROPERTY)); |
| 2218 | 2214 |
| 2215 // This variable holds either an index into the types-table, or a function |
| 2216 // that can compute a function-rti. (The latter is necessary if the type |
| 2217 // is dependent on generic arguments). |
| 2219 var functionType; | 2218 var functionType; |
| 2220 if (reflectionInfo is List) { | 2219 if (reflectionInfo is List) { |
| 2221 JS('', '#.\$reflectionInfo = #', function, reflectionInfo); | 2220 JS('', '#.\$reflectionInfo = #', function, reflectionInfo); |
| 2222 ReflectionInfo info = new ReflectionInfo(function); | 2221 ReflectionInfo info = new ReflectionInfo(function); |
| 2223 functionType = info.functionType; | 2222 functionType = info.functionType; |
| 2224 } else { | 2223 } else { |
| 2225 functionType = reflectionInfo; | 2224 functionType = reflectionInfo; |
| 2226 } | 2225 } |
| 2227 | 2226 |
| 2228 | 2227 |
| (...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2643 } else { | 2642 } else { |
| 2644 // A bound closure on an intercepted native class, just use the | 2643 // A bound closure on an intercepted native class, just use the |
| 2645 // identity hash code. | 2644 // identity hash code. |
| 2646 receiverHashCode = Primitives.objectHashCode(_receiver); | 2645 receiverHashCode = Primitives.objectHashCode(_receiver); |
| 2647 } | 2646 } |
| 2648 return receiverHashCode ^ Primitives.objectHashCode(_target); | 2647 return receiverHashCode ^ Primitives.objectHashCode(_target); |
| 2649 } | 2648 } |
| 2650 | 2649 |
| 2651 toString() { | 2650 toString() { |
| 2652 var receiver = _receiver == null ? _self : _receiver; | 2651 var receiver = _receiver == null ? _self : _receiver; |
| 2653 return "Closure '$_name' of ${Primitives.objectToString(receiver)}"; | 2652 return "Closure '$_name' of ${Primitives.objectToHumanReadableString(receive
r)}"; |
| 2654 } | 2653 } |
| 2655 | 2654 |
| 2656 @NoInline() | 2655 @NoInline() |
| 2657 static selfOf(BoundClosure closure) => closure._self; | 2656 static selfOf(BoundClosure closure) => closure._self; |
| 2658 | 2657 |
| 2659 static targetOf(BoundClosure closure) => closure._target; | 2658 static targetOf(BoundClosure closure) => closure._target; |
| 2660 | 2659 |
| 2661 @NoInline() | 2660 @NoInline() |
| 2662 static receiverOf(BoundClosure closure) => closure._receiver; | 2661 static receiverOf(BoundClosure closure) => closure._receiver; |
| 2663 | 2662 |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2861 throw new TypeErrorImplementation(value, 'int'); | 2860 throw new TypeErrorImplementation(value, 'int'); |
| 2862 } | 2861 } |
| 2863 | 2862 |
| 2864 intTypeCast(value) { | 2863 intTypeCast(value) { |
| 2865 if (value is int || value == null) return value; | 2864 if (value is int || value == null) return value; |
| 2866 throw new CastErrorImplementation( | 2865 throw new CastErrorImplementation( |
| 2867 Primitives.objectTypeName(value), 'int'); | 2866 Primitives.objectTypeName(value), 'int'); |
| 2868 } | 2867 } |
| 2869 | 2868 |
| 2870 void propertyTypeError(value, property) { | 2869 void propertyTypeError(value, property) { |
| 2871 String name = classNameFromIsCheckProperty(property); | 2870 String name = isCheckPropertyToJsConstructorName(property); |
| 2872 throw new TypeErrorImplementation(value, name); | 2871 throw new TypeErrorImplementation(value, name); |
| 2873 } | 2872 } |
| 2874 | 2873 |
| 2875 void propertyTypeCastError(value, property) { | 2874 void propertyTypeCastError(value, property) { |
| 2876 // Cuts the property name to the class name. | 2875 // Cuts the property name to the class name. |
| 2877 String actualType = Primitives.objectTypeName(value); | 2876 String actualType = Primitives.objectTypeName(value); |
| 2878 String expectedType = property.substring(3, property.length); | 2877 String expectedType = property.substring(3, property.length); |
| 2879 throw new CastErrorImplementation(actualType, expectedType); | 2878 throw new CastErrorImplementation(actualType, expectedType); |
| 2880 } | 2879 } |
| 2881 | 2880 |
| (...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3221 } | 3220 } |
| 3222 | 3221 |
| 3223 _extractFunctionTypeObjectFrom(o) { | 3222 _extractFunctionTypeObjectFrom(o) { |
| 3224 var interceptor = getInterceptor(o); | 3223 var interceptor = getInterceptor(o); |
| 3225 return JS('bool', '# in #', JS_SIGNATURE_NAME(), interceptor) | 3224 return JS('bool', '# in #', JS_SIGNATURE_NAME(), interceptor) |
| 3226 ? JS('', '#[#]()', interceptor, JS_SIGNATURE_NAME()) | 3225 ? JS('', '#[#]()', interceptor, JS_SIGNATURE_NAME()) |
| 3227 : null; | 3226 : null; |
| 3228 } | 3227 } |
| 3229 | 3228 |
| 3230 toRti() { | 3229 toRti() { |
| 3231 var result = createDartFunctionType(); | 3230 var result = createDartFunctionTypeRti(); |
| 3232 if (isVoid) { | 3231 if (isVoid) { |
| 3233 JS('', '#[#] = true', result, JS_FUNCTION_TYPE_VOID_RETURN_TAG()); | 3232 JS('', '#[#] = true', result, JS_FUNCTION_TYPE_VOID_RETURN_TAG()); |
| 3234 } else { | 3233 } else { |
| 3235 if (returnType is! DynamicRuntimeType) { | 3234 if (returnType is! DynamicRuntimeType) { |
| 3236 JS('', '#[#] = #', result, JS_FUNCTION_TYPE_RETURN_TYPE_TAG(), | 3235 JS('', '#[#] = #', result, JS_FUNCTION_TYPE_RETURN_TYPE_TAG(), |
| 3237 returnType.toRti()); | 3236 returnType.toRti()); |
| 3238 } | 3237 } |
| 3239 } | 3238 } |
| 3240 if (parameterTypes != null && !parameterTypes.isEmpty) { | 3239 if (parameterTypes != null && !parameterTypes.isEmpty) { |
| 3241 JS('', '#[#] = #', result, JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG(), | 3240 JS('', '#[#] = #', result, JS_FUNCTION_TYPE_REQUIRED_PARAMETERS_TAG(), |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3327 parameterTypes, | 3326 parameterTypes, |
| 3328 namedParameters) { | 3327 namedParameters) { |
| 3329 return new RuntimeFunctionType( | 3328 return new RuntimeFunctionType( |
| 3330 returnType, | 3329 returnType, |
| 3331 parameterTypes, | 3330 parameterTypes, |
| 3332 null, | 3331 null, |
| 3333 namedParameters); | 3332 namedParameters); |
| 3334 } | 3333 } |
| 3335 | 3334 |
| 3336 RuntimeType buildInterfaceType(rti, typeArguments) { | 3335 RuntimeType buildInterfaceType(rti, typeArguments) { |
| 3337 String name = JS('String', r'#.name', rti); | 3336 String jsConstructorName = rawRtiToJsConstructorName(rti); |
| 3338 if (typeArguments == null || typeArguments.isEmpty) { | 3337 if (typeArguments == null || typeArguments.isEmpty) { |
| 3339 return new RuntimeTypePlain(name); | 3338 return new RuntimeTypePlain(jsConstructorName); |
| 3340 } | 3339 } |
| 3341 return new RuntimeTypeGeneric(name, typeArguments, null); | 3340 return new RuntimeTypeGeneric(jsConstructorName, typeArguments, null); |
| 3342 } | 3341 } |
| 3343 | 3342 |
| 3344 class DynamicRuntimeType extends RuntimeType { | 3343 class DynamicRuntimeType extends RuntimeType { |
| 3345 const DynamicRuntimeType(); | 3344 const DynamicRuntimeType(); |
| 3346 | 3345 |
| 3347 String toString() => 'dynamic'; | 3346 String toString() => 'dynamic'; |
| 3348 | 3347 |
| 3349 toRti() => null; | 3348 toRti() => null; |
| 3350 } | 3349 } |
| 3351 | 3350 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3403 } else if (JS('bool', '"func" in #', rti)) { | 3402 } else if (JS('bool', '"func" in #', rti)) { |
| 3404 return new FunctionTypeInfoDecoderRing(rti).toRuntimeType(); | 3403 return new FunctionTypeInfoDecoderRing(rti).toRuntimeType(); |
| 3405 } else { | 3404 } else { |
| 3406 throw new RuntimeError( | 3405 throw new RuntimeError( |
| 3407 "Cannot convert " | 3406 "Cannot convert " |
| 3408 "'${JS('String', 'JSON.stringify(#)', rti)}' to RuntimeType."); | 3407 "'${JS('String', 'JSON.stringify(#)', rti)}' to RuntimeType."); |
| 3409 } | 3408 } |
| 3410 } | 3409 } |
| 3411 | 3410 |
| 3412 class RuntimeTypePlain extends RuntimeType { | 3411 class RuntimeTypePlain extends RuntimeType { |
| 3413 final String name; | 3412 /// The constructor name of this raw type. |
| 3413 final String _jsConstructorName; |
| 3414 | 3414 |
| 3415 RuntimeTypePlain(this.name); | 3415 RuntimeTypePlain(this._jsConstructorName); |
| 3416 | 3416 |
| 3417 toRti() { | 3417 toRti() { |
| 3418 var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME); | 3418 var rti = jsConstructorNameToRti(_jsConstructorName); |
| 3419 var rti = JS('', '#(#)', getTypeFromName, name); | 3419 if (rti == null) throw "no type for '$_jsConstructorName'"; |
| 3420 if (rti == null) throw "no type for '$name'"; | |
| 3421 return rti; | 3420 return rti; |
| 3422 } | 3421 } |
| 3423 | 3422 |
| 3424 String toString() => name; | 3423 String toString() => _jsConstructorName; |
| 3425 } | 3424 } |
| 3426 | 3425 |
| 3427 class RuntimeTypeGeneric extends RuntimeType { | 3426 class RuntimeTypeGeneric extends RuntimeType { |
| 3428 final String name; | 3427 /// The constructor name of the raw type for this generic type. |
| 3428 final String _jsConstructorName; |
| 3429 final List<RuntimeType> arguments; | 3429 final List<RuntimeType> arguments; |
| 3430 var rti; | 3430 var rti; |
| 3431 | 3431 |
| 3432 RuntimeTypeGeneric(this.name, this.arguments, this.rti); | 3432 RuntimeTypeGeneric(this._jsConstructorName, this.arguments, this.rti); |
| 3433 | 3433 |
| 3434 toRti() { | 3434 toRti() { |
| 3435 if (rti != null) return rti; | 3435 if (rti != null) return rti; |
| 3436 var getTypeFromName = JS_EMBEDDED_GLOBAL('', GET_TYPE_FROM_NAME); | 3436 var result = [jsConstructorNameToRti(_jsConstructorName)]; |
| 3437 var result = JS('JSExtendableArray', '[#(#)]', getTypeFromName, name); | |
| 3438 if (result[0] == null) { | 3437 if (result[0] == null) { |
| 3439 throw "no type for '$name<...>'"; | 3438 throw "no type for '$_jsConstructorName<...>'"; |
| 3440 } | 3439 } |
| 3441 for (RuntimeType argument in arguments) { | 3440 for (RuntimeType argument in arguments) { |
| 3442 JS('', '#.push(#)', result, argument.toRti()); | 3441 result.add(argument.toRti()); |
| 3443 } | 3442 } |
| 3444 return rti = result; | 3443 return rti = result; |
| 3445 } | 3444 } |
| 3446 | 3445 |
| 3447 String toString() => '$name<${arguments.join(", ")}>'; | 3446 String toString() => '$_jsConstructorName<${arguments.join(", ")}>'; |
| 3448 } | 3447 } |
| 3449 | 3448 |
| 3450 class FunctionTypeInfoDecoderRing { | 3449 class FunctionTypeInfoDecoderRing { |
| 3451 final _typeData; | 3450 final _typeData; |
| 3452 String _cachedToString; | 3451 String _cachedToString; |
| 3453 | 3452 |
| 3454 FunctionTypeInfoDecoderRing(this._typeData); | 3453 FunctionTypeInfoDecoderRing(this._typeData); |
| 3455 | 3454 |
| 3456 bool get _hasReturnType => JS('bool', '"ret" in #', _typeData); | 3455 bool get _hasReturnType => JS('bool', '"ret" in #', _typeData); |
| 3457 get _returnType => JS('', '#.ret', _typeData); | 3456 get _returnType => JS('', '#.ret', _typeData); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 3468 get _namedArguments => JS('=Object', '#.named', _typeData); | 3467 get _namedArguments => JS('=Object', '#.named', _typeData); |
| 3469 | 3468 |
| 3470 RuntimeType toRuntimeType() { | 3469 RuntimeType toRuntimeType() { |
| 3471 // TODO(ahe): Implement this (and update return type). | 3470 // TODO(ahe): Implement this (and update return type). |
| 3472 return const DynamicRuntimeType(); | 3471 return const DynamicRuntimeType(); |
| 3473 } | 3472 } |
| 3474 | 3473 |
| 3475 String _convert(type) { | 3474 String _convert(type) { |
| 3476 String result = runtimeTypeToString(type); | 3475 String result = runtimeTypeToString(type); |
| 3477 if (result != null) return result; | 3476 if (result != null) return result; |
| 3477 // Currently the [runtimeTypeToString] method doesn't handle function rtis. |
| 3478 if (JS('bool', '"func" in #', type)) { | 3478 if (JS('bool', '"func" in #', type)) { |
| 3479 return new FunctionTypeInfoDecoderRing(type).toString(); | 3479 return new FunctionTypeInfoDecoderRing(type).toString(); |
| 3480 } else { | 3480 } else { |
| 3481 throw 'bad type'; | 3481 throw 'bad type'; |
| 3482 } | 3482 } |
| 3483 } | 3483 } |
| 3484 | 3484 |
| 3485 String toString() { | 3485 String toString() { |
| 3486 if (_cachedToString != null) return _cachedToString; | 3486 if (_cachedToString != null) return _cachedToString; |
| 3487 var s = "("; | 3487 var s = "("; |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4089 // This is a function that will return a helper function that does the | 4089 // This is a function that will return a helper function that does the |
| 4090 // iteration of the sync*. | 4090 // iteration of the sync*. |
| 4091 // | 4091 // |
| 4092 // Each invocation should give a body with fresh state. | 4092 // Each invocation should give a body with fresh state. |
| 4093 final dynamic /* js function */ _outerHelper; | 4093 final dynamic /* js function */ _outerHelper; |
| 4094 | 4094 |
| 4095 SyncStarIterable(this._outerHelper); | 4095 SyncStarIterable(this._outerHelper); |
| 4096 | 4096 |
| 4097 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 4097 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
| 4098 } | 4098 } |
| OLD | NEW |