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:_js_embedded_names' show | 7 import 'dart:_js_embedded_names' show |
8 GET_TYPE_FROM_NAME, | 8 GET_TYPE_FROM_NAME, |
9 GET_ISOLATE_TAG, | 9 GET_ISOLATE_TAG, |
10 INTERCEPTED_NAMES, | 10 INTERCEPTED_NAMES, |
11 INTERCEPTORS_BY_TAG, | 11 INTERCEPTORS_BY_TAG, |
12 LEAF_TAGS, | 12 LEAF_TAGS, |
13 METADATA, | 13 METADATA, |
14 DEFERRED_LIBRARY_URIS, | 14 DEFERRED_LIBRARY_URIS, |
15 DEFERRED_LIBRARY_HASHES, | 15 DEFERRED_LIBRARY_HASHES, |
16 INITIALIZE_LOADED_HUNK, | 16 INITIALIZE_LOADED_HUNK, |
17 IS_HUNK_LOADED, | 17 IS_HUNK_LOADED, |
18 IS_HUNK_INITIALIZED, | 18 IS_HUNK_INITIALIZED, |
19 NATIVE_SUPERCLASS_TAG_NAME; | 19 NATIVE_SUPERCLASS_TAG_NAME; |
20 | 20 |
21 import 'dart:collection'; | 21 import 'dart:collection'; |
22 import 'dart:_isolate_helper' show | 22 import 'dart:_isolate_helper' show |
23 IsolateNatives, | 23 IsolateNatives, |
24 leaveJsAsync, | 24 leaveJsAsync, |
25 enterJsAsync, | 25 enterJsAsync, |
26 isWorker; | 26 isWorker; |
27 | 27 |
28 import 'dart:async' show Future, DeferredLoadException, Completer; | 28 import 'dart:async' |
| 29 show Future, DeferredLoadException, Completer, StreamController; |
29 | 30 |
30 import 'dart:_foreign_helper' show | 31 import 'dart:_foreign_helper' show |
31 DART_CLOSURE_TO_JS, | 32 DART_CLOSURE_TO_JS, |
32 JS, | 33 JS, |
33 JS_CALL_IN_ISOLATE, | 34 JS_CALL_IN_ISOLATE, |
34 JS_CONST, | 35 JS_CONST, |
35 JS_CURRENT_ISOLATE, | 36 JS_CURRENT_ISOLATE, |
36 JS_CURRENT_ISOLATE_CONTEXT, | 37 JS_CURRENT_ISOLATE_CONTEXT, |
37 JS_DART_OBJECT_CONSTRUCTOR, | 38 JS_DART_OBJECT_CONSTRUCTOR, |
38 JS_EFFECT, | 39 JS_EFFECT, |
(...skipping 3410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3449 throw new MainError("No top-level function named 'main'."); | 3450 throw new MainError("No top-level function named 'main'."); |
3450 } | 3451 } |
3451 | 3452 |
3452 void badMain() { | 3453 void badMain() { |
3453 throw new MainError("'main' is not a function."); | 3454 throw new MainError("'main' is not a function."); |
3454 } | 3455 } |
3455 | 3456 |
3456 void mainHasTooManyParameters() { | 3457 void mainHasTooManyParameters() { |
3457 throw new MainError("'main' expects too many parameters."); | 3458 throw new MainError("'main' expects too many parameters."); |
3458 } | 3459 } |
| 3460 |
| 3461 /// Runtime support for async-await transformation. |
| 3462 // If helperCallback is null we complete the completer with object. |
| 3463 // If helperCallback or errorCallback throws we complete the completer with |
| 3464 // the error. |
| 3465 thenHelper(object, |
| 3466 helperCallback, |
| 3467 Completer completer, |
| 3468 errorCallback) { |
| 3469 if (helperCallback == null) { |
| 3470 completer.complete(object); |
| 3471 return; |
| 3472 } |
| 3473 Future future = object is Future ? object : new Future.value(object); |
| 3474 future.then(new WrappedJsFunction(helperCallback, completer), |
| 3475 onError: new WrappedJsFunction(errorCallback, completer)); |
| 3476 return completer.future; |
| 3477 } |
| 3478 |
| 3479 // Used to avoid creating two identical closure classes in [thenHelper]. |
| 3480 class WrappedJsFunction { |
| 3481 final function; |
| 3482 final Completer completer; |
| 3483 |
| 3484 WrappedJsFunction(this.function, this.completer); |
| 3485 |
| 3486 call(result) { |
| 3487 try { |
| 3488 JS('', '#(#)', function, result); |
| 3489 } catch (e, st) { |
| 3490 completer.completeError(e, st); |
| 3491 } |
| 3492 } |
| 3493 } |
| 3494 |
| 3495 // If helperCallback is null we close the stream. |
| 3496 // If helperCallback or errorCallback throws we add the error to the stream |
| 3497 // If the object is a YIELD_SINGLE we add the object to the stream. |
| 3498 streamHelper(object, |
| 3499 helperCallback, |
| 3500 StreamController controller, |
| 3501 errorCallback) { |
| 3502 print("Called with $controller"); |
| 3503 if (helperCallback == null) { |
| 3504 // This happens on return from the async* function. |
| 3505 controller.close(); |
| 3506 return; |
| 3507 } |
| 3508 |
| 3509 if (object is IterationMarker) { |
| 3510 if (object.state == IterationMarker.YIELD_SINGLE) { |
| 3511 controller.add(object.value); |
| 3512 } else if (object.state == IterationMarker.YIELD_STAR) { |
| 3513 // TODO(sigurdm): Handle yield star from async*. |
| 3514 } |
| 3515 if (controller.isPaused) { |
| 3516 return; |
| 3517 } else if (controller.isCanceled) { |
| 3518 // TODO(sigurdm): Handle cancelled streams. |
| 3519 } |
| 3520 object = null; |
| 3521 } |
| 3522 |
| 3523 Future future = object is Future ? object : new Future.value(object); |
| 3524 future.then(new WrappedJsFunctionForStream(helperCallback, controller), |
| 3525 onError: errorCallback = null |
| 3526 ? null |
| 3527 : new WrappedJsFunctionForStream(errorCallback, |
| 3528 controller)); |
| 3529 return controller.stream; |
| 3530 } |
| 3531 |
| 3532 |
| 3533 makeAsyncStarController(helperCallBack) { |
| 3534 StreamControllor c; |
| 3535 c = new StreamController( |
| 3536 onResume: () { |
| 3537 // TODO(sigurdm): The errorCallback should not be null. |
| 3538 streamHelper(null, helperCallBack, c, null); |
| 3539 }); |
| 3540 return c; |
| 3541 } |
| 3542 |
| 3543 // Used to avoid creating two identical closure classes in [streamHelper]. |
| 3544 class WrappedJsFunctionForStream { |
| 3545 final function; |
| 3546 final StreamController controller; |
| 3547 |
| 3548 WrappedJsFunctionForStream(this.function, this.controller); |
| 3549 |
| 3550 call(result) { |
| 3551 print(controller); |
| 3552 try { |
| 3553 JS('', "#(#)", function, result); |
| 3554 } catch (e, st) { |
| 3555 controller.addError(e, st); |
| 3556 } |
| 3557 } |
| 3558 } |
| 3559 |
| 3560 class IterationMarker { |
| 3561 static const YIELD_SINGLE = 0; |
| 3562 static const YIELD_STAR = 1; |
| 3563 static const ITERATION_ENDED = 2; |
| 3564 |
| 3565 final value; |
| 3566 final int state; |
| 3567 |
| 3568 IterationMarker._(this.state, this.value); |
| 3569 |
| 3570 static yieldStar(Iterable iterable) { |
| 3571 return new IterationMarker._(YIELD_STAR, iterable); |
| 3572 } |
| 3573 |
| 3574 static endOfIteration() { |
| 3575 return new IterationMarker._(ITERATION_ENDED, null); |
| 3576 } |
| 3577 |
| 3578 static yieldSingle(value) { |
| 3579 return new IterationMarker._(YIELD_SINGLE, value); |
| 3580 } |
| 3581 |
| 3582 toString() => "IterationMarker($state, $value)"; |
| 3583 } |
| 3584 |
| 3585 class SyncStarIterator implements Iterator { |
| 3586 final helper; |
| 3587 |
| 3588 var _current = null; |
| 3589 bool stillRunning = true; |
| 3590 bool runningNested = false; |
| 3591 |
| 3592 get current => runningNested ? _current.current : _current; |
| 3593 |
| 3594 SyncStarIterator(helper) |
| 3595 : helper = ((arg) => JS('', '#(#)', helper, arg)); |
| 3596 |
| 3597 bool moveNext() { |
| 3598 if (!stillRunning) return false; |
| 3599 if (runningNested) { |
| 3600 if (_current.moveNext()) { |
| 3601 return true; |
| 3602 } else { |
| 3603 runningNested = false; |
| 3604 } |
| 3605 } |
| 3606 _current = helper(null); |
| 3607 if (_current is IterationMarker) { |
| 3608 if (_current.state == IterationMarker.ITERATION_ENDED) { |
| 3609 _current = null; |
| 3610 stillRunning = false; |
| 3611 } else { |
| 3612 assert(_current.state == IterationMarker.YIELD_STAR); |
| 3613 _current = _current.value.iterator; |
| 3614 runningNested = true; |
| 3615 return moveNext(); |
| 3616 } |
| 3617 } |
| 3618 return stillRunning; |
| 3619 } |
| 3620 } |
| 3621 |
| 3622 class SyncStarIterable extends IterableBase { |
| 3623 final outerHelper; |
| 3624 |
| 3625 SyncStarIterable(this.outerHelper); |
| 3626 |
| 3627 Iterator get iterator => new SyncStarIterator(JS('', '#()', outerHelper)); |
| 3628 } |
| 3629 |
OLD | NEW |