Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 14644x 14644x 14644x 14644x 58490x 761265x 761265x 761265x 58490x 14644x 14644x 14644x 14644x 14644x 14644x 580678x 580678x 580678x 580678x 580678x 580678x 580678x 394663x 394663x 394663x 394663x 394663x 1062941x 1062941x 668559x 668559x 668559x 668559x 668559x 668559x 668559x 668559x 309284x 309284x 309284x 668559x 668559x 1062941x 358994x 358994x 1062941x 394663x 394663x 394663x 580678x 580678x 580678x 580678x 14644x 14644x 14644x | const overrides = { visit() { throw new Error('Cannot call visit() during analysis'); }, stop() { throw new Error('Cannot call stop() during analysis'); } }; /** * @template {{ type: string }} T * @template U * @param {...import('zimmerframe').Visitors<T, U>} tasks * @returns */ export function merge(...tasks) { /** @type {Record<string, any[]>} */ const visitors = {}; for (const task of tasks) { for (const key in task) { if (!visitors[key]) visitors[key] = []; visitors[key].push(task[key]); } } /** @type {import('zimmerframe').Visitors<T, U>} */ // @ts-expect-error const combined = {}; for (const key in visitors) { const fns = visitors[key]; /** * @param {T} node * @param {import('zimmerframe').Context<T, U>} context */ function visitor(node, context) { /** * @param {number} i * @param {U} state */ function go(i, state) { const fn = fns[i]; if (!fn) return context.next(state); let called_next = false; fn(node, { ...context, ...overrides, state, next(next_state = state) { called_next = true; go(i + 1, next_state); } }); if (!called_next) { go(i + 1, state); } } go(0, context.state); } // @ts-expect-error combined[key] = visitor; } return combined; } |