solidity-antlr4
Version:
Solidity Lang Lexer and Parser by official ANTLR4 grammar
81 lines (80 loc) • 2.58 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.traverse = traverse;
var _lodashEs = require("lodash-es");
var _base = require("../ast/base.cjs");
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 ((0, _base.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 ((0, _base.isSyntaxNode)(tree)) {
let node = (0, _lodashEs.clone)(tree);
const rewrite = newNode => {
node = newNode;
};
const matches = filter => (0, _lodashEs.matches)(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 (!(0, _base.isSyntaxNode)(node)) return node;
const keys = (0, _base.keysInNode)(node);
for (let index = 0; index < keys.length; index += 1) {
const valueInKey = node[keys[index]];
if ((0, _base.isSyntaxNode)(valueInKey) || (0, _base.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);
}