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 14128x 14128x 14128x 14128x 56427x 747104x 747104x 747104x 56427x 14128x 14128x 14128x 14128x 14128x 14128x 573347x 573347x 573347x 573347x 573347x 573347x 573347x 398228x 398228x 398228x 398228x 398228x 1060430x 1060430x 662472x 662472x 662472x 662472x 662472x 662472x 662472x 662472x 298195x 298195x 298195x 662472x 662472x 1060430x 364007x 364007x 1060430x 398228x 398228x 398228x 573347x 573347x 573347x 573347x 14128x 14128x 14128x | 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;
}
|