call_get.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. "use strict";
  2. var cr = Object.create;
  3. if (cr) {
  4. var callerCache = cr(null);
  5. var getterCache = cr(null);
  6. callerCache[" size"] = getterCache[" size"] = 0;
  7. }
  8. module.exports = function(Promise) {
  9. var util = require("./util");
  10. var canEvaluate = util.canEvaluate;
  11. var isIdentifier = util.isIdentifier;
  12. var getMethodCaller;
  13. var getGetter;
  14. if (!false) {
  15. var makeMethodCaller = function (methodName) {
  16. return new Function("ensureMethod", " \n\
  17. return function(obj) { \n\
  18. 'use strict' \n\
  19. var len = this.length; \n\
  20. ensureMethod(obj, 'methodName'); \n\
  21. switch(len) { \n\
  22. case 1: return obj.methodName(this[0]); \n\
  23. case 2: return obj.methodName(this[0], this[1]); \n\
  24. case 3: return obj.methodName(this[0], this[1], this[2]); \n\
  25. case 0: return obj.methodName(); \n\
  26. default: \n\
  27. return obj.methodName.apply(obj, this); \n\
  28. } \n\
  29. }; \n\
  30. ".replace(/methodName/g, methodName))(ensureMethod);
  31. };
  32. var makeGetter = function (propertyName) {
  33. return new Function("obj", " \n\
  34. 'use strict'; \n\
  35. return obj.propertyName; \n\
  36. ".replace("propertyName", propertyName));
  37. };
  38. var getCompiled = function(name, compiler, cache) {
  39. var ret = cache[name];
  40. if (typeof ret !== "function") {
  41. if (!isIdentifier(name)) {
  42. return null;
  43. }
  44. ret = compiler(name);
  45. cache[name] = ret;
  46. cache[" size"]++;
  47. if (cache[" size"] > 512) {
  48. var keys = Object.keys(cache);
  49. for (var i = 0; i < 256; ++i) delete cache[keys[i]];
  50. cache[" size"] = keys.length - 256;
  51. }
  52. }
  53. return ret;
  54. };
  55. getMethodCaller = function(name) {
  56. return getCompiled(name, makeMethodCaller, callerCache);
  57. };
  58. getGetter = function(name) {
  59. return getCompiled(name, makeGetter, getterCache);
  60. };
  61. }
  62. function ensureMethod(obj, methodName) {
  63. var fn;
  64. if (obj != null) fn = obj[methodName];
  65. if (typeof fn !== "function") {
  66. var message = "Object " + util.classString(obj) + " has no method '" +
  67. util.toString(methodName) + "'";
  68. throw new Promise.TypeError(message);
  69. }
  70. return fn;
  71. }
  72. function caller(obj) {
  73. var methodName = this.pop();
  74. var fn = ensureMethod(obj, methodName);
  75. return fn.apply(obj, this);
  76. }
  77. Promise.prototype.call = function (methodName) {
  78. 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];};
  79. if (!false) {
  80. if (canEvaluate) {
  81. var maybeCaller = getMethodCaller(methodName);
  82. if (maybeCaller !== null) {
  83. return this._then(
  84. maybeCaller, undefined, undefined, args, undefined);
  85. }
  86. }
  87. }
  88. args.push(methodName);
  89. return this._then(caller, undefined, undefined, args, undefined);
  90. };
  91. function namedGetter(obj) {
  92. return obj[this];
  93. }
  94. function indexedGetter(obj) {
  95. var index = +this;
  96. if (index < 0) index = Math.max(0, index + obj.length);
  97. return obj[index];
  98. }
  99. Promise.prototype.get = function (propertyName) {
  100. var isIndex = (typeof propertyName === "number");
  101. var getter;
  102. if (!isIndex) {
  103. if (canEvaluate) {
  104. var maybeGetter = getGetter(propertyName);
  105. getter = maybeGetter !== null ? maybeGetter : namedGetter;
  106. } else {
  107. getter = namedGetter;
  108. }
  109. } else {
  110. getter = indexedGetter;
  111. }
  112. return this._then(getter, undefined, undefined, propertyName, undefined);
  113. };
  114. };