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 13953x 13953x 13953x 13953x 55727x 711981x 711981x 711981x 55727x 13953x 13953x 13953x 13953x 13953x 13953x 556750x 556750x 556750x 556750x 556750x 556750x 556750x 382494x 382494x 382494x 382494x 382494x 1015081x 1015081x 632853x 632853x 632853x 632853x 632853x 632853x 632853x 632853x 282943x 282943x 282943x 632853x 632853x 1015081x 349644x 349644x 1015081x 382494x 382494x 382494x 556750x 556750x 556750x 556750x 13953x 13953x 13953x | 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;
}
|