Chromium Code Reviews| 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. | |
|
floitsch
2015/02/02 22:00:12
Explain more.
Is errorCallback necessary?...
sigurdm
2015/02/03 16:59:32
The error callback will redirect the control flow
floitsch
2015/02/04 12:31:27
Yes. I was talking about another implementation. F
| |
| 3463 // If helperCallback or errorCallback throws we complete the completer with | |
| 3464 // the error. | |
| 3465 thenHelper(object, | |
|
floitsch
2015/02/02 22:00:11
Types.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 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 { | |
|
floitsch
2015/02/02 22:00:11
I don't understand this.
Why not:
Function _wrapJ
sigurdm
2015/02/03 16:59:32
That is better, thanks
| |
| 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 | |
|
floitsch
2015/02/02 22:00:11
Add more documentation what exactly is expected an
sigurdm
2015/02/03 16:59:32
Done.
| |
| 3497 // If the object is a YIELD_SINGLE we add the object to the stream. | |
| 3498 streamHelper(object, | |
|
floitsch
2015/02/02 22:00:12
add real dartdoc.
types.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 3499 helperCallback, | |
| 3500 StreamController controller, | |
| 3501 errorCallback) { | |
| 3502 print("Called with $controller"); | |
|
floitsch
2015/02/02 22:00:11
debug line.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 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*. | |
|
floitsch
2015/02/02 22:00:11
Don't silently ignore the value.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 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]. | |
|
floitsch
2015/02/02 22:00:12
Ditto: I don't like "call" classes. Never sure if
sigurdm
2015/02/03 16:59:32
Done.
| |
| 3544 class WrappedJsFunctionForStream { | |
| 3545 final function; | |
| 3546 final StreamController controller; | |
| 3547 | |
| 3548 WrappedJsFunctionForStream(this.function, this.controller); | |
| 3549 | |
| 3550 call(result) { | |
| 3551 print(controller); | |
|
floitsch
2015/02/02 22:00:11
debugprint.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 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; | |
|
floitsch
2015/02/02 22:00:11
should not be public.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 3587 | |
| 3588 var _current = null; | |
| 3589 bool stillRunning = true; | |
|
floitsch
2015/02/02 22:00:11
Should not be public.
floitsch
2015/02/02 22:00:12
I don't think we use "stillRunning" in other itera
sigurdm
2015/02/03 16:59:32
Done.
sigurdm
2015/02/03 16:59:32
None of the other Iterators I could find maintains
| |
| 3590 bool runningNested = false; | |
|
floitsch
2015/02/02 22:00:12
should not be public.
sigurdm
2015/02/03 16:59:33
Done.
| |
| 3591 | |
| 3592 get current => runningNested ? _current.current : _current; | |
| 3593 | |
| 3594 SyncStarIterator(helper) | |
| 3595 : helper = ((arg) => JS('', '#(#)', helper, arg)); | |
|
floitsch
2015/02/02 22:00:11
don't call them the same.
Call the argument jsHel
sigurdm
2015/02/03 16:59:33
Done.
| |
| 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; | |
|
floitsch
2015/02/02 22:00:11
should not be public.
sigurdm
2015/02/03 16:59:33
Done.
| |
| 3624 | |
| 3625 SyncStarIterable(this.outerHelper); | |
|
floitsch
2015/02/02 22:00:12
Document what this is.
sigurdm
2015/02/03 16:59:32
Done.
| |
| 3626 | |
| 3627 Iterator get iterator => new SyncStarIterator(JS('', '#()', outerHelper)); | |
| 3628 } | |
| 3629 | |
| OLD | NEW |