Skip to content
Snippets Groups Projects
index.js 7.32 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function(Promise) {
    var longStackTraces = false;
    var contextStack = [];
    
    Promise.prototype._promiseCreated = function() {};
    Promise.prototype._pushContext = function() {};
    Promise.prototype._popContext = function() {return null;};
    Promise._peekContext = Promise.prototype._peekContext = function() {};
    
    function Context() {
        this._trace = new Context.CapturedTrace(peekContext());
    }
    Context.prototype._pushContext = function () {
        if (this._trace !== undefined) {
            this._trace._promiseCreated = null;
            contextStack.push(this._trace);
        }
    };
    
    Context.prototype._popContext = function () {
        if (this._trace !== undefined) {
            var trace = contextStack.pop();
            var ret = trace._promiseCreated;
            trace._promiseCreated = null;
            return ret;
        }
        return null;
    };
    
    function createContext() {
        if (longStackTraces) return new Context();
    }
    
    function peekContext() {
        var lastIndex = contextStack.length - 1;
        if (lastIndex >= 0) {
            return contextStack[lastIndex];
        }
        return undefined;
    }
    Context.CapturedTrace = null;
    Context.create = createContext;
    Context.deactivateLongStackTraces = function() {};
    Context.activateLongStackTraces = function() {
        var Promise_pushContext = Promise.prototype._pushContext;
        var Promise_popContext = Promise.prototype._popContext;
        var Promise_PeekContext = Promise._peekContext;
        var Promise_peekContext = Promise.prototype._peekContext;
        var Promise_promiseCreated = Promise.prototype._promiseCreated;
        Context.deactivateLongStackTraces = function() {
            Promise.prototype._pushContext = Promise_pushContext;
            Promise.prototype._popContext = Promise_popContext;
            Promise._peekContext = Promise_PeekContext;
            Promise.prototype._peekContext = Promise_peekContext;
            Promise.prototype._promiseCreated = Promise_promiseCreated;
            longStackTraces = false;
        };
        longStackTraces = true;
        Promise.prototype._pushContext = Context.prototype._pushContext;
        Promise.prototype._popContext = Context.prototype._popContext;
        Promise._peekContext = Promise.prototype._peekContext = peekContext;
        Promise.prototype._promiseCreated = function() {
            var ctx = this._peekContext();
            if (ctx && ctx._promiseCreated == null) ctx._promiseCreated = this;
        };
    };
    return Context;
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    
    module.exports = function(Promise, Context,
        enableAsyncHooks, disableAsyncHooks) {
    
    Romain CREY's avatar
    Romain CREY committed
    var async = Promise._async;
    
    var Warning = __webpack_require__(33).Warning;
    
    var util = __webpack_require__(27);
    var es5 = __webpack_require__(28);
    
    Romain CREY's avatar
    Romain CREY committed
    var canAttachTrace = util.canAttachTrace;
    var unhandledRejectionHandled;
    var possiblyUnhandledRejection;
    var bluebirdFramePattern =
        /[\\\/]bluebird[\\\/]js[\\\/](release|debug|instrumented)/;
    var nodeFramePattern = /\((?:timers\.js):\d+:\d+\)/;
    var parseLinePattern = /[\/<\(](.+?):(\d+):(\d+)\)?\s*$/;
    var stackFramePattern = null;
    var formatStack = null;
    var indentStackFrames = false;
    var printWarning;
    var debugging = !!(util.env("BLUEBIRD_DEBUG") != 0 &&
                            ( false ||
                             util.env("BLUEBIRD_DEBUG") ||
                             util.env("NODE_ENV") === "development"));
    
    var warnings = !!(util.env("BLUEBIRD_WARNINGS") != 0 &&
        (debugging || util.env("BLUEBIRD_WARNINGS")));
    
    var longStackTraces = !!(util.env("BLUEBIRD_LONG_STACK_TRACES") != 0 &&
        (debugging || util.env("BLUEBIRD_LONG_STACK_TRACES")));
    
    var wForgottenReturn = util.env("BLUEBIRD_W_FORGOTTEN_RETURN") != 0 &&
        (warnings || !!util.env("BLUEBIRD_W_FORGOTTEN_RETURN"));
    
    
    var deferUnhandledRejectionCheck;
    (function() {
        var promises = [];
    
        function unhandledRejectionCheck() {
            for (var i = 0; i < promises.length; ++i) {
                promises[i]._notifyUnhandledRejection();
            }
            unhandledRejectionClear();
        }
    
        function unhandledRejectionClear() {
            promises.length = 0;
        }
    
        deferUnhandledRejectionCheck = function(promise) {
            promises.push(promise);
            setTimeout(unhandledRejectionCheck, 1);
        };
    
        es5.defineProperty(Promise, "_unhandledRejectionCheck", {
            value: unhandledRejectionCheck
        });
        es5.defineProperty(Promise, "_unhandledRejectionClear", {
            value: unhandledRejectionClear
        });
    })();
    
    
    Romain CREY's avatar
    Romain CREY committed
    Promise.prototype.suppressUnhandledRejections = function() {
        var target = this._target();
        target._bitField = ((target._bitField & (~1048576)) |
                          524288);
    };
    
    Promise.prototype._ensurePossibleRejectionHandled = function () {
        if ((this._bitField & 524288) !== 0) return;
        this._setRejectionIsUnhandled();
    
        deferUnhandledRejectionCheck(this);
    
    Romain CREY's avatar
    Romain CREY committed
    };
    
    Promise.prototype._notifyUnhandledRejectionIsHandled = function () {
        fireRejectionEvent("rejectionHandled",
                                      unhandledRejectionHandled, undefined, this);
    };
    
    Promise.prototype._setReturnedNonUndefined = function() {
        this._bitField = this._bitField | 268435456;
    };
    
    Promise.prototype._returnedNonUndefined = function() {
        return (this._bitField & 268435456) !== 0;
    };
    
    Promise.prototype._notifyUnhandledRejection = function () {
        if (this._isRejectionUnhandled()) {
            var reason = this._settledValue();
            this._setUnhandledRejectionIsNotified();
            fireRejectionEvent("unhandledRejection",
                                          possiblyUnhandledRejection, reason, this);
        }
    };
    
    Promise.prototype._setUnhandledRejectionIsNotified = function () {
        this._bitField = this._bitField | 262144;
    };
    
    Promise.prototype._unsetUnhandledRejectionIsNotified = function () {
        this._bitField = this._bitField & (~262144);
    };
    
    Promise.prototype._isUnhandledRejectionNotified = function () {
        return (this._bitField & 262144) > 0;
    };
    
    Promise.prototype._setRejectionIsUnhandled = function () {
        this._bitField = this._bitField | 1048576;
    };
    
    Promise.prototype._unsetRejectionIsUnhandled = function () {
        this._bitField = this._bitField & (~1048576);
        if (this._isUnhandledRejectionNotified()) {
            this._unsetUnhandledRejectionIsNotified();
            this._notifyUnhandledRejectionIsHandled();
        }
    };
    
    Promise.prototype._isRejectionUnhandled = function () {
        return (this._bitField & 1048576) > 0;
    };
    
    Promise.prototype._warn = function(message, shouldUseOwnTrace, promise) {
        return warn(message, shouldUseOwnTrace, promise || this);
    };
    
    Promise.onPossiblyUnhandledRejection = function (fn) {
    
        var context = Promise._getContext();
        possiblyUnhandledRejection = util.contextBind(context, fn);
    
    Romain CREY's avatar
    Romain CREY committed
    };
    
    Promise.onUnhandledRejectionHandled = function (fn) {
    
        var context = Promise._getContext();
        unhandledRejectionHandled = util.contextBind(context, fn);
    
    Romain CREY's avatar
    Romain CREY committed
    };
    
    var disableLongStackTraces = function() {};
    Promise.longStackTraces = function () {
        if (async.haveItemsQueued() && !config.longStackTraces) {
            throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
        }
        if (!config.longStackTraces && longStackTracesIsSupported()) {
            var Promise_captureStackTrace = Promise.prototype._captureStackTrace;
            var Promise_attachExtraTrace = Promise.prototype._attachExtraTrace;
            var Promise_dereferenceTrace = Promise.prototype._dereferenceTrace;
            config.longStackTraces = true;
            disableLongStackTraces = function() {
                if (async.haveItemsQueued() && !config.longStackTraces) {
                    throw new Error("cannot enable long stack traces after promises have been created\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
                }
                Promise.prototype._captureStackTrace = Promise_captureStackTrace;
                Promise.prototype._attachExtraTrace = Promise_attachExtraTrace;
                Promise.prototype._dereferenceTrace = Promise_dereferenceTrace;
                Context.deactivateLongStackTraces();
                config.longStackTraces = false;
            };
            Promise.prototype._captureStackTrace = longStackTracesCaptureStackTrace;
            Promise.prototype._attachExtraTrace = longStackTracesAttachExtraTrace;
            Promise.prototype._dereferenceTrace = longStackTracesDereferenceTrace;
            Context.activateLongStackTraces();
        }
    };
    
    Promise.hasLongStackTraces = function () {
        return config.longStackTraces && longStackTracesIsSupported();
    };
    
    
    
    var legacyHandlers = {
        unhandledrejection: {
            before: function() {
                var ret = util.global.onunhandledrejection;
                util.global.onunhandledrejection = null;
                return ret;
            },
            after: function(fn) {
                util.global.onunhandledrejection = fn;
            }
        },
        rejectionhandled: {
            before: function() {
                var ret = util.global.onrejectionhandled;
                util.global.onrejectionhandled = null;
                return ret;
            },
            after: function(fn) {
                util.global.onrejectionhandled = fn;
            }
        }
    };
    
    
    Romain CREY's avatar
    Romain CREY committed
    var fireDomEvent = (function() {
    
        var dispatch = function(legacy, e) {
            if (legacy) {
                var fn;
                try {
                    fn = legacy.before();
                    return !util.global.dispatchEvent(e);
                } finally {
                    legacy.after(fn);
                }
            } else {
                return !util.global.dispatchEvent(e);
            }
        };
    
    Romain CREY's avatar
    Romain CREY committed
        try {
            if (typeof CustomEvent === "function") {
                var event = new CustomEvent("CustomEvent");
                util.global.dispatchEvent(event);
                return function(name, event) {
    
                    name = name.toLowerCase();
    
    Romain CREY's avatar
    Romain CREY committed
                    var eventData = {
                        detail: event,
                        cancelable: true
                    };
    
                    var domEvent = new CustomEvent(name, eventData);
                    es5.defineProperty(
                        domEvent, "promise", {value: event.promise});
    
    Romain CREY's avatar
    Romain CREY committed
                    es5.defineProperty(
    
                        domEvent, "reason", {value: event.reason});
    
                    return dispatch(legacyHandlers[name], domEvent);
    
    Romain CREY's avatar
    Romain CREY committed
                };
            } else if (typeof Event === "function") {
                var event = new Event("CustomEvent");
                util.global.dispatchEvent(event);
                return function(name, event) {
    
                    name = name.toLowerCase();
                    var domEvent = new Event(name, {
    
    Romain CREY's avatar
    Romain CREY committed
                        cancelable: true
                    });
                    domEvent.detail = event;
                    es5.defineProperty(domEvent, "promise", {value: event.promise});
                    es5.defineProperty(domEvent, "reason", {value: event.reason});
    
                    return dispatch(legacyHandlers[name], domEvent);
    
    Romain CREY's avatar
    Romain CREY committed
                };
            } else {
                var event = document.createEvent("CustomEvent");
                event.initCustomEvent("testingtheevent", false, true, {});
                util.global.dispatchEvent(event);
                return function(name, event) {
    
                    name = name.toLowerCase();
    
    Romain CREY's avatar
    Romain CREY committed
                    var domEvent = document.createEvent("CustomEvent");
    
                    domEvent.initCustomEvent(name, false, true,
    
    Romain CREY's avatar
    Romain CREY committed
                        event);
    
                    return dispatch(legacyHandlers[name], domEvent);
    
    Romain CREY's avatar
    Romain CREY committed
                };
            }
        } catch (e) {}
        return function() {
            return false;
        };
    })();
    
    var fireGlobalEvent = (function() {
        if (util.isNode) {
            return function() {
                return process.emit.apply(process, arguments);
            };
        } else {
            if (!util.global) {
                return function() {
                    return false;
                };
            }
            return function(name) {
                var methodName = "on" + name.toLowerCase();
                var method = util.global[methodName];
                if (!method) return false;
                method.apply(util.global, [].slice.call(arguments, 1));
                return true;
            };
        }
    })();
    
    function generatePromiseLifecycleEventObject(name, promise) {
        return {promise: promise};
    }
    
    var eventToObjectGenerator = {
        promiseCreated: generatePromiseLifecycleEventObject,
        promiseFulfilled: generatePromiseLifecycleEventObject,
        promiseRejected: generatePromiseLifecycleEventObject,
        promiseResolved: generatePromiseLifecycleEventObject,
        promiseCancelled: generatePromiseLifecycleEventObject,
        promiseChained: function(name, promise, child) {
            return {promise: promise, child: child};
        },
        warning: function(name, warning) {
            return {warning: warning};
        },
        unhandledRejection: function (name, reason, promise) {
            return {reason: reason, promise: promise};
        },
        rejectionHandled: generatePromiseLifecycleEventObject
    };
    
    var activeFireEvent = function (name) {
        var globalEventFired = false;
        try {
            globalEventFired = fireGlobalEvent.apply(null, arguments);
        } catch (e) {
            async.throwLater(e);
            globalEventFired = true;
        }
    
        var domEventFired = false;
        try {
            domEventFired = fireDomEvent(name,
                        eventToObjectGenerator[name].apply(null, arguments));
        } catch (e) {
            async.throwLater(e);
            domEventFired = true;
        }
    
        return domEventFired || globalEventFired;
    };
    
    Promise.config = function(opts) {
        opts = Object(opts);
        if ("longStackTraces" in opts) {
            if (opts.longStackTraces) {
                Promise.longStackTraces();
            } else if (!opts.longStackTraces && Promise.hasLongStackTraces()) {
                disableLongStackTraces();
            }
        }
        if ("warnings" in opts) {
            var warningsOption = opts.warnings;
            config.warnings = !!warningsOption;
            wForgottenReturn = config.warnings;
    
            if (util.isObject(warningsOption)) {
                if ("wForgottenReturn" in warningsOption) {
                    wForgottenReturn = !!warningsOption.wForgottenReturn;
                }
            }
        }
        if ("cancellation" in opts && opts.cancellation && !config.cancellation) {
            if (async.haveItemsQueued()) {
                throw new Error(
                    "cannot enable cancellation after promises are in use");
            }
            Promise.prototype._clearCancellationData =
                cancellationClearCancellationData;
            Promise.prototype._propagateFrom = cancellationPropagateFrom;
            Promise.prototype._onCancel = cancellationOnCancel;
            Promise.prototype._setOnCancel = cancellationSetOnCancel;
            Promise.prototype._attachCancellationCallback =
                cancellationAttachCancellationCallback;
            Promise.prototype._execute = cancellationExecute;
            propagateFromFunction = cancellationPropagateFrom;
            config.cancellation = true;
        }
        if ("monitoring" in opts) {
            if (opts.monitoring && !config.monitoring) {
                config.monitoring = true;
                Promise.prototype._fireEvent = activeFireEvent;
            } else if (!opts.monitoring && config.monitoring) {
                config.monitoring = false;
                Promise.prototype._fireEvent = defaultFireEvent;
            }
        }
    
        if ("asyncHooks" in opts && util.nodeSupportsAsyncResource) {
            var prev = config.asyncHooks;
            var cur = !!opts.asyncHooks;
            if (prev !== cur) {
                config.asyncHooks = cur;
                if (cur) {
                    enableAsyncHooks();
                } else {
                    disableAsyncHooks();
                }
            }
        }
    
    Romain CREY's avatar
    Romain CREY committed
    5455 5456 5457 5458 5459 5460 5461 5462 5463 5464 5465 5466 5467 5468 5469 5470 5471 5472 5473 5474 5475 5476 5477 5478 5479 5480 5481 5482 5483 5484 5485 5486 5487 5488 5489 5490 5491 5492 5493 5494 5495 5496 5497 5498 5499 5500 5501 5502 5503 5504 5505 5506 5507 5508 5509 5510 5511 5512 5513 5514 5515 5516 5517 5518 5519 5520 5521 5522 5523 5524 5525 5526 5527 5528 5529 5530 5531 5532 5533 5534 5535 5536 5537 5538 5539 5540 5541 5542 5543 5544 5545 5546 5547 5548 5549 5550 5551 5552 5553 5554 5555 5556 5557 5558 5559 5560 5561 5562 5563 5564 5565 5566 5567 5568 5569 5570 5571 5572 5573 5574 5575 5576 5577 5578 5579 5580 5581 5582 5583 5584 5585 5586 5587 5588 5589 5590 5591 5592 5593 5594 5595 5596 5597 5598 5599 5600 5601 5602 5603 5604 5605 5606 5607 5608 5609 5610 5611 5612 5613 5614 5615 5616 5617 5618 5619 5620 5621 5622 5623 5624 5625 5626 5627 5628 5629 5630 5631 5632 5633 5634 5635 5636 5637 5638 5639 5640 5641 5642 5643 5644 5645 5646 5647 5648 5649 5650 5651 5652 5653 5654 5655 5656 5657 5658 5659 5660 5661 5662 5663 5664 5665 5666 5667 5668 5669 5670 5671 5672 5673 5674 5675 5676 5677 5678 5679 5680 5681 5682 5683 5684 5685 5686 5687 5688 5689 5690 5691 5692 5693 5694 5695 5696 5697 5698 5699 5700 5701 5702 5703 5704 5705 5706 5707 5708 5709 5710 5711 5712 5713 5714 5715 5716 5717 5718 5719 5720 5721 5722 5723 5724 5725 5726 5727 5728 5729 5730 5731 5732 5733 5734 5735 5736 5737 5738 5739 5740 5741 5742 5743 5744 5745 5746 5747 5748 5749 5750 5751 5752 5753 5754 5755 5756 5757 5758 5759 5760 5761 5762 5763 5764 5765 5766 5767 5768 5769 5770 5771 5772 5773 5774 5775 5776 5777 5778 5779 5780 5781 5782 5783 5784 5785 5786 5787 5788 5789 5790 5791 5792 5793 5794 5795 5796 5797 5798 5799 5800 5801 5802 5803 5804 5805 5806 5807 5808 5809 5810 5811 5812 5813 5814 5815 5816 5817 5818 5819 5820 5821 5822 5823 5824 5825 5826 5827 5828 5829 5830 5831 5832 5833 5834 5835 5836 5837 5838 5839 5840 5841
        return Promise;
    };
    
    function defaultFireEvent() { return false; }
    
    Promise.prototype._fireEvent = defaultFireEvent;
    Promise.prototype._execute = function(executor, resolve, reject) {
        try {
            executor(resolve, reject);
        } catch (e) {
            return e;
        }
    };
    Promise.prototype._onCancel = function () {};
    Promise.prototype._setOnCancel = function (handler) { ; };
    Promise.prototype._attachCancellationCallback = function(onCancel) {
        ;
    };
    Promise.prototype._captureStackTrace = function () {};
    Promise.prototype._attachExtraTrace = function () {};
    Promise.prototype._dereferenceTrace = function () {};
    Promise.prototype._clearCancellationData = function() {};
    Promise.prototype._propagateFrom = function (parent, flags) {
        ;
        ;
    };
    
    function cancellationExecute(executor, resolve, reject) {
        var promise = this;
        try {
            executor(resolve, reject, function(onCancel) {
                if (typeof onCancel !== "function") {
                    throw new TypeError("onCancel must be a function, got: " +
                                        util.toString(onCancel));
                }
                promise._attachCancellationCallback(onCancel);
            });
        } catch (e) {
            return e;
        }
    }
    
    function cancellationAttachCancellationCallback(onCancel) {
        if (!this._isCancellable()) return this;
    
        var previousOnCancel = this._onCancel();
        if (previousOnCancel !== undefined) {
            if (util.isArray(previousOnCancel)) {
                previousOnCancel.push(onCancel);
            } else {
                this._setOnCancel([previousOnCancel, onCancel]);
            }
        } else {
            this._setOnCancel(onCancel);
        }
    }
    
    function cancellationOnCancel() {
        return this._onCancelField;
    }
    
    function cancellationSetOnCancel(onCancel) {
        this._onCancelField = onCancel;
    }
    
    function cancellationClearCancellationData() {
        this._cancellationParent = undefined;
        this._onCancelField = undefined;
    }
    
    function cancellationPropagateFrom(parent, flags) {
        if ((flags & 1) !== 0) {
            this._cancellationParent = parent;
            var branchesRemainingToCancel = parent._branchesRemainingToCancel;
            if (branchesRemainingToCancel === undefined) {
                branchesRemainingToCancel = 0;
            }
            parent._branchesRemainingToCancel = branchesRemainingToCancel + 1;
        }
        if ((flags & 2) !== 0 && parent._isBound()) {
            this._setBoundTo(parent._boundTo);
        }
    }
    
    function bindingPropagateFrom(parent, flags) {
        if ((flags & 2) !== 0 && parent._isBound()) {
            this._setBoundTo(parent._boundTo);
        }
    }
    var propagateFromFunction = bindingPropagateFrom;
    
    function boundValueFunction() {
        var ret = this._boundTo;
        if (ret !== undefined) {
            if (ret instanceof Promise) {
                if (ret.isFulfilled()) {
                    return ret.value();
                } else {
                    return undefined;
                }
            }
        }
        return ret;
    }
    
    function longStackTracesCaptureStackTrace() {
        this._trace = new CapturedTrace(this._peekContext());
    }
    
    function longStackTracesAttachExtraTrace(error, ignoreSelf) {
        if (canAttachTrace(error)) {
            var trace = this._trace;
            if (trace !== undefined) {
                if (ignoreSelf) trace = trace._parent;
            }
            if (trace !== undefined) {
                trace.attachExtraTrace(error);
            } else if (!error.__stackCleaned__) {
                var parsed = parseStackAndMessage(error);
                util.notEnumerableProp(error, "stack",
                    parsed.message + "\n" + parsed.stack.join("\n"));
                util.notEnumerableProp(error, "__stackCleaned__", true);
            }
        }
    }
    
    function longStackTracesDereferenceTrace() {
        this._trace = undefined;
    }
    
    function checkForgottenReturns(returnValue, promiseCreated, name, promise,
                                   parent) {
        if (returnValue === undefined && promiseCreated !== null &&
            wForgottenReturn) {
            if (parent !== undefined && parent._returnedNonUndefined()) return;
            if ((promise._bitField & 65535) === 0) return;
    
            if (name) name = name + " ";
            var handlerLine = "";
            var creatorLine = "";
            if (promiseCreated._trace) {
                var traceLines = promiseCreated._trace.stack.split("\n");
                var stack = cleanStack(traceLines);
                for (var i = stack.length - 1; i >= 0; --i) {
                    var line = stack[i];
                    if (!nodeFramePattern.test(line)) {
                        var lineMatches = line.match(parseLinePattern);
                        if (lineMatches) {
                            handlerLine  = "at " + lineMatches[1] +
                                ":" + lineMatches[2] + ":" + lineMatches[3] + " ";
                        }
                        break;
                    }
                }
    
                if (stack.length > 0) {
                    var firstUserLine = stack[0];
                    for (var i = 0; i < traceLines.length; ++i) {
    
                        if (traceLines[i] === firstUserLine) {
                            if (i > 0) {
                                creatorLine = "\n" + traceLines[i - 1];
                            }
                            break;
                        }
                    }
    
                }
            }
            var msg = "a promise was created in a " + name +
                "handler " + handlerLine + "but was not returned from it, " +
                "see http://goo.gl/rRqMUw" +
                creatorLine;
            promise._warn(msg, true, promiseCreated);
        }
    }
    
    function deprecated(name, replacement) {
        var message = name +
            " is deprecated and will be removed in a future version.";
        if (replacement) message += " Use " + replacement + " instead.";
        return warn(message);
    }
    
    function warn(message, shouldUseOwnTrace, promise) {
        if (!config.warnings) return;
        var warning = new Warning(message);
        var ctx;
        if (shouldUseOwnTrace) {
            promise._attachExtraTrace(warning);
        } else if (config.longStackTraces && (ctx = Promise._peekContext())) {
            ctx.attachExtraTrace(warning);
        } else {
            var parsed = parseStackAndMessage(warning);
            warning.stack = parsed.message + "\n" + parsed.stack.join("\n");
        }
    
        if (!activeFireEvent("warning", warning)) {
            formatAndLogError(warning, "", true);
        }
    }
    
    function reconstructStack(message, stacks) {
        for (var i = 0; i < stacks.length - 1; ++i) {
            stacks[i].push("From previous event:");
            stacks[i] = stacks[i].join("\n");
        }
        if (i < stacks.length) {
            stacks[i] = stacks[i].join("\n");
        }
        return message + "\n" + stacks.join("\n");
    }
    
    function removeDuplicateOrEmptyJumps(stacks) {
        for (var i = 0; i < stacks.length; ++i) {
            if (stacks[i].length === 0 ||
                ((i + 1 < stacks.length) && stacks[i][0] === stacks[i+1][0])) {
                stacks.splice(i, 1);
                i--;
            }
        }
    }
    
    function removeCommonRoots(stacks) {
        var current = stacks[0];
        for (var i = 1; i < stacks.length; ++i) {
            var prev = stacks[i];
            var currentLastIndex = current.length - 1;
            var currentLastLine = current[currentLastIndex];
            var commonRootMeetPoint = -1;
    
            for (var j = prev.length - 1; j >= 0; --j) {
                if (prev[j] === currentLastLine) {
                    commonRootMeetPoint = j;
                    break;
                }
            }
    
            for (var j = commonRootMeetPoint; j >= 0; --j) {
                var line = prev[j];
                if (current[currentLastIndex] === line) {
                    current.pop();
                    currentLastIndex--;
                } else {
                    break;
                }
            }
            current = prev;
        }
    }
    
    function cleanStack(stack) {
        var ret = [];
        for (var i = 0; i < stack.length; ++i) {
            var line = stack[i];
            var isTraceLine = "    (No stack trace)" === line ||
                stackFramePattern.test(line);
            var isInternalFrame = isTraceLine && shouldIgnore(line);
            if (isTraceLine && !isInternalFrame) {
                if (indentStackFrames && line.charAt(0) !== " ") {
                    line = "    " + line;
                }
                ret.push(line);
            }
        }
        return ret;
    }
    
    function stackFramesAsArray(error) {
        var stack = error.stack.replace(/\s+$/g, "").split("\n");
        for (var i = 0; i < stack.length; ++i) {
            var line = stack[i];
            if ("    (No stack trace)" === line || stackFramePattern.test(line)) {
                break;
            }
        }
        if (i > 0 && error.name != "SyntaxError") {
            stack = stack.slice(i);
        }
        return stack;
    }
    
    function parseStackAndMessage(error) {
        var stack = error.stack;
        var message = error.toString();
        stack = typeof stack === "string" && stack.length > 0
                    ? stackFramesAsArray(error) : ["    (No stack trace)"];
        return {
            message: message,
            stack: error.name == "SyntaxError" ? stack : cleanStack(stack)
        };
    }
    
    function formatAndLogError(error, title, isSoft) {
        if (typeof console !== "undefined") {
            var message;
            if (util.isObject(error)) {
                var stack = error.stack;
                message = title + formatStack(stack, error);
            } else {
                message = title + String(error);
            }
            if (typeof printWarning === "function") {
                printWarning(message, isSoft);
            } else if (typeof console.log === "function" ||
                typeof console.log === "object") {
                console.log(message);
            }
        }
    }
    
    function fireRejectionEvent(name, localHandler, reason, promise) {
        var localEventFired = false;
        try {
            if (typeof localHandler === "function") {
                localEventFired = true;
                if (name === "rejectionHandled") {
                    localHandler(promise);
                } else {
                    localHandler(reason, promise);
                }
            }
        } catch (e) {
            async.throwLater(e);
        }
    
        if (name === "unhandledRejection") {
            if (!activeFireEvent(name, reason, promise) && !localEventFired) {
                formatAndLogError(reason, "Unhandled rejection ");
            }
        } else {
            activeFireEvent(name, promise);
        }
    }
    
    function formatNonError(obj) {
        var str;
        if (typeof obj === "function") {
            str = "[function " +
                (obj.name || "anonymous") +
                "]";
        } else {
            str = obj && typeof obj.toString === "function"
                ? obj.toString() : util.toString(obj);
            var ruselessToString = /\[object [a-zA-Z0-9$_]+\]/;
            if (ruselessToString.test(str)) {
                try {
                    var newStr = JSON.stringify(obj);
                    str = newStr;
                }
                catch(e) {
    
                }
            }
            if (str.length === 0) {
                str = "(empty array)";
            }
        }
        return ("(<" + snip(str) + ">, no stack trace)");
    }
    
    function snip(str) {
        var maxChars = 41;
        if (str.length < maxChars) {
            return str;
        }
        return str.substr(0, maxChars - 3) + "...";
    }
    
    function longStackTracesIsSupported() {
        return typeof captureStackTrace === "function";
    }
    
    var shouldIgnore = function() { return false; };
    var parseLineInfoRegex = /[\/<\(]([^:\/]+):(\d+):(?:\d+)\)?\s*$/;
    function parseLineInfo(line) {
        var matches = line.match(parseLineInfoRegex);
        if (matches) {
            return {
                fileName: matches[1],
                line: parseInt(matches[2], 10)
            };
        }
    }
    
    function setBounds(firstLineError, lastLineError) {
        if (!longStackTracesIsSupported()) return;
    
        var firstStackLines = (firstLineError.stack || "").split("\n");
        var lastStackLines = (lastLineError.stack || "").split("\n");
    
    Romain CREY's avatar
    Romain CREY committed
        var firstIndex = -1;
        var lastIndex = -1;
        var firstFileName;
        var lastFileName;
        for (var i = 0; i < firstStackLines.length; ++i) {
            var result = parseLineInfo(firstStackLines[i]);
            if (result) {
                firstFileName = result.fileName;
                firstIndex = result.line;
                break;
            }
        }
        for (var i = 0; i < lastStackLines.length; ++i) {
            var result = parseLineInfo(lastStackLines[i]);
            if (result) {
                lastFileName = result.fileName;
                lastIndex = result.line;
                break;
            }
        }
        if (firstIndex < 0 || lastIndex < 0 || !firstFileName || !lastFileName ||
            firstFileName !== lastFileName || firstIndex >= lastIndex) {
            return;
        }
    
        shouldIgnore = function(line) {
            if (bluebirdFramePattern.test(line)) return true;
            var info = parseLineInfo(line);
            if (info) {
                if (info.fileName === firstFileName &&
                    (firstIndex <= info.line && info.line <= lastIndex)) {
                    return true;
                }
            }
            return false;
        };
    }
    
    function CapturedTrace(parent) {
        this._parent = parent;
        this._promisesCreated = 0;
        var length = this._length = 1 + (parent === undefined ? 0 : parent._length);
        captureStackTrace(this, CapturedTrace);
        if (length > 32) this.uncycle();
    }
    util.inherits(CapturedTrace, Error);
    Context.CapturedTrace = CapturedTrace;
    
    CapturedTrace.prototype.uncycle = function() {
        var length = this._length;
        if (length < 2) return;
        var nodes = [];
        var stackToIndex = {};
    
        for (var i = 0, node = this; node !== undefined; ++i) {
            nodes.push(node);
            node = node._parent;
        }
        length = this._length = i;
        for (var i = length - 1; i >= 0; --i) {
            var stack = nodes[i].stack;
            if (stackToIndex[stack] === undefined) {
                stackToIndex[stack] = i;
            }
        }
        for (var i = 0; i < length; ++i) {
            var currentStack = nodes[i].stack;
            var index = stackToIndex[currentStack];
            if (index !== undefined && index !== i) {
                if (index > 0) {
                    nodes[index - 1]._parent = undefined;
                    nodes[index - 1]._length = 1;
                }
                nodes[i]._parent = undefined;
                nodes[i]._length = 1;
                var cycleEdgeNode = i > 0 ? nodes[i - 1] : this;
    
                if (index < length - 1) {
                    cycleEdgeNode._parent = nodes[index + 1];
                    cycleEdgeNode._parent.uncycle();
                    cycleEdgeNode._length =
                        cycleEdgeNode._parent._length + 1;
                } else {
                    cycleEdgeNode._parent = undefined;
                    cycleEdgeNode._length = 1;
                }
                var currentChildLength = cycleEdgeNode._length + 1;
                for (var j = i - 2; j >= 0; --j) {
                    nodes[j]._length = currentChildLength;
                    currentChildLength++;
                }
                return;
            }
        }
    };
    
    CapturedTrace.prototype.attachExtraTrace = function(error) {
        if (error.__stackCleaned__) return;
        this.uncycle();
        var parsed = parseStackAndMessage(error);
        var message = parsed.message;
        var stacks = [parsed.stack];
    
        var trace = this;
        while (trace !== undefined) {
            stacks.push(cleanStack(trace.stack.split("\n")));
            trace = trace._parent;
        }
        removeCommonRoots(stacks);
        removeDuplicateOrEmptyJumps(stacks);
        util.notEnumerableProp(error, "stack", reconstructStack(message, stacks));
        util.notEnumerableProp(error, "__stackCleaned__", true);
    };
    
    var captureStackTrace = (function stackDetection() {
        var v8stackFramePattern = /^\s*at\s*/;
        var v8stackFormatter = function(stack, error) {
            if (typeof stack === "string") return stack;
    
            if (error.name !== undefined &&
                error.message !== undefined) {
                return error.toString();
            }
            return formatNonError(error);
        };
    
        if (typeof Error.stackTraceLimit === "number" &&
            typeof Error.captureStackTrace === "function") {
            Error.stackTraceLimit += 6;
            stackFramePattern = v8stackFramePattern;
            formatStack = v8stackFormatter;
            var captureStackTrace = Error.captureStackTrace;
    
            shouldIgnore = function(line) {
                return bluebirdFramePattern.test(line);
            };
            return function(receiver, ignoreUntil) {
                Error.stackTraceLimit += 6;
                captureStackTrace(receiver, ignoreUntil);
                Error.stackTraceLimit -= 6;
            };
        }
        var err = new Error();
    
        if (typeof err.stack === "string" &&
            err.stack.split("\n")[0].indexOf("stackDetection@") >= 0) {
            stackFramePattern = /@/;
            formatStack = v8stackFormatter;
            indentStackFrames = true;
            return function captureStackTrace(o) {
                o.stack = new Error().stack;
            };
        }
    
        var hasStackAfterThrow;
        try { throw new Error(); }
        catch(e) {