操作AST主要方法
添加节点
替换节点
删除节点
添加节点
function visitCallback(node, parent, key, index) {
node.foo = createNewNode();
}
如果节点是一个数组:
function visitCallback(node, parent, key, index) {
node.foo.push(createNewNode());
}
如果要将节点添加为兄弟节点,那就需要访问它的父节点:
function visitCallback(node, parent, key, index) {
// 插入到最前
parent[key].unshift(createNewNode());
// 添加到最后
parent[key].push(createNewNode());
// 插入到当前节点之后
parent[key].splice(index + 1, 0, createNewNode());
// 添加到当前节点之前
parent[key].splice(index, 0, createNewNode());
}
替换节点
要将当前节点替换为另一个节点,需要更新当前节点的父节点的 key 属性
function visitCallback(node, parent, key, index) {
parent[key] = updatedNode();
}
如果父节点是数组:
function visitCallback(node, parent, key, index) {
parent[key][index] = updatedNode();
}
删除节点
要删除当前节点,需要删除当前节点父节点的 key 属性
function visitCallback(node, parent, key, index) {
delete parent[key];
}
如果父节点是数组:
function visitCallback(node, parent, key, index) {
parent[key].splice(index, 1);
}
注意:所有操作完成后,需要确保遍历的正常进行,对于作为其父键的属性的节点,添加、替换和删除它们通常是可以的。除了替换操作,你可能需要重新访问“当前节点”,即新的替换节点。
但是,对于数组中的节点,需要特别注意更新循环的数组索引:
function visit(ast, callbackMap) {
function _visit(node, parent, key, index) {
// ...
if (Array.isArray(child)) {
for (let j = 0; j < child.length; j++) {
_visit(child[j], node, key, j);
if (hasRemoved()) {
j--;
}
}
}
// ...
}
}
怎么判断当前节点是否被删除呢?
function visit(ast, callbackMap) {
function _visit(node, parent, key, index) {
let _hasRemoved = false;
const _this = {
//不需要node,parent
remove() {
_hasRemoved = true;
// 继续删除当前节点
},
};
// ...
if (nodeType in callbackMap) {
callbackMap[nodeType].call(_this, node, parent, key, index);
}
}
}
function visitCallback(node, parent, key, index) {
this.remove();
}
声明:①本站为个人博客,博客所发布的一切修改补丁、注册机和注册信息及软件的文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。②本站信息来自网络,版权争议与本站无关,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。访问和下载本站内容,说明您已同意上述条款。③本站为非盈利性站点,VIP功能仅仅作为用户喜欢本站捐赠打赏功能,不开通VIP同样可以通过每日签到免费获取积分下载所有软件资源,本站不贩卖软件,所有内容不作为商业行为。