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 14572x 14572x 14572x 14572x 58202x 757161x 757161x 757161x 58202x 14572x 14572x 14572x 14572x 14572x 14572x 577582x 577582x 577582x 577582x 577582x 577582x 577582x 392491x 392491x 392491x 392491x 392491x 1057123x 1057123x 664913x 664913x 664913x 664913x 664913x 664913x 664913x 664913x 307530x 307530x 307530x 664913x 664913x 1057123x 357102x 357102x 1057123x 392491x 392491x 392491x 577582x 577582x 577582x 577582x 14572x 14572x 14572x | 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; } |