silphius/app/astride/traverse.js

52 lines
1.6 KiB
JavaScript
Raw Normal View History

2024-06-16 08:01:01 -05:00
export const TRAVERSAL_PATH = {
2024-06-22 10:47:17 -05:00
ArrayExpression: ['elements'],
2024-06-16 08:01:01 -05:00
ArrayPattern: ['elements'],
AssignmentExpression: ['left', 'right'],
AwaitExpression: ['argument'],
BinaryExpression: ['left', 'right'],
2024-06-22 10:47:17 -05:00
BlockStatement: ['body'],
2024-07-12 18:32:55 -05:00
BreakStatement: [],
2024-06-22 10:47:17 -05:00
CallExpression: ['arguments', 'callee'],
2024-06-28 12:12:38 -05:00
ChainExpression: ['expression'],
2024-06-16 08:01:01 -05:00
ConditionalExpression: ['alternate', 'consequent', 'test'],
DoWhileStatement: ['body', 'test'],
ExpressionStatement: ['expression'],
2024-07-12 03:31:22 -05:00
ForOfStatement: ['body', 'left', 'right'],
2024-06-16 08:01:01 -05:00
ForStatement: ['body', 'init', 'test', 'update'],
Identifier: [],
IfStatement: ['alternate', 'consequent', 'test'],
MemberExpression: ['object', 'property'],
2024-06-22 10:47:17 -05:00
Literal: [],
2024-06-30 14:20:37 -05:00
LogicalExpression: ['left', 'right'],
2024-06-16 08:01:01 -05:00
ObjectExpression: ['properties'],
ObjectPattern: ['properties'],
2024-06-22 10:47:17 -05:00
Program: ['body'],
Property: ['key', 'value'],
2024-06-18 22:29:40 -05:00
ReturnStatement: ['argument'],
2024-06-22 11:43:52 -05:00
SpreadElement: ['argument'],
2024-06-16 08:01:01 -05:00
UnaryExpression: ['argument'],
UpdateExpression: ['argument'],
VariableDeclaration: ['declarations'],
VariableDeclarator: ['id', 'init'],
WhileStatement: ['body', 'test'],
};
export default function traverse(node, visitor) {
/* v8 ignore next 3 */
if (!(node.type in TRAVERSAL_PATH)) {
2024-06-22 10:47:17 -05:00
throw new Error(`node type ${node.type} not traversable. (${Object.keys(node).join(', ')})`);
2024-06-16 08:01:01 -05:00
}
visitor(node, 'enter');
const path = TRAVERSAL_PATH[node.type];
2024-06-30 14:20:37 -05:00
const children = [];
for (const key of path) {
children.push(...(Array.isArray(node[key]) ? node[key] : [node[key]]));
2024-06-16 08:01:01 -05:00
}
for (const child of children) {
if (child) {
traverse(child, visitor);
}
}
visitor(node, 'exit');
}