操作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小时内删除,严禁商用。若由于商用引起版权纠纷,一切责任均由使用者承担。
【注意:本站发布资源来源于网络搜集,均有较强时效性,请在下载前注意查看文章资源发布或更新时间,距离当前时间太久的资源不建议下载,特别是安卓专区相关资源,会有大概率失效无法使用】
评论(0)