createWrapper.js 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. var baseSetData = require('./baseSetData'),
  2. createBindWrapper = require('./createBindWrapper'),
  3. createHybridWrapper = require('./createHybridWrapper'),
  4. createPartialWrapper = require('./createPartialWrapper'),
  5. getData = require('./getData'),
  6. mergeData = require('./mergeData'),
  7. setData = require('./setData');
  8. /** Used to compose bitmasks for wrapper metadata. */
  9. var BIND_FLAG = 1,
  10. BIND_KEY_FLAG = 2,
  11. PARTIAL_FLAG = 32,
  12. PARTIAL_RIGHT_FLAG = 64;
  13. /** Used as the `TypeError` message for "Functions" methods. */
  14. var FUNC_ERROR_TEXT = 'Expected a function';
  15. /* Native method references for those with the same name as other `lodash` methods. */
  16. var nativeMax = Math.max;
  17. /**
  18. * Creates a function that either curries or invokes `func` with optional
  19. * `this` binding and partially applied arguments.
  20. *
  21. * @private
  22. * @param {Function|string} func The function or method name to reference.
  23. * @param {number} bitmask The bitmask of flags.
  24. * The bitmask may be composed of the following flags:
  25. * 1 - `_.bind`
  26. * 2 - `_.bindKey`
  27. * 4 - `_.curry` or `_.curryRight` of a bound function
  28. * 8 - `_.curry`
  29. * 16 - `_.curryRight`
  30. * 32 - `_.partial`
  31. * 64 - `_.partialRight`
  32. * 128 - `_.rearg`
  33. * 256 - `_.ary`
  34. * @param {*} [thisArg] The `this` binding of `func`.
  35. * @param {Array} [partials] The arguments to be partially applied.
  36. * @param {Array} [holders] The `partials` placeholder indexes.
  37. * @param {Array} [argPos] The argument positions of the new function.
  38. * @param {number} [ary] The arity cap of `func`.
  39. * @param {number} [arity] The arity of `func`.
  40. * @returns {Function} Returns the new wrapped function.
  41. */
  42. function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) {
  43. var isBindKey = bitmask & BIND_KEY_FLAG;
  44. if (!isBindKey && typeof func != 'function') {
  45. throw new TypeError(FUNC_ERROR_TEXT);
  46. }
  47. var length = partials ? partials.length : 0;
  48. if (!length) {
  49. bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG);
  50. partials = holders = undefined;
  51. }
  52. length -= (holders ? holders.length : 0);
  53. if (bitmask & PARTIAL_RIGHT_FLAG) {
  54. var partialsRight = partials,
  55. holdersRight = holders;
  56. partials = holders = undefined;
  57. }
  58. var data = isBindKey ? undefined : getData(func),
  59. newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity];
  60. if (data) {
  61. mergeData(newData, data);
  62. bitmask = newData[1];
  63. arity = newData[9];
  64. }
  65. newData[9] = arity == null
  66. ? (isBindKey ? 0 : func.length)
  67. : (nativeMax(arity - length, 0) || 0);
  68. if (bitmask == BIND_FLAG) {
  69. var result = createBindWrapper(newData[0], newData[2]);
  70. } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) {
  71. result = createPartialWrapper.apply(undefined, newData);
  72. } else {
  73. result = createHybridWrapper.apply(undefined, newData);
  74. }
  75. var setter = data ? baseSetData : setData;
  76. return setter(result, newData);
  77. }
  78. module.exports = createWrapper;