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 14008x 14008x 14008x 14008x 55947x 728949x 728949x 728949x 55947x 14008x 14008x 14008x 14008x 14008x 14008x 568307x 568307x 568307x 568307x 568307x 568307x 568307x 395446x 395446x 395446x 395446x 395446x 1052958x 1052958x 657782x 657782x 657782x 657782x 657782x 657782x 657782x 657782x 296018x 296018x 296018x 657782x 657782x 1052958x 361494x 361494x 1052958x 395446x 395446x 395446x 568307x 568307x 568307x 568307x 14008x 14008x 14008x | 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;
}
|