124 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			124 lines
		
	
	
		
			4.3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
"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);
 | 
						|
};
 | 
						|
};
 |