| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314 | 
							- "use strict";
 
- module.exports = function(Promise, INTERNAL) {
 
- var THIS = {};
 
- var util = require("./util");
 
- var nodebackForPromise = require("./nodeback");
 
- var withAppended = util.withAppended;
 
- var maybeWrapAsError = util.maybeWrapAsError;
 
- var canEvaluate = util.canEvaluate;
 
- var TypeError = require("./errors").TypeError;
 
- 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 (!false) {
 
- 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;
 
-         var fn = nodebackForPromise(promise, multiArgs);
 
-         try {
 
-             cb.apply(_receiver, withAppended(arguments, fn));
 
-         } catch(e) {
 
-             promise._rejectCallback(maybeWrapAsError(e), true, true);
 
-         }
 
-         if (!promise._isFateSealed()) promise._setAsyncGuaranteed();
 
-         return promise;
 
-     }
 
-     util.notEnumerableProp(promisified, "__isPromisified__", true);
 
-     return promisified;
 
- }
 
- var makeNodePromisified = canEvaluate
 
-     ? makeNodePromisifiedEval
 
-     : makeNodePromisifiedClosure;
 
- function promisifyAll(obj, suffix, filter, promisifier, multiArgs) {
 
-     var suffixRegexp = new RegExp(escapeIdentRegex(suffix) + "$");
 
-     var methods =
 
-         promisifiableMethods(obj, suffix, suffixRegexp, filter);
 
-     for (var i = 0, len = methods.length; i < len; i+= 2) {
 
-         var key = methods[i];
 
-         var fn = methods[i+1];
 
-         var promisifiedKey = key + suffix;
 
-         if (promisifier === makeNodePromisified) {
 
-             obj[promisifiedKey] =
 
-                 makeNodePromisified(key, THIS, key, fn, suffix, multiArgs);
 
-         } else {
 
-             var promisified = promisifier(fn, function() {
 
-                 return makeNodePromisified(key, THIS, key,
 
-                                            fn, suffix, multiArgs);
 
-             });
 
-             util.notEnumerableProp(promisified, "__isPromisified__", true);
 
-             obj[promisifiedKey] = promisified;
 
-         }
 
-     }
 
-     util.toFastProperties(obj);
 
-     return obj;
 
- }
 
- function promisify(callback, receiver, multiArgs) {
 
-     return makeNodePromisified(callback, receiver, undefined,
 
-                                 callback, null, multiArgs);
 
- }
 
- Promise.promisify = function (fn, options) {
 
-     if (typeof fn !== "function") {
 
-         throw new TypeError("expecting a function but got " + util.classString(fn));
 
-     }
 
-     if (isPromisified(fn)) {
 
-         return fn;
 
-     }
 
-     options = Object(options);
 
-     var receiver = options.context === undefined ? THIS : options.context;
 
-     var multiArgs = !!options.multiArgs;
 
-     var ret = promisify(fn, receiver, multiArgs);
 
-     util.copyDescriptors(fn, ret, propsFilter);
 
-     return ret;
 
- };
 
- Promise.promisifyAll = function (target, options) {
 
-     if (typeof target !== "function" && typeof target !== "object") {
 
-         throw new TypeError("the target of promisifyAll must be an object or a function\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
 
-     }
 
-     options = Object(options);
 
-     var multiArgs = !!options.multiArgs;
 
-     var suffix = options.suffix;
 
-     if (typeof suffix !== "string") suffix = defaultSuffix;
 
-     var filter = options.filter;
 
-     if (typeof filter !== "function") filter = defaultFilter;
 
-     var promisifier = options.promisifier;
 
-     if (typeof promisifier !== "function") promisifier = makeNodePromisified;
 
-     if (!util.isIdentifier(suffix)) {
 
-         throw new RangeError("suffix must be a valid identifier\u000a\u000a    See http://goo.gl/MqrFmX\u000a");
 
-     }
 
-     var keys = util.inheritedDataKeys(target);
 
-     for (var i = 0; i < keys.length; ++i) {
 
-         var value = target[keys[i]];
 
-         if (keys[i] !== "constructor" &&
 
-             util.isClass(value)) {
 
-             promisifyAll(value.prototype, suffix, filter, promisifier,
 
-                 multiArgs);
 
-             promisifyAll(value, suffix, filter, promisifier, multiArgs);
 
-         }
 
-     }
 
-     return promisifyAll(target, suffix, filter, promisifier, multiArgs);
 
- };
 
- };
 
 
  |