| "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 = require("./util"); |
| var canEvaluate = util.canEvaluate; |
| var isIdentifier = util.isIdentifier; |
| |
| var getMethodCaller; |
| var getGetter; |
| if (!false) { |
| 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 (!false) { |
| 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); |
| }; |
| }; |