| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 _interceptors; | 5 library _interceptors; |
| 6 | 6 |
| 7 import 'dart:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
| 8 DISPATCH_PROPERTY_NAME, | 8 DISPATCH_PROPERTY_NAME, |
| 9 TYPE_TO_INTERCEPTOR_MAP; | 9 TYPE_TO_INTERCEPTOR_MAP; |
| 10 | 10 |
| 11 import 'dart:collection'; | 11 import 'dart:collection'; |
| 12 import 'dart:_internal' hide Symbol; | 12 import 'dart:_internal' hide Symbol; |
| 13 import "dart:_internal" as _symbol_dev show Symbol; | 13 import "dart:_internal" as _symbol_dev show Symbol; |
| 14 import 'dart:_js_helper' show allMatchesInStringUnchecked, | 14 import 'dart:_js_helper' show allMatchesInStringUnchecked, |
| 15 Null, | 15 Null, |
| 16 JSSyntaxRegExp, | 16 JSSyntaxRegExp, |
| 17 Primitives, | 17 Primitives, |
| 18 argumentErrorValue, | 18 argumentErrorValue, |
| 19 checkInt, | 19 checkInt, |
| 20 checkNull, | 20 checkNull, |
| 21 checkNum, | 21 checkNum, |
| 22 checkString, | 22 checkString, |
| 23 defineProperty, | 23 defineProperty, |
| 24 diagnoseIndexError, | 24 diagnoseIndexError, |
| 25 getIsolateAffinityTag, |
| 25 getRuntimeType, | 26 getRuntimeType, |
| 26 initNativeDispatch, | 27 initNativeDispatch, |
| 27 initNativeDispatchFlag, | 28 initNativeDispatchFlag, |
| 28 regExpGetNative, | 29 regExpGetNative, |
| 29 regExpCaptureCount, | 30 regExpCaptureCount, |
| 30 stringContainsUnchecked, | 31 stringContainsUnchecked, |
| 31 stringIndexOfStringUnchecked, | 32 stringIndexOfStringUnchecked, |
| 32 stringLastIndexOfUnchecked, | 33 stringLastIndexOfUnchecked, |
| 33 stringReplaceAllFuncUnchecked, | 34 stringReplaceAllFuncUnchecked, |
| 34 stringReplaceAllUnchecked, | 35 stringReplaceAllUnchecked, |
| 35 stringReplaceFirstUnchecked, | 36 stringReplaceFirstUnchecked, |
| 36 stringReplaceFirstMappedUnchecked, | 37 stringReplaceFirstMappedUnchecked, |
| 37 stringReplaceRangeUnchecked, | 38 stringReplaceRangeUnchecked, |
| 38 lookupAndCacheInterceptor, | 39 lookupAndCacheInterceptor, |
| 39 lookupDispatchRecord, | 40 lookupDispatchRecord, |
| 40 StringMatch, | 41 StringMatch, |
| 41 firstMatchAfter, | 42 firstMatchAfter, |
| 42 NoInline; | 43 NoInline; |
| 44 import 'dart:js' show JsNative; |
| 45 |
| 43 import 'dart:_foreign_helper' show | 46 import 'dart:_foreign_helper' show |
| 44 JS, | 47 JS, |
| 45 JS_EFFECT, | 48 JS_EFFECT, |
| 46 JS_EMBEDDED_GLOBAL, | 49 JS_EMBEDDED_GLOBAL, |
| 47 JS_INTERCEPTOR_CONSTANT, | 50 JS_INTERCEPTOR_CONSTANT, |
| 48 JS_STRING_CONCAT; | 51 JS_STRING_CONCAT; |
| 49 import 'dart:math' show Random; | 52 import 'dart:math' show Random; |
| 50 | 53 |
| 51 part 'js_array.dart'; | 54 part 'js_array.dart'; |
| 52 part 'js_number.dart'; | 55 part 'js_number.dart'; |
| 53 part 'js_string.dart'; | 56 part 'js_string.dart'; |
| 54 | 57 |
| 58 final String DART_CLOSURE_PROPERTY_NAME = |
| 59 getIsolateAffinityTag(r'_$dart_dartClosure'); |
| 60 |
| 55 String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); | 61 String _symbolToString(Symbol symbol) => _symbol_dev.Symbol.getName(symbol); |
| 56 | 62 |
| 57 _symbolMapToStringMap(Map<Symbol, dynamic> map) { | 63 _symbolMapToStringMap(Map<Symbol, dynamic> map) { |
| 58 if (map == null) return null; | 64 if (map == null) return null; |
| 59 var result = new Map<String, dynamic>(); | 65 var result = new Map<String, dynamic>(); |
| 60 map.forEach((Symbol key, value) { | 66 map.forEach((Symbol key, value) { |
| 61 result[_symbolToString(key)] = value; | 67 result[_symbolToString(key)] = value; |
| 62 }); | 68 }); |
| 63 return result; | 69 return result; |
| 64 } | 70 } |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 163 throw new UnimplementedError('Return interceptor for $discriminatedTag'); | 169 throw new UnimplementedError('Return interceptor for $discriminatedTag'); |
| 164 } | 170 } |
| 165 } | 171 } |
| 166 | 172 |
| 167 var interceptor = lookupAndCacheInterceptor(object); | 173 var interceptor = lookupAndCacheInterceptor(object); |
| 168 if (interceptor == null) { | 174 if (interceptor == null) { |
| 169 // JavaScript Objects created via object literals and `Object.create(null)` | 175 // JavaScript Objects created via object literals and `Object.create(null)` |
| 170 // are 'plain' Objects. This test could be simplified and the dispatch path | 176 // are 'plain' Objects. This test could be simplified and the dispatch path |
| 171 // be faster if Object.prototype was pre-patched with a non-leaf dispatch | 177 // be faster if Object.prototype was pre-patched with a non-leaf dispatch |
| 172 // record. | 178 // record. |
| 179 if (JS('bool', 'typeof # == "function"', object)) { |
| 180 return JS_INTERCEPTOR_CONSTANT(JavaScriptFunction); |
| 181 } |
| 173 var proto = JS('', 'Object.getPrototypeOf(#)', object); | 182 var proto = JS('', 'Object.getPrototypeOf(#)', object); |
| 174 if (JS('bool', '# == null || # === Object.prototype', proto, proto)) { | 183 if (JS('bool', '# == null || # === Object.prototype', proto, proto)) { |
| 175 return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject); | 184 return JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject); |
| 176 } else { | 185 } else { |
| 177 return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject); | 186 return JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject); |
| 178 } | 187 } |
| 179 } | 188 } |
| 180 | 189 |
| 181 return interceptor; | 190 return interceptor; |
| 182 } | 191 } |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 * This is the type that should be exported by a JavaScript interop library. | 396 * This is the type that should be exported by a JavaScript interop library. |
| 388 */ | 397 */ |
| 389 abstract class JSObject { | 398 abstract class JSObject { |
| 390 } | 399 } |
| 391 | 400 |
| 392 | 401 |
| 393 /** | 402 /** |
| 394 * Interceptor base class for JavaScript objects not recognized as some more | 403 * Interceptor base class for JavaScript objects not recognized as some more |
| 395 * specific native type. | 404 * specific native type. |
| 396 */ | 405 */ |
| 397 abstract class JavaScriptObject extends Interceptor implements JSObject { | 406 class JavaScriptObject extends Interceptor implements JSObject { |
| 398 const JavaScriptObject(); | 407 const JavaScriptObject(); |
| 399 | 408 |
| 400 // It would be impolite to stash a property on the object. | 409 // It would be impolite to stash a property on the object. |
| 401 int get hashCode => 0; | 410 int get hashCode => 0; |
| 402 | 411 |
| 403 Type get runtimeType => JSObject; | 412 Type get runtimeType => JSObject; |
| 413 |
| 414 /** |
| 415 * Returns the result of the JavaScript objects `toString` method. |
| 416 */ |
| 417 String toString() { |
| 418 try { |
| 419 return JS('String', 'String(#)', this); |
| 420 } catch(e) { |
| 421 return super.toString(); |
| 422 } |
| 423 } |
| 404 } | 424 } |
| 405 | 425 |
| 406 | 426 |
| 407 /** | 427 /** |
| 408 * Interceptor for plain JavaScript objects created as JavaScript object | 428 * Interceptor for plain JavaScript objects created as JavaScript object |
| 409 * literals or `new Object()`. | 429 * literals or `new Object()`. |
| 410 */ | 430 */ |
| 411 class PlainJavaScriptObject extends JavaScriptObject { | 431 class PlainJavaScriptObject extends JavaScriptObject { |
| 412 const PlainJavaScriptObject(); | 432 const PlainJavaScriptObject(); |
| 413 } | 433 } |
| 414 | 434 |
| 415 | 435 |
| 416 /** | 436 /** |
| 417 * Interceptor for unclassified JavaScript objects, typically objects with a | 437 * Interceptor for unclassified JavaScript objects, typically objects with a |
| 418 * non-trivial prototype chain. | 438 * non-trivial prototype chain. |
| 419 * | 439 * |
| 420 * This class also serves as a fallback for unknown JavaScript exceptions. | 440 * This class also serves as a fallback for unknown JavaScript exceptions. |
| 421 */ | 441 */ |
| 422 class UnknownJavaScriptObject extends JavaScriptObject { | 442 class UnknownJavaScriptObject extends JavaScriptObject { |
| 423 const UnknownJavaScriptObject(); | 443 const UnknownJavaScriptObject(); |
| 424 | 444 |
| 425 String toString() => JS('String', 'String(#)', this); | 445 String toString() => JS('String', 'String(#)', this); |
| 426 } | 446 } |
| 447 |
| 448 /** |
| 449 * Interceptor for JavaScript function objects and Dart functions that have |
| 450 * been converted to JavaScript functions. |
| 451 * These interceptor methods are not always used as the JavaScript function |
| 452 * object has also been mangled to support Dart function calling conventions. |
| 453 */ |
| 454 class JavaScriptFunction extends JavaScriptObject implements Function { |
| 455 const JavaScriptFunction(); |
| 456 |
| 457 String toString() { |
| 458 var dartClosure = JsNative.getProperty(this, DART_CLOSURE_PROPERTY_NAME); |
| 459 return dartClosure == null ? super.toString() : dartClosure.toString(); |
| 460 } |
| 461 } |
| OLD | NEW |