Projekt

Obecné

Profil

Stáhnout (3.18 KB) Statistiky
| Větev: | Revize:
1
var composeArgs = require('./_composeArgs'),
2
    composeArgsRight = require('./_composeArgsRight'),
3
    countHolders = require('./_countHolders'),
4
    createCtor = require('./_createCtor'),
5
    createRecurry = require('./_createRecurry'),
6
    getHolder = require('./_getHolder'),
7
    reorder = require('./_reorder'),
8
    replaceHolders = require('./_replaceHolders'),
9
    root = require('./_root');
10

    
11
/** Used to compose bitmasks for function metadata. */
12
var WRAP_BIND_FLAG = 1,
13
    WRAP_BIND_KEY_FLAG = 2,
14
    WRAP_CURRY_FLAG = 8,
15
    WRAP_CURRY_RIGHT_FLAG = 16,
16
    WRAP_ARY_FLAG = 128,
17
    WRAP_FLIP_FLAG = 512;
18

    
19
/**
20
 * Creates a function that wraps `func` to invoke it with optional `this`
21
 * binding of `thisArg`, partial application, and currying.
22
 *
23
 * @private
24
 * @param {Function|string} func The function or method name to wrap.
25
 * @param {number} bitmask The bitmask flags. See `createWrap` for more details.
26
 * @param {*} [thisArg] The `this` binding of `func`.
27
 * @param {Array} [partials] The arguments to prepend to those provided to
28
 *  the new function.
29
 * @param {Array} [holders] The `partials` placeholder indexes.
30
 * @param {Array} [partialsRight] The arguments to append to those provided
31
 *  to the new function.
32
 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes.
33
 * @param {Array} [argPos] The argument positions of the new function.
34
 * @param {number} [ary] The arity cap of `func`.
35
 * @param {number} [arity] The arity of `func`.
36
 * @returns {Function} Returns the new wrapped function.
37
 */
38
function createHybrid(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) {
39
  var isAry = bitmask & WRAP_ARY_FLAG,
40
      isBind = bitmask & WRAP_BIND_FLAG,
41
      isBindKey = bitmask & WRAP_BIND_KEY_FLAG,
42
      isCurried = bitmask & (WRAP_CURRY_FLAG | WRAP_CURRY_RIGHT_FLAG),
43
      isFlip = bitmask & WRAP_FLIP_FLAG,
44
      Ctor = isBindKey ? undefined : createCtor(func);
45

    
46
  function wrapper() {
47
    var length = arguments.length,
48
        args = Array(length),
49
        index = length;
50

    
51
    while (index--) {
52
      args[index] = arguments[index];
53
    }
54
    if (isCurried) {
55
      var placeholder = getHolder(wrapper),
56
          holdersCount = countHolders(args, placeholder);
57
    }
58
    if (partials) {
59
      args = composeArgs(args, partials, holders, isCurried);
60
    }
61
    if (partialsRight) {
62
      args = composeArgsRight(args, partialsRight, holdersRight, isCurried);
63
    }
64
    length -= holdersCount;
65
    if (isCurried && length < arity) {
66
      var newHolders = replaceHolders(args, placeholder);
67
      return createRecurry(
68
        func, bitmask, createHybrid, wrapper.placeholder, thisArg,
69
        args, newHolders, argPos, ary, arity - length
70
      );
71
    }
72
    var thisBinding = isBind ? thisArg : this,
73
        fn = isBindKey ? thisBinding[func] : func;
74

    
75
    length = args.length;
76
    if (argPos) {
77
      args = reorder(args, argPos);
78
    } else if (isFlip && length > 1) {
79
      args.reverse();
80
    }
81
    if (isAry && ary < length) {
82
      args.length = ary;
83
    }
84
    if (this && this !== root && this instanceof wrapper) {
85
      fn = Ctor || createCtor(fn);
86
    }
87
    return fn.apply(thisBinding, args);
88
  }
89
  return wrapper;
90
}
91

    
92
module.exports = createHybrid;
(169-169/590)