UNPKG

solidity-antlr4

Version:

Solidity Lang Lexer and Parser by official ANTLR4 grammar

81 lines (80 loc) 2.5 kB
import { clone, matches as lodashMatches } from "lodash-es"; import { isSyntaxNode, isSyntaxNodeList, keysInNode } from "../ast/base.js"; export function traverse(astOrPath, callback) { let ast; let globalParentPath = null; if (astOrPath.type && !astOrPath.matches) { ast = astOrPath; } else { ast = astOrPath.node; globalParentPath = astOrPath; } let shouldStop = false; const stop = () => { shouldStop = true; }; const traverseInner = (tree, parentPath) => { const depth = parentPath?.depth !== void 0 ? parentPath.depth + 1 : 0; if (isSyntaxNodeList(tree)) { const nodeList = []; for (let index = 0; index < tree.length; index += 1) { if (shouldStop) break; nodeList.push(traverseInner(tree[index], parentPath)); } return nodeList; } else if (isSyntaxNode(tree)) { let node = clone(tree); const rewrite = (newNode) => { node = newNode; }; const matches = (filter) => lodashMatches(filter)(node); const getFlattenParents = (maxDepth = Number.MAX_SAFE_INTEGER) => { const nodes = []; const recursion = (p) => { if (p.parentPath && nodes.length < maxDepth) { nodes.unshift(p.parentPath.node); recursion(p.parentPath); } }; recursion(path); return nodes; }; const checkOffset = (offset) => { if (offset === void 0) return true; return node.range[0] <= offset && offset <= node.range[1]; }; const path = { path: [parentPath?.path, node.type].filter((t) => t !== void 0 && t !== null).join("."), depth, node, parentPath, stop, rewrite, getFlattenParents, matches, checkOffset }; const exitCallback = callback(path); if (shouldStop) return node; if (!isSyntaxNode(node)) return node; const keys = keysInNode(node); for (let index = 0; index < keys.length; index += 1) { const valueInKey = node[keys[index]]; if (isSyntaxNode(valueInKey) || isSyntaxNodeList(valueInKey)) { node[keys[index]] = traverseInner(valueInKey, path); } else { node[keys[index]] = valueInKey; } } if (exitCallback && typeof exitCallback === "function") exitCallback(); return node; } return tree; }; return traverseInner(ast, globalParentPath); }