You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					1010 lines
				
				31 KiB
			
		
		
			
		
	
	
					1010 lines
				
				31 KiB
			| 
											3 years ago
										 | "use strict"; | ||
|  | module.exports = function(Promise, Context, | ||
|  |     enableAsyncHooks, disableAsyncHooks) { | ||
|  | var async = Promise._async; | ||
|  | var Warning = require("./errors").Warning; | ||
|  | var util = require("./util"); | ||
|  | var es5 = require("./es5"); | ||
|  | 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 | ||
|  |     }); | ||
|  | })(); | ||
|  | 
 | ||
|  | 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); | ||
|  | }; | ||
|  | 
 | ||
|  | 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); | ||
|  | }; | ||
|  | 
 | ||
|  | Promise.onUnhandledRejectionHandled = function (fn) { | ||
|  |     var context = Promise._getContext(); | ||
|  |     unhandledRejectionHandled = util.contextBind(context, fn); | ||
|  | }; | ||
|  | 
 | ||
|  | 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; | ||
|  |         } | ||
|  |     } | ||
|  | }; | ||
|  | 
 | ||
|  | 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); | ||
|  |         } | ||
|  |     }; | ||
|  |     try { | ||
|  |         if (typeof CustomEvent === "function") { | ||
|  |             var event = new CustomEvent("CustomEvent"); | ||
|  |             util.global.dispatchEvent(event); | ||
|  |             return function(name, event) { | ||
|  |                 name = name.toLowerCase(); | ||
|  |                 var eventData = { | ||
|  |                     detail: event, | ||
|  |                     cancelable: true | ||
|  |                 }; | ||
|  |                 var domEvent = new CustomEvent(name, eventData); | ||
|  |                 es5.defineProperty( | ||
|  |                     domEvent, "promise", {value: event.promise}); | ||
|  |                 es5.defineProperty( | ||
|  |                     domEvent, "reason", {value: event.reason}); | ||
|  | 
 | ||
|  |                 return dispatch(legacyHandlers[name], domEvent); | ||
|  |             }; | ||
|  |         } 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, { | ||
|  |                     cancelable: true | ||
|  |                 }); | ||
|  |                 domEvent.detail = event; | ||
|  |                 es5.defineProperty(domEvent, "promise", {value: event.promise}); | ||
|  |                 es5.defineProperty(domEvent, "reason", {value: event.reason}); | ||
|  |                 return dispatch(legacyHandlers[name], domEvent); | ||
|  |             }; | ||
|  |         } else { | ||
|  |             var event = document.createEvent("CustomEvent"); | ||
|  |             event.initCustomEvent("testingtheevent", false, true, {}); | ||
|  |             util.global.dispatchEvent(event); | ||
|  |             return function(name, event) { | ||
|  |                 name = name.toLowerCase(); | ||
|  |                 var domEvent = document.createEvent("CustomEvent"); | ||
|  |                 domEvent.initCustomEvent(name, false, true, | ||
|  |                     event); | ||
|  |                 return dispatch(legacyHandlers[name], domEvent); | ||
|  |             }; | ||
|  |         } | ||
|  |     } 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(); | ||
|  |             } | ||
|  |         } | ||
|  |     } | ||
|  |     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"); | ||
|  |     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) { | ||
|  |         hasStackAfterThrow = ("stack" in e); | ||
|  |     } | ||
|  |     if (!("stack" in err) && hasStackAfterThrow && | ||
|  |         typeof Error.stackTraceLimit === "number") { | ||
|  |         stackFramePattern = v8stackFramePattern; | ||
|  |         formatStack = v8stackFormatter; | ||
|  |         return function captureStackTrace(o) { | ||
|  |             Error.stackTraceLimit += 6; | ||
|  |             try { throw new Error(); } | ||
|  |             catch(e) { o.stack = e.stack; } | ||
|  |             Error.stackTraceLimit -= 6; | ||
|  |         }; | ||
|  |     } | ||
|  | 
 | ||
|  |     formatStack = function(stack, error) { | ||
|  |         if (typeof stack === "string") return stack; | ||
|  | 
 | ||
|  |         if ((typeof error === "object" || | ||
|  |             typeof error === "function") && | ||
|  |             error.name !== undefined && | ||
|  |             error.message !== undefined) { | ||
|  |             return error.toString(); | ||
|  |         } | ||
|  |         return formatNonError(error); | ||
|  |     }; | ||
|  | 
 | ||
|  |     return null; | ||
|  | 
 | ||
|  | })([]); | ||
|  | 
 | ||
|  | if (typeof console !== "undefined" && typeof console.warn !== "undefined") { | ||
|  |     printWarning = function (message) { | ||
|  |         console.warn(message); | ||
|  |     }; | ||
|  |     if (util.isNode && process.stderr.isTTY) { | ||
|  |         printWarning = function(message, isSoft) { | ||
|  |             var color = isSoft ? "\u001b[33m" : "\u001b[31m"; | ||
|  |             console.warn(color + message + "\u001b[0m\n"); | ||
|  |         }; | ||
|  |     } else if (!util.isNode && typeof (new Error().stack) === "string") { | ||
|  |         printWarning = function(message, isSoft) { | ||
|  |             console.warn("%c" + message, | ||
|  |                         isSoft ? "color: darkorange" : "color: red"); | ||
|  |         }; | ||
|  |     } | ||
|  | } | ||
|  | 
 | ||
|  | var config = { | ||
|  |     warnings: warnings, | ||
|  |     longStackTraces: false, | ||
|  |     cancellation: false, | ||
|  |     monitoring: false, | ||
|  |     asyncHooks: false | ||
|  | }; | ||
|  | 
 | ||
|  | if (longStackTraces) Promise.longStackTraces(); | ||
|  | 
 | ||
|  | return { | ||
|  |     asyncHooks: function() { | ||
|  |         return config.asyncHooks; | ||
|  |     }, | ||
|  |     longStackTraces: function() { | ||
|  |         return config.longStackTraces; | ||
|  |     }, | ||
|  |     warnings: function() { | ||
|  |         return config.warnings; | ||
|  |     }, | ||
|  |     cancellation: function() { | ||
|  |         return config.cancellation; | ||
|  |     }, | ||
|  |     monitoring: function() { | ||
|  |         return config.monitoring; | ||
|  |     }, | ||
|  |     propagateFromFunction: function() { | ||
|  |         return propagateFromFunction; | ||
|  |     }, | ||
|  |     boundValueFunction: function() { | ||
|  |         return boundValueFunction; | ||
|  |     }, | ||
|  |     checkForgottenReturns: checkForgottenReturns, | ||
|  |     setBounds: setBounds, | ||
|  |     warn: warn, | ||
|  |     deprecated: deprecated, | ||
|  |     CapturedTrace: CapturedTrace, | ||
|  |     fireDomEvent: fireDomEvent, | ||
|  |     fireGlobalEvent: fireGlobalEvent | ||
|  | }; | ||
|  | }; |