Skip to content
Snippets Groups Projects
index.js 8.75 MiB
Newer Older
  • Learn to ignore specific revisions
  • Romain CREY's avatar
    Romain CREY committed
        limit = typeof limit === "number" &&
            isFinite(limit) && limit >= 1 ? limit : 0;
        return new MappingPromiseArray(promises, fn, limit, _filter).promise();
    }
    
    Promise.prototype.map = function (fn, options) {
        return map(this, fn, options, null);
    };
    
    Promise.map = function (promises, fn, options, _filter) {
        return map(promises, fn, options, _filter);
    };
    
    
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    var cr = Object.create;
    if (cr) {
        var callerCache = cr(null);
        var getterCache = cr(null);
        callerCache[" size"] = getterCache[" size"] = 0;
    }
    
    module.exports = function(Promise) {
    
    var util = __webpack_require__(27);
    
    Romain CREY's avatar
    Romain CREY committed
    var canEvaluate = util.canEvaluate;
    var isIdentifier = util.isIdentifier;
    
    var getMethodCaller;
    var getGetter;
    if (true) {
    var makeMethodCaller = function (methodName) {
        return new Function("ensureMethod", "                                    \n\
            return function(obj) {                                               \n\
                'use strict'                                                     \n\
                var len = this.length;                                           \n\
                ensureMethod(obj, 'methodName');                                 \n\
                switch(len) {                                                    \n\
                    case 1: return obj.methodName(this[0]);                      \n\
                    case 2: return obj.methodName(this[0], this[1]);             \n\
                    case 3: return obj.methodName(this[0], this[1], this[2]);    \n\
                    case 0: return obj.methodName();                             \n\
                    default:                                                     \n\
                        return obj.methodName.apply(obj, this);                  \n\
                }                                                                \n\
            };                                                                   \n\
            ".replace(/methodName/g, methodName))(ensureMethod);
    };
    
    var makeGetter = function (propertyName) {
        return new Function("obj", "                                             \n\
            'use strict';                                                        \n\
            return obj.propertyName;                                             \n\
            ".replace("propertyName", propertyName));
    };
    
    var getCompiled = function(name, compiler, cache) {
        var ret = cache[name];
        if (typeof ret !== "function") {
            if (!isIdentifier(name)) {
                return null;
            }
            ret = compiler(name);
            cache[name] = ret;
            cache[" size"]++;
            if (cache[" size"] > 512) {
                var keys = Object.keys(cache);
                for (var i = 0; i < 256; ++i) delete cache[keys[i]];
                cache[" size"] = keys.length - 256;
            }
        }
        return ret;
    };
    
    getMethodCaller = function(name) {
        return getCompiled(name, makeMethodCaller, callerCache);
    };
    
    getGetter = function(name) {
        return getCompiled(name, makeGetter, getterCache);
    };
    }
    
    function ensureMethod(obj, methodName) {
        var fn;
        if (obj != null) fn = obj[methodName];
        if (typeof fn !== "function") {
            var message = "Object " + util.classString(obj) + " has no method '" +
                util.toString(methodName) + "'";
            throw new Promise.TypeError(message);
        }
        return fn;
    }
    
    function caller(obj) {
        var methodName = this.pop();
        var fn = ensureMethod(obj, methodName);
        return fn.apply(obj, this);
    }
    Promise.prototype.call = function (methodName) {
        var $_len = arguments.length;var args = new Array(Math.max($_len - 1, 0)); for(var $_i = 1; $_i < $_len; ++$_i) {args[$_i - 1] = arguments[$_i];};
        if (true) {
            if (canEvaluate) {
                var maybeCaller = getMethodCaller(methodName);
                if (maybeCaller !== null) {
                    return this._then(
                        maybeCaller, undefined, undefined, args, undefined);
                }
            }
        }
        args.push(methodName);
        return this._then(caller, undefined, undefined, args, undefined);
    };
    
    function namedGetter(obj) {
        return obj[this];
    }
    function indexedGetter(obj) {
        var index = +this;
        if (index < 0) index = Math.max(0, index + obj.length);
        return obj[index];
    }
    Promise.prototype.get = function (propertyName) {
        var isIndex = (typeof propertyName === "number");
        var getter;
        if (!isIndex) {
            if (canEvaluate) {
                var maybeGetter = getGetter(propertyName);
                getter = maybeGetter !== null ? maybeGetter : namedGetter;
            } else {
                getter = namedGetter;
            }
        } else {
            getter = indexedGetter;
        }
        return this._then(getter, undefined, undefined, propertyName, undefined);
    };
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function (Promise, apiRejection, tryConvertToPromise,
        createContext, INTERNAL, debug) {
    
        var util = __webpack_require__(27);
        var TypeError = __webpack_require__(32).TypeError;
        var inherits = __webpack_require__(27).inherits;
    
    Romain CREY's avatar
    Romain CREY committed
        var errorObj = util.errorObj;
        var tryCatch = util.tryCatch;
        var NULL = {};
    
        function thrower(e) {
            setTimeout(function(){throw e;}, 0);
        }
    
        function castPreservingDisposable(thenable) {
            var maybePromise = tryConvertToPromise(thenable);
            if (maybePromise !== thenable &&
                typeof thenable._isDisposable === "function" &&
                typeof thenable._getDisposer === "function" &&
                thenable._isDisposable()) {
                maybePromise._setDisposable(thenable._getDisposer());
            }
            return maybePromise;
        }
        function dispose(resources, inspection) {
            var i = 0;
            var len = resources.length;
            var ret = new Promise(INTERNAL);
            function iterator() {
                if (i >= len) return ret._fulfill();
                var maybePromise = castPreservingDisposable(resources[i++]);
                if (maybePromise instanceof Promise &&
                    maybePromise._isDisposable()) {
                    try {
                        maybePromise = tryConvertToPromise(
                            maybePromise._getDisposer().tryDispose(inspection),
                            resources.promise);
                    } catch (e) {
                        return thrower(e);
                    }
                    if (maybePromise instanceof Promise) {
                        return maybePromise._then(iterator, thrower,
                                                  null, null, null);
                    }
                }
                iterator();
            }
            iterator();
            return ret;
        }
    
        function Disposer(data, promise, context) {
            this._data = data;
            this._promise = promise;
            this._context = context;
        }
    
        Disposer.prototype.data = function () {
            return this._data;
        };
    
        Disposer.prototype.promise = function () {
            return this._promise;
        };
    
        Disposer.prototype.resource = function () {
            if (this.promise().isFulfilled()) {
                return this.promise().value();
            }
            return NULL;
        };
    
        Disposer.prototype.tryDispose = function(inspection) {
            var resource = this.resource();
            var context = this._context;
            if (context !== undefined) context._pushContext();
            var ret = resource !== NULL
                ? this.doDispose(resource, inspection) : null;
            if (context !== undefined) context._popContext();
            this._promise._unsetDisposable();
            this._data = null;
            return ret;
        };
    
        Disposer.isDisposer = function (d) {
            return (d != null &&
                    typeof d.resource === "function" &&
                    typeof d.tryDispose === "function");
        };
    
        function FunctionDisposer(fn, promise, context) {
            this.constructor$(fn, promise, context);
        }
        inherits(FunctionDisposer, Disposer);
    
        FunctionDisposer.prototype.doDispose = function (resource, inspection) {
            var fn = this.data();
            return fn.call(resource, resource, inspection);
        };
    
        function maybeUnwrapDisposer(value) {
            if (Disposer.isDisposer(value)) {
                this.resources[this.index]._setDisposable(value);
                return value.promise();
            }
            return value;
        }
    
        function ResourceList(length) {
            this.length = length;
            this.promise = null;
            this[length-1] = null;
        }
    
        ResourceList.prototype._resultCancelled = function() {
            var len = this.length;
            for (var i = 0; i < len; ++i) {
                var item = this[i];
                if (item instanceof Promise) {
                    item.cancel();
                }
            }
        };
    
        Promise.using = function () {
            var len = arguments.length;
            if (len < 2) return apiRejection(
                            "you must pass at least 2 arguments to Promise.using");
            var fn = arguments[len - 1];
            if (typeof fn !== "function") {
                return apiRejection("expecting a function but got " + util.classString(fn));
            }
            var input;
            var spreadArgs = true;
            if (len === 2 && Array.isArray(arguments[0])) {
                input = arguments[0];
                len = input.length;
                spreadArgs = false;
            } else {
                input = arguments;
                len--;
            }
            var resources = new ResourceList(len);
            for (var i = 0; i < len; ++i) {
                var resource = input[i];
                if (Disposer.isDisposer(resource)) {
                    var disposer = resource;
                    resource = resource.promise();
                    resource._setDisposable(disposer);
                } else {
                    var maybePromise = tryConvertToPromise(resource);
                    if (maybePromise instanceof Promise) {
                        resource =
                            maybePromise._then(maybeUnwrapDisposer, null, null, {
                                resources: resources,
                                index: i
                        }, undefined);
                    }
                }
                resources[i] = resource;
            }
    
            var reflectedResources = new Array(resources.length);
            for (var i = 0; i < reflectedResources.length; ++i) {
                reflectedResources[i] = Promise.resolve(resources[i]).reflect();
            }
    
            var resultPromise = Promise.all(reflectedResources)
                .then(function(inspections) {
                    for (var i = 0; i < inspections.length; ++i) {
                        var inspection = inspections[i];
                        if (inspection.isRejected()) {
                            errorObj.e = inspection.error();
                            return errorObj;
                        } else if (!inspection.isFulfilled()) {
                            resultPromise.cancel();
                            return;
                        }
                        inspections[i] = inspection.value();
                    }
                    promise._pushContext();
    
                    fn = tryCatch(fn);
                    var ret = spreadArgs
                        ? fn.apply(undefined, inspections) : fn(inspections);
                    var promiseCreated = promise._popContext();
                    debug.checkForgottenReturns(
                        ret, promiseCreated, "Promise.using", promise);
                    return ret;
                });
    
            var promise = resultPromise.lastly(function() {
                var inspection = new Promise.PromiseInspection(resultPromise);
                return dispose(resources, inspection);
            });
            resources.promise = promise;
            promise._setOnCancel(resources);
            return promise;
        };
    
        Promise.prototype._setDisposable = function (disposer) {
            this._bitField = this._bitField | 131072;
            this._disposer = disposer;
        };
    
        Promise.prototype._isDisposable = function () {
            return (this._bitField & 131072) > 0;
        };
    
        Promise.prototype._getDisposer = function () {
            return this._disposer;
        };
    
        Promise.prototype._unsetDisposable = function () {
            this._bitField = this._bitField & (~131072);
            this._disposer = undefined;
        };
    
        Promise.prototype.disposer = function (fn) {
            if (typeof fn === "function") {
                return new FunctionDisposer(fn, this, createContext());
            }
            throw new TypeError();
        };
    
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function(Promise, INTERNAL, debug) {
    
    var util = __webpack_require__(27);
    
    Romain CREY's avatar
    Romain CREY committed
    var TimeoutError = Promise.TimeoutError;
    
    function HandleWrapper(handle)  {
        this.handle = handle;
    }
    
    HandleWrapper.prototype._resultCancelled = function() {
        clearTimeout(this.handle);
    };
    
    var afterValue = function(value) { return delay(+this).thenReturn(value); };
    var delay = Promise.delay = function (ms, value) {
        var ret;
        var handle;
        if (value !== undefined) {
            ret = Promise.resolve(value)
                    ._then(afterValue, null, null, ms, undefined);
            if (debug.cancellation() && value instanceof Promise) {
                ret._setOnCancel(value);
            }
        } else {
            ret = new Promise(INTERNAL);
            handle = setTimeout(function() { ret._fulfill(); }, +ms);
            if (debug.cancellation()) {
                ret._setOnCancel(new HandleWrapper(handle));
            }
            ret._captureStackTrace();
        }
        ret._setAsyncGuaranteed();
        return ret;
    };
    
    Promise.prototype.delay = function (ms) {
        return delay(ms, this);
    };
    
    var afterTimeout = function (promise, message, parent) {
        var err;
        if (typeof message !== "string") {
            if (message instanceof Error) {
                err = message;
            } else {
                err = new TimeoutError("operation timed out");
            }
        } else {
            err = new TimeoutError(message);
        }
        util.markAsOriginatingFromRejection(err);
        promise._attachExtraTrace(err);
        promise._reject(err);
    
        if (parent != null) {
            parent.cancel();
        }
    };
    
    function successClear(value) {
        clearTimeout(this.handle);
        return value;
    }
    
    function failureClear(reason) {
        clearTimeout(this.handle);
        throw reason;
    }
    
    Promise.prototype.timeout = function (ms, message) {
        ms = +ms;
        var ret, parent;
    
        var handleWrapper = new HandleWrapper(setTimeout(function timeoutTimeout() {
            if (ret.isPending()) {
                afterTimeout(ret, message, parent);
            }
        }, ms));
    
        if (debug.cancellation()) {
            parent = this.then();
            ret = parent._then(successClear, failureClear,
                                undefined, handleWrapper, undefined);
            ret._setOnCancel(handleWrapper);
        } else {
            ret = this._then(successClear, failureClear,
                                undefined, handleWrapper, undefined);
        }
    
        return ret;
    };
    
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function(Promise,
                              apiRejection,
                              INTERNAL,
                              tryConvertToPromise,
                              Proxyable,
                              debug) {
    
    var errors = __webpack_require__(32);
    
    Romain CREY's avatar
    Romain CREY committed
    var TypeError = errors.TypeError;
    
    var util = __webpack_require__(27);
    
    Romain CREY's avatar
    Romain CREY committed
    var errorObj = util.errorObj;
    var tryCatch = util.tryCatch;
    var yieldHandlers = [];
    
    function promiseFromYieldHandler(value, yieldHandlers, traceParent) {
        for (var i = 0; i < yieldHandlers.length; ++i) {
            traceParent._pushContext();
            var result = tryCatch(yieldHandlers[i])(value);
            traceParent._popContext();
            if (result === errorObj) {
                traceParent._pushContext();
                var ret = Promise.reject(errorObj.e);
                traceParent._popContext();
                return ret;
            }
            var maybePromise = tryConvertToPromise(result, traceParent);
            if (maybePromise instanceof Promise) return maybePromise;
        }
        return null;
    }
    
    function PromiseSpawn(generatorFunction, receiver, yieldHandler, stack) {
        if (debug.cancellation()) {
            var internal = new Promise(INTERNAL);
            var _finallyPromise = this._finallyPromise = new Promise(INTERNAL);
            this._promise = internal.lastly(function() {
                return _finallyPromise;
            });
            internal._captureStackTrace();
            internal._setOnCancel(this);
        } else {
            var promise = this._promise = new Promise(INTERNAL);
            promise._captureStackTrace();
        }
        this._stack = stack;
        this._generatorFunction = generatorFunction;
        this._receiver = receiver;
        this._generator = undefined;
        this._yieldHandlers = typeof yieldHandler === "function"
            ? [yieldHandler].concat(yieldHandlers)
            : yieldHandlers;
        this._yieldedPromise = null;
        this._cancellationPhase = false;
    }
    util.inherits(PromiseSpawn, Proxyable);
    
    PromiseSpawn.prototype._isResolved = function() {
        return this._promise === null;
    };
    
    PromiseSpawn.prototype._cleanup = function() {
        this._promise = this._generator = null;
        if (debug.cancellation() && this._finallyPromise !== null) {
            this._finallyPromise._fulfill();
            this._finallyPromise = null;
        }
    };
    
    PromiseSpawn.prototype._promiseCancelled = function() {
        if (this._isResolved()) return;
        var implementsReturn = typeof this._generator["return"] !== "undefined";
    
        var result;
        if (!implementsReturn) {
            var reason = new Promise.CancellationError(
                "generator .return() sentinel");
            Promise.coroutine.returnSentinel = reason;
            this._promise._attachExtraTrace(reason);
            this._promise._pushContext();
            result = tryCatch(this._generator["throw"]).call(this._generator,
                                                             reason);
            this._promise._popContext();
        } else {
            this._promise._pushContext();
            result = tryCatch(this._generator["return"]).call(this._generator,
                                                              undefined);
            this._promise._popContext();
        }
        this._cancellationPhase = true;
        this._yieldedPromise = null;
        this._continue(result);
    };
    
    PromiseSpawn.prototype._promiseFulfilled = function(value) {
        this._yieldedPromise = null;
        this._promise._pushContext();
        var result = tryCatch(this._generator.next).call(this._generator, value);
        this._promise._popContext();
        this._continue(result);
    };
    
    PromiseSpawn.prototype._promiseRejected = function(reason) {
        this._yieldedPromise = null;
        this._promise._attachExtraTrace(reason);
        this._promise._pushContext();
        var result = tryCatch(this._generator["throw"])
            .call(this._generator, reason);
        this._promise._popContext();
        this._continue(result);
    };
    
    PromiseSpawn.prototype._resultCancelled = function() {
        if (this._yieldedPromise instanceof Promise) {
            var promise = this._yieldedPromise;
            this._yieldedPromise = null;
            promise.cancel();
        }
    };
    
    PromiseSpawn.prototype.promise = function () {
        return this._promise;
    };
    
    PromiseSpawn.prototype._run = function () {
        this._generator = this._generatorFunction.call(this._receiver);
        this._receiver =
            this._generatorFunction = undefined;
        this._promiseFulfilled(undefined);
    };
    
    PromiseSpawn.prototype._continue = function (result) {
        var promise = this._promise;
        if (result === errorObj) {
            this._cleanup();
            if (this._cancellationPhase) {
                return promise.cancel();
            } else {
                return promise._rejectCallback(result.e, false);
            }
        }
    
        var value = result.value;
        if (result.done === true) {
            this._cleanup();
            if (this._cancellationPhase) {
                return promise.cancel();
            } else {
                return promise._resolveCallback(value);
            }
        } else {
            var maybePromise = tryConvertToPromise(value, this._promise);
            if (!(maybePromise instanceof Promise)) {
                maybePromise =
                    promiseFromYieldHandler(maybePromise,
                                            this._yieldHandlers,
                                            this._promise);
                if (maybePromise === null) {
                    this._promiseRejected(
                        new TypeError(
                            "A value %s was yielded that could not be treated as a promise\u000a\u000a    See http://goo.gl/MqrFmX\u000a\u000a".replace("%s", String(value)) +
                            "From coroutine:\u000a" +
                            this._stack.split("\n").slice(1, -7).join("\n")
                        )
                    );
                    return;
                }
            }
            maybePromise = maybePromise._target();
            var bitField = maybePromise._bitField;
            ;
            if (((bitField & 50397184) === 0)) {
                this._yieldedPromise = maybePromise;
                maybePromise._proxy(this, null);
            } else if (((bitField & 33554432) !== 0)) {
                Promise._async.invoke(
                    this._promiseFulfilled, this, maybePromise._value()
                );
            } else if (((bitField & 16777216) !== 0)) {
                Promise._async.invoke(
                    this._promiseRejected, this, maybePromise._reason()
                );
            } else {
                this._promiseCancelled();
            }
        }
    };
    
    Promise.coroutine = function (generatorFunction, options) {
        if (typeof generatorFunction !== "function") {
            throw new TypeError("generatorFunction must be a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
        }
        var yieldHandler = Object(options).yieldHandler;
        var PromiseSpawn$ = PromiseSpawn;
        var stack = new Error().stack;
        return function () {
            var generator = generatorFunction.apply(this, arguments);
            var spawn = new PromiseSpawn$(undefined, undefined, yieldHandler,
                                          stack);
            var ret = spawn.promise();
            spawn._generator = generator;
            spawn._promiseFulfilled(undefined);
            return ret;
        };
    };
    
    Promise.coroutine.addYieldHandler = function(fn) {
        if (typeof fn !== "function") {
            throw new TypeError("expecting a function but got " + util.classString(fn));
        }
        yieldHandlers.push(fn);
    };
    
    Promise.spawn = function (generatorFunction) {
        debug.deprecated("Promise.spawn()", "Promise.coroutine()");
        if (typeof generatorFunction !== "function") {
            return apiRejection("generatorFunction must be a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
        }
        var spawn = new PromiseSpawn(generatorFunction, this);
        var ret = spawn.promise();
        spawn._run(Promise.spawn);
        return ret;
    };
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function(Promise) {
    
    var util = __webpack_require__(27);
    
    Romain CREY's avatar
    Romain CREY committed
    var async = Promise._async;
    var tryCatch = util.tryCatch;
    var errorObj = util.errorObj;
    
    function spreadAdapter(val, nodeback) {
        var promise = this;
        if (!util.isArray(val)) return successAdapter.call(promise, val, nodeback);
        var ret =
            tryCatch(nodeback).apply(promise._boundValue(), [null].concat(val));
        if (ret === errorObj) {
            async.throwLater(ret.e);
        }
    }
    
    function successAdapter(val, nodeback) {
        var promise = this;
        var receiver = promise._boundValue();
        var ret = val === undefined
            ? tryCatch(nodeback).call(receiver, null)
            : tryCatch(nodeback).call(receiver, null, val);
        if (ret === errorObj) {
            async.throwLater(ret.e);
        }
    }
    function errorAdapter(reason, nodeback) {
        var promise = this;
        if (!reason) {
            var newReason = new Error(reason + "");
            newReason.cause = reason;
            reason = newReason;
        }
        var ret = tryCatch(nodeback).call(promise._boundValue(), reason);
        if (ret === errorObj) {
            async.throwLater(ret.e);
        }
    }
    
    Promise.prototype.asCallback = Promise.prototype.nodeify = function (nodeback,
                                                                         options) {
        if (typeof nodeback == "function") {
            var adapter = successAdapter;
            if (options !== undefined && Object(options).spread) {
                adapter = spreadAdapter;
            }
            this._then(
                adapter,
                errorAdapter,
                undefined,
                this,
                nodeback
            );
        }
        return this;
    };
    };
    
    
    /***/ }),
    
    Romain CREY's avatar
    Romain CREY committed
    /***/ (function(module, exports, __webpack_require__) {
    
    "use strict";
    
    module.exports = function(Promise, INTERNAL) {
    var THIS = {};
    
    var util = __webpack_require__(27);
    var nodebackForPromise = __webpack_require__(39);
    
    Romain CREY's avatar
    Romain CREY committed
    var withAppended = util.withAppended;
    var maybeWrapAsError = util.maybeWrapAsError;
    var canEvaluate = util.canEvaluate;
    
    var TypeError = __webpack_require__(32).TypeError;
    
    Romain CREY's avatar
    Romain CREY committed
    var defaultSuffix = "Async";
    var defaultPromisified = {__isPromisified__: true};
    var noCopyProps = [
        "arity",    "length",
        "name",
        "arguments",
        "caller",
        "callee",
        "prototype",
        "__isPromisified__"
    ];
    var noCopyPropsPattern = new RegExp("^(?:" + noCopyProps.join("|") + ")$");
    
    var defaultFilter = function(name) {
        return util.isIdentifier(name) &&
            name.charAt(0) !== "_" &&
            name !== "constructor";
    };
    
    function propsFilter(key) {
        return !noCopyPropsPattern.test(key);
    }
    
    function isPromisified(fn) {
        try {
            return fn.__isPromisified__ === true;
        }
        catch (e) {
            return false;
        }
    }
    
    function hasPromisified(obj, key, suffix) {
        var val = util.getDataPropertyOrDefault(obj, key + suffix,
                                                defaultPromisified);
        return val ? isPromisified(val) : false;
    }
    function checkValid(ret, suffix, suffixRegexp) {
        for (var i = 0; i < ret.length; i += 2) {
            var key = ret[i];
            if (suffixRegexp.test(key)) {
                var keyWithoutAsyncSuffix = key.replace(suffixRegexp, "");
                for (var j = 0; j < ret.length; j += 2) {
                    if (ret[j] === keyWithoutAsyncSuffix) {
                        throw new TypeError("Cannot promisify an API that has normal methods with '%s'-suffix\u000a\u000a    See http://goo.gl/MqrFmX\u000a"
                            .replace("%s", suffix));
                    }
                }
            }
        }
    }
    
    function promisifiableMethods(obj, suffix, suffixRegexp, filter) {
        var keys = util.inheritedDataKeys(obj);
        var ret = [];
        for (var i = 0; i < keys.length; ++i) {
            var key = keys[i];
            var value = obj[key];
            var passesDefaultFilter = filter === defaultFilter
                ? true : defaultFilter(key, value, obj);
            if (typeof value === "function" &&
                !isPromisified(value) &&
                !hasPromisified(obj, key, suffix) &&
                filter(key, value, obj, passesDefaultFilter)) {
                ret.push(key, value);
            }
        }
        checkValid(ret, suffix, suffixRegexp);
        return ret;
    }
    
    var escapeIdentRegex = function(str) {
        return str.replace(/([$])/, "\\$");
    };
    
    var makeNodePromisifiedEval;
    if (true) {
    var switchCaseArgumentOrder = function(likelyArgumentCount) {
        var ret = [likelyArgumentCount];
        var min = Math.max(0, likelyArgumentCount - 1 - 3);
        for(var i = likelyArgumentCount - 1; i >= min; --i) {
            ret.push(i);
        }
        for(var i = likelyArgumentCount + 1; i <= 3; ++i) {
            ret.push(i);
        }
        return ret;
    };
    
    var argumentSequence = function(argumentCount) {
        return util.filledRange(argumentCount, "_arg", "");
    };
    
    var parameterDeclaration = function(parameterCount) {
        return util.filledRange(
            Math.max(parameterCount, 3), "_arg", "");
    };
    
    var parameterCount = function(fn) {
        if (typeof fn.length === "number") {
            return Math.max(Math.min(fn.length, 1023 + 1), 0);
        }
        return 0;
    };
    
    makeNodePromisifiedEval =
    function(callback, receiver, originalName, fn, _, multiArgs) {
        var newParameterCount = Math.max(0, parameterCount(fn) - 1);
        var argumentOrder = switchCaseArgumentOrder(newParameterCount);
        var shouldProxyThis = typeof callback === "string" || receiver === THIS;
    
        function generateCallForArgumentCount(count) {
            var args = argumentSequence(count).join(", ");
            var comma = count > 0 ? ", " : "";
            var ret;
            if (shouldProxyThis) {
                ret = "ret = callback.call(this, {{args}}, nodeback); break;\n";
            } else {
                ret = receiver === undefined
                    ? "ret = callback({{args}}, nodeback); break;\n"
                    : "ret = callback.call(receiver, {{args}}, nodeback); break;\n";
            }
            return ret.replace("{{args}}", args).replace(", ", comma);
        }
    
        function generateArgumentSwitchCase() {
            var ret = "";
            for (var i = 0; i < argumentOrder.length; ++i) {
                ret += "case " + argumentOrder[i] +":" +
                    generateCallForArgumentCount(argumentOrder[i]);
            }
    
            ret += "                                                             \n\
            default:                                                             \n\
                var args = new Array(len + 1);                                   \n\
                var i = 0;                                                       \n\
                for (var i = 0; i < len; ++i) {                                  \n\
                   args[i] = arguments[i];                                       \n\
                }                                                                \n\
                args[i] = nodeback;                                              \n\
                [CodeForCall]                                                    \n\
                break;                                                           \n\
            ".replace("[CodeForCall]", (shouldProxyThis
                                    ? "ret = callback.apply(this, args);\n"
                                    : "ret = callback.apply(receiver, args);\n"));
            return ret;
        }
    
        var getFunctionCode = typeof callback === "string"
                                    ? ("this != null ? this['"+callback+"'] : fn")
                                    : "fn";
        var body = "'use strict';                                                \n\
            var ret = function (Parameters) {                                    \n\
                'use strict';                                                    \n\
                var len = arguments.length;                                      \n\
                var promise = new Promise(INTERNAL);                             \n\
                promise._captureStackTrace();                                    \n\
                var nodeback = nodebackForPromise(promise, " + multiArgs + ");   \n\
                var ret;                                                         \n\
                var callback = tryCatch([GetFunctionCode]);                      \n\
                switch(len) {                                                    \n\
                    [CodeForSwitchCase]                                          \n\
                }                                                                \n\
                if (ret === errorObj) {                                          \n\
                    promise._rejectCallback(maybeWrapAsError(ret.e), true, true);\n\
                }                                                                \n\
                if (!promise._isFateSealed()) promise._setAsyncGuaranteed();     \n\
                return promise;                                                  \n\
            };                                                                   \n\
            notEnumerableProp(ret, '__isPromisified__', true);                   \n\
            return ret;                                                          \n\
        ".replace("[CodeForSwitchCase]", generateArgumentSwitchCase())
            .replace("[GetFunctionCode]", getFunctionCode);
        body = body.replace("Parameters", parameterDeclaration(newParameterCount));
        return new Function("Promise",
                            "fn",
                            "receiver",
                            "withAppended",
                            "maybeWrapAsError",
                            "nodebackForPromise",
                            "tryCatch",
                            "errorObj",
                            "notEnumerableProp",
                            "INTERNAL",
                            body)(
                        Promise,
                        fn,
                        receiver,
                        withAppended,
                        maybeWrapAsError,
                        nodebackForPromise,
                        util.tryCatch,
                        util.errorObj,
                        util.notEnumerableProp,
                        INTERNAL);
    };
    }
    
    function makeNodePromisifiedClosure(callback, receiver, _, fn, __, multiArgs) {
        var defaultThis = (function() {return this;})();
        var method = callback;
        if (typeof method === "string") {
            callback = fn;
        }
        function promisified() {
            var _receiver = receiver;
            if (receiver === THIS) _receiver = this;
            var promise = new Promise(INTERNAL);
            promise._captureStackTrace();
            var cb = typeof method === "string" && this !== defaultThis
                ? this[method] : callback;