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 74 | 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 2x 15241x 15241x 15241x 15241x 60872x 846112x 846112x 846112x 60872x 15241x 15241x 15241x 15241x 15241x 15241x 611985x 611985x 611985x 611985x 611985x 611985x 611985x 418301x 418301x 418301x 418301x 418301x 1129359x 1129359x 711351x 711351x 711351x 711351x 711351x 711351x 711351x 711351x 329232x 329232x 329232x 711351x 711351x 1129359x 381826x 381826x 1129359x 418301x 418301x 418301x 611985x 611985x 611985x 611985x 15241x 15241x 15241x | /** @import { Visitors, Context } from 'zimmerframe' */ 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 {...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 {Visitors<T, U>} */ // @ts-expect-error const combined = {}; for (const key in visitors) { const fns = visitors[key]; /** * @param {T} node * @param {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; } |