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.
123 lines
4.3 KiB
123 lines
4.3 KiB
"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); |
|
}; |
|
};
|
|
|