/** * Copyright (c) 2014 Petka Antonov * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions:

* * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN * THE SOFTWARE. * */ "use strict"; module.exports = function(Promise, INTERNAL) { var errors = require("./errors.js"); var TypeError = errors.TypeError; var util = require("./util.js"); var isArray = util.isArray; var errorObj = util.errorObj; var tryCatch1 = util.tryCatch1; function PromiseSpawn(generatorFunction, receiver, caller) { var promise = this._promise = new Promise(INTERNAL); promise._setTrace(caller, void 0); this._generatorFunction = generatorFunction; this._receiver = receiver; this._generator = void 0; } PromiseSpawn.prototype.promise = function PromiseSpawn$promise() { return this._promise; }; PromiseSpawn.prototype._run = function PromiseSpawn$_run() { this._generator = this._generatorFunction.call(this._receiver); this._receiver = this._generatorFunction = void 0; this._next(void 0); }; PromiseSpawn.prototype._continue = function PromiseSpawn$_continue(result) { if (result === errorObj) { this._generator = void 0; var trace = errors.canAttach(result.e) ? result.e : new Error(result.e + ""); this._promise._attachExtraTrace(trace); this._promise._reject(result.e, trace); return; } var value = result.value; if (result.done === true) { this._generator = void 0; if (!this._promise._tryFollow(value)) { this._promise._fulfill(value); } } else { var maybePromise = Promise._cast(value, PromiseSpawn$_continue, void 0); if (!(maybePromise instanceof Promise)) { if (isArray(maybePromise)) { maybePromise = Promise.all(maybePromise); } else { this._throw(new TypeError( "A value was yielded that could not be treated as a promise" )); return; } } maybePromise._then( this._next, this._throw, void 0, this, null, void 0 ); } }; PromiseSpawn.prototype._throw = function PromiseSpawn$_throw(reason) { if (errors.canAttach(reason)) this._promise._attachExtraTrace(reason); this._continue( tryCatch1(this._generator["throw"], this._generator, reason) ); }; PromiseSpawn.prototype._next = function PromiseSpawn$_next(value) { this._continue( tryCatch1(this._generator.next, this._generator, value) ); }; return PromiseSpawn; };