(h, built, fields, args)
| 71 | }; |
| 72 | |
| 73 | export const evaluate = (h, built, fields, args) => { |
| 74 | let tmp; |
| 75 | |
| 76 | // `build()` used the first element of the operation list as |
| 77 | // temporary workspace. Now that `build()` is done we can use |
| 78 | // that space to track whether the current element is "dynamic" |
| 79 | // (i.e. it or any of its descendants depend on dynamic values). |
| 80 | built[0] = 0; |
| 81 | |
| 82 | for (let i = 1; i < built.length; i++) { |
| 83 | const type = built[i++]; |
| 84 | |
| 85 | // Set `built[0]`'s appropriate bits if this element depends on a dynamic value. |
| 86 | const value = built[i] ? ((built[0] |= type ? 1 : 2), fields[built[i++]]) : built[++i]; |
| 87 | |
| 88 | if (type === TAG_SET) { |
| 89 | args[0] = value; |
| 90 | } |
| 91 | else if (type === PROPS_ASSIGN) { |
| 92 | args[1] = Object.assign(args[1] || {}, value); |
| 93 | } |
| 94 | else if (type === PROP_SET) { |
| 95 | (args[1] = args[1] || {})[built[++i]] = value; |
| 96 | } |
| 97 | else if (type === PROP_APPEND) { |
| 98 | args[1][built[++i]] += (value + ''); |
| 99 | } |
| 100 | else if (type) { // type === CHILD_RECURSE |
| 101 | // Set the operation list (including the staticness bits) as |
| 102 | // `this` for the `h` call. |
| 103 | tmp = h.apply(value, evaluate(h, value, fields, ['', null])); |
| 104 | args.push(tmp); |
| 105 | |
| 106 | if (value[0]) { |
| 107 | // Set the 2nd lowest bit it the child element is dynamic. |
| 108 | built[0] |= 2; |
| 109 | } |
| 110 | else { |
| 111 | // Rewrite the operation list in-place if the child element is static. |
| 112 | // The currently evaluated piece `CHILD_RECURSE, 0, [...]` becomes |
| 113 | // `CHILD_APPEND, 0, tmp`. |
| 114 | // Essentially the operation list gets optimized for potential future |
| 115 | // re-evaluations. |
| 116 | built[i-2] = CHILD_APPEND; |
| 117 | built[i] = tmp; |
| 118 | } |
| 119 | } |
| 120 | else { // type === CHILD_APPEND |
| 121 | args.push(value); |
| 122 | } |
| 123 | } |
| 124 | |
| 125 | return args; |
| 126 | }; |
| 127 | |
| 128 | export const build = function(statics) { |
| 129 | const fields = arguments; |
no outgoing calls
no test coverage detected
searching dependent graphs…