| 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 JsGetName, | 10 JsGetName, |
| (...skipping 1766 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1777 if (thrownStackTrace == null) { | 1777 if (thrownStackTrace == null) { |
| 1778 JS('void', r'#.$thrownJsError = #', error, ex); | 1778 JS('void', r'#.$thrownJsError = #', error, ex); |
| 1779 } | 1779 } |
| 1780 } | 1780 } |
| 1781 return error; | 1781 return error; |
| 1782 } | 1782 } |
| 1783 | 1783 |
| 1784 // Note that we are checking if the object has the property. If it | 1784 // Note that we are checking if the object has the property. If it |
| 1785 // has, it could be set to null if the thrown value is null. | 1785 // has, it could be set to null if the thrown value is null. |
| 1786 if (ex == null) return null; | 1786 if (ex == null) return null; |
| 1787 if (ex is ExceptionAndStackTrace) { |
| 1788 return saveStackTrace(ex.dartException); |
| 1789 } |
| 1787 if (JS('bool', 'typeof # !== "object"', ex)) return ex; | 1790 if (JS('bool', 'typeof # !== "object"', ex)) return ex; |
| 1788 | 1791 |
| 1789 if (JS('bool', r'"dartException" in #', ex)) { | 1792 if (JS('bool', r'"dartException" in #', ex)) { |
| 1790 return saveStackTrace(JS('', r'#.dartException', ex)); | 1793 return saveStackTrace(JS('', r'#.dartException', ex)); |
| 1791 } else if (!JS('bool', r'"message" in #', ex)) { | 1794 } else if (!JS('bool', r'"message" in #', ex)) { |
| 1792 return ex; | 1795 return ex; |
| 1793 } | 1796 } |
| 1794 | 1797 |
| 1795 // Grab hold of the exception message. This field is available on | 1798 // Grab hold of the exception message. This field is available on |
| 1796 // all supported browsers. | 1799 // all supported browsers. |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1900 // Just return the exception. We should not wrap it because in case | 1903 // Just return the exception. We should not wrap it because in case |
| 1901 // the exception comes from the DOM, it is a JavaScript | 1904 // the exception comes from the DOM, it is a JavaScript |
| 1902 // object backed by a native Dart class. | 1905 // object backed by a native Dart class. |
| 1903 return ex; | 1906 return ex; |
| 1904 } | 1907 } |
| 1905 | 1908 |
| 1906 /** | 1909 /** |
| 1907 * Called by generated code to fetch the stack trace from an | 1910 * Called by generated code to fetch the stack trace from an |
| 1908 * exception. Should never return null. | 1911 * exception. Should never return null. |
| 1909 */ | 1912 */ |
| 1910 StackTrace getTraceFromException(exception) => new _StackTrace(exception); | 1913 StackTrace getTraceFromException(exception) { |
| 1914 if (exception is ExceptionAndStackTrace) { |
| 1915 return exception.stackTrace; |
| 1916 } |
| 1917 return new _StackTrace(exception); |
| 1918 } |
| 1911 | 1919 |
| 1912 class _StackTrace implements StackTrace { | 1920 class _StackTrace implements StackTrace { |
| 1913 var _exception; | 1921 var _exception; |
| 1914 String _trace; | 1922 String _trace; |
| 1915 _StackTrace(this._exception); | 1923 _StackTrace(this._exception); |
| 1916 | 1924 |
| 1917 String toString() { | 1925 String toString() { |
| 1918 if (_trace != null) return JS('String', '#', _trace); | 1926 if (_trace != null) return JS('String', '#', _trace); |
| 1919 | 1927 |
| 1920 String trace; | 1928 String trace; |
| (...skipping 1628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3549 } | 3557 } |
| 3550 | 3558 |
| 3551 void badMain() { | 3559 void badMain() { |
| 3552 throw new MainError("'main' is not a function."); | 3560 throw new MainError("'main' is not a function."); |
| 3553 } | 3561 } |
| 3554 | 3562 |
| 3555 void mainHasTooManyParameters() { | 3563 void mainHasTooManyParameters() { |
| 3556 throw new MainError("'main' expects too many parameters."); | 3564 throw new MainError("'main' expects too many parameters."); |
| 3557 } | 3565 } |
| 3558 | 3566 |
| 3567 /// A wrapper around an exception, much like the one created by [wrapException] |
| 3568 /// but with a pre-given stack-trace. |
| 3569 class ExceptionAndStackTrace { |
| 3570 dynamic dartException; |
| 3571 StackTrace stackTrace; |
| 3572 |
| 3573 ExceptionAndStackTrace(this.dartException, this.stackTrace); |
| 3574 } |
| 3575 |
| 3559 /// Runtime support for async-await transformation. | 3576 /// Runtime support for async-await transformation. |
| 3560 /// | 3577 /// |
| 3561 /// This function is called by a transformed function on each await and return | 3578 /// This function is called by a transformed function on each await and return |
| 3562 /// in the untransformed function, and before starting. | 3579 /// in the untransformed function, and before starting. |
| 3563 /// | 3580 /// |
| 3564 /// If [object] is not a future it will be wrapped in a `new Future.value`. | 3581 /// If [object] is not a future it will be wrapped in a `new Future.value`. |
| 3565 /// | 3582 /// |
| 3566 /// If [asyncBody] is [async_error_codes.SUCCESS]/[async_error_codes.ERROR] it | 3583 /// If [asyncBody] is [async_error_codes.SUCCESS]/[async_error_codes.ERROR] it |
| 3567 /// indicates a return or throw from the async function, and | 3584 /// indicates a return or throw from the async function, and |
| 3568 /// complete/completeError is called on [completer] with [object]. | 3585 /// complete/completeError is called on [completer] with [object]. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 3580 return; | 3597 return; |
| 3581 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { | 3598 } else if (identical(bodyFunctionOrErrorCode, async_error_codes.ERROR)) { |
| 3582 // The error is a js-error. | 3599 // The error is a js-error. |
| 3583 completer.completeError(unwrapException(object), | 3600 completer.completeError(unwrapException(object), |
| 3584 getTraceFromException(object)); | 3601 getTraceFromException(object)); |
| 3585 return; | 3602 return; |
| 3586 } | 3603 } |
| 3587 Future future = object is Future ? object : new Future.value(object); | 3604 Future future = object is Future ? object : new Future.value(object); |
| 3588 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3605 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
| 3589 async_error_codes.SUCCESS), | 3606 async_error_codes.SUCCESS), |
| 3590 onError: _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3607 onError: (dynamic error, StackTrace stackTrace) { |
| 3591 async_error_codes.ERROR)); | 3608 ExceptionAndStackTrace wrapped = |
| 3609 new ExceptionAndStackTrace(error, stackTrace); |
| 3610 return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
| 3611 async_error_codes.ERROR)(wrapped); |
| 3612 }); |
| 3592 return completer.future; | 3613 return completer.future; |
| 3593 } | 3614 } |
| 3594 | 3615 |
| 3595 Function _wrapJsFunctionForAsync(dynamic /* js function */ function, | 3616 Function _wrapJsFunctionForAsync(dynamic /* js function */ function, |
| 3596 int errorCode) { | 3617 int errorCode) { |
| 3597 var protected = JS('', """ | 3618 var protected = JS('', """ |
| 3598 // Invokes [function] with [errorCode] and [result]. | 3619 // Invokes [function] with [errorCode] and [result]. |
| 3599 // | 3620 // |
| 3600 // If (and as long as) the invocation throws, calls [function] again, | 3621 // If (and as long as) the invocation throws, calls [function] again, |
| 3601 // with an error-code. | 3622 // with an error-code. |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3696 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3717 _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
| 3697 async_error_codes.SUCCESS)(null); | 3718 async_error_codes.SUCCESS)(null); |
| 3698 }); | 3719 }); |
| 3699 return; | 3720 return; |
| 3700 } | 3721 } |
| 3701 } | 3722 } |
| 3702 | 3723 |
| 3703 Future future = object is Future ? object : new Future.value(object); | 3724 Future future = object is Future ? object : new Future.value(object); |
| 3704 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3725 future.then(_wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
| 3705 async_error_codes.SUCCESS), | 3726 async_error_codes.SUCCESS), |
| 3706 onError: _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, | 3727 onError: (error, StackTrace stackTrace) { |
| 3707 async_error_codes.ERROR)); | 3728 ExceptionAndStackTrace wrapped = |
| 3729 new ExceptionAndStackTrace(error, stackTrace); |
| 3730 return _wrapJsFunctionForAsync(bodyFunctionOrErrorCode, |
| 3731 async_error_codes.ERROR) |
| 3732 (wrapped); |
| 3733 }); |
| 3708 } | 3734 } |
| 3709 | 3735 |
| 3710 Stream streamOfController(AsyncStarStreamController controller) { | 3736 Stream streamOfController(AsyncStarStreamController controller) { |
| 3711 return controller.stream; | 3737 return controller.stream; |
| 3712 } | 3738 } |
| 3713 | 3739 |
| 3714 /// A wrapper around a [StreamController] that remembers if that controller | 3740 /// A wrapper around a [StreamController] that remembers if that controller |
| 3715 /// got a cancel. | 3741 /// got a cancel. |
| 3716 /// | 3742 /// |
| 3717 /// Also has a subSubscription that when not null will provide events for the | 3743 /// Also has a subSubscription that when not null will provide events for the |
| 3718 /// stream, and will be paused and resumed along with this controller. | 3744 /// stream, and will be paused and resumed along with this controller. |
| 3719 class AsyncStarStreamController { | 3745 class AsyncStarStreamController { |
| 3720 StreamController controller; | 3746 StreamController controller; |
| 3721 Stream get stream => controller.stream; | 3747 Stream get stream => controller.stream; |
| 3722 bool stopRunning = false; | 3748 bool stopRunning = false; |
| 3723 bool isAdding = false; | 3749 bool isAdding = false; |
| 3724 bool get isPaused => controller.isPaused; | 3750 bool get isPaused => controller.isPaused; |
| 3725 add(event) => controller.add(event); | 3751 add(event) => controller.add(event); |
| 3726 addStream(Stream stream) { | 3752 addStream(Stream stream) { |
| 3727 return controller.addStream(stream, cancelOnError: false); | 3753 return controller.addStream(stream, cancelOnError: false); |
| 3728 } | 3754 } |
| 3729 addError(error, stackTrace) => controller.addError(error, stackTrace); | 3755 addError(error, stackTrace) => controller.addError(error, stackTrace); |
| 3730 close() => controller.close(); | 3756 close() => controller.close(); |
| 3731 | 3757 |
| 3732 AsyncStarStreamController(helperCallback) { | 3758 AsyncStarStreamController(body) { |
| 3733 controller = new StreamController( | 3759 controller = new StreamController( |
| 3734 onListen: () { | 3760 onListen: () { |
| 3735 scheduleMicrotask(() { | 3761 scheduleMicrotask(() { |
| 3736 JS('', '#(#, null)', helperCallback, async_error_codes.SUCCESS); | 3762 _wrapJsFunctionForAsync(body, |
| 3763 async_error_codes.SUCCESS)(null); |
| 3737 }); | 3764 }); |
| 3738 }, | 3765 }, |
| 3739 onResume: () { | 3766 onResume: () { |
| 3740 if (!isAdding) { | 3767 if (!isAdding) { |
| 3741 asyncStarHelper(null, helperCallback, this); | 3768 asyncStarHelper(null, body, this); |
| 3742 } | 3769 } |
| 3743 }, onCancel: () { | 3770 }, onCancel: () { |
| 3744 stopRunning = true; | 3771 stopRunning = true; |
| 3745 }); | 3772 }); |
| 3746 } | 3773 } |
| 3747 } | 3774 } |
| 3748 | 3775 |
| 3749 makeAsyncStarController(helperCallback) { | 3776 makeAsyncStarController(body) { |
| 3750 return new AsyncStarStreamController(helperCallback); | 3777 return new AsyncStarStreamController(body); |
| 3751 } | 3778 } |
| 3752 | 3779 |
| 3753 class IterationMarker { | 3780 class IterationMarker { |
| 3754 static const YIELD_SINGLE = 0; | 3781 static const YIELD_SINGLE = 0; |
| 3755 static const YIELD_STAR = 1; | 3782 static const YIELD_STAR = 1; |
| 3756 static const ITERATION_ENDED = 2; | 3783 static const ITERATION_ENDED = 2; |
| 3757 static const UNCAUGHT_ERROR = 3; | 3784 static const UNCAUGHT_ERROR = 3; |
| 3758 | 3785 |
| 3759 final value; | 3786 final value; |
| 3760 final int state; | 3787 final int state; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3848 // This is a function that will return a helper function that does the | 3875 // This is a function that will return a helper function that does the |
| 3849 // iteration of the sync*. | 3876 // iteration of the sync*. |
| 3850 // | 3877 // |
| 3851 // Each invocation should give a body with fresh state. | 3878 // Each invocation should give a body with fresh state. |
| 3852 final dynamic /* js function */ _outerHelper; | 3879 final dynamic /* js function */ _outerHelper; |
| 3853 | 3880 |
| 3854 SyncStarIterable(this._outerHelper); | 3881 SyncStarIterable(this._outerHelper); |
| 3855 | 3882 |
| 3856 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); | 3883 Iterator get iterator => new SyncStarIterator(JS('', '#()', _outerHelper)); |
| 3857 } | 3884 } |
| OLD | NEW |