AST基础知识|babel库中path常用方法总结

关注它,不迷路。       

本文章中所有内容仅供学习交流,不可用于任何商业用途和非法用途,否则后果自负,如有侵权,请联系作者立即删除!

1. path源码学习:

path相关的源代码在这个js文件中,大家可以直接照着源码学习:

\node_modules\@babel\traverse\lib\path

当然,第一个需要学习的文件应该是这个:

node_modules\@babel\traverse\lib\path\index.js

在本文中,选出部分常用的方法大家参考,更多的知识请自行学习源码。

2. path常用方法介绍

path.toString  

用来获取当前遍历path的js源代码,调用方式:

let sourceCode = path.toString();

这个非常有用,经常用于定于插件遍历的path,以便分析问题。如果想通过 path.node来获取源代码,可以使用 generator 函数来获取:

let sourceCode = generator(path.node).code;

path.replaceWith 

(单)节点替换函数,调用方式:

path.replaceWith(newNode);

实参一般是 node 类型,即将当前遍历的path替换为 实参里的 新节点。

注意,它不能用于 Array 的替换,即实参不能是Array类型。

path.replaceWithMultiple

(多)节点替换函数,调用方式:

path.rreplaceWithMultiple(ArrayNode);

实参一般是 Array 类型,它只能用于 Array 的替换。即所有需要替换的节点在一个Array里面,常见的替换如 Block 类型节点里的 body.body。

path.remove

节点的删除,调用方式:

path.remove();

直接调用即可将当前遍历的所有符合条件的路径全部删除,所以使用的时候需要注意。

path.insertBefore

在当前节点前面插入新的节点。调用方式:

path.insertBefore(newNode);

path.insertAfter

在当前节点后面插入新的节点。调用方式:

path.insertAfter(newNode);

path.traverse

在当前节点下遍历其他的节点,比如有如下for循环:

for(;;)
{a = b;b = c;c =d;
}

想要遍历这个for循环下面的 赋值语句,可以借助该函数进行遍历:

const visitFor = 
{ForStatement(path){......path.traverse({AssignmentExpression(_path){......},}),......},
}

path.get

获取当前路径下的子孙节点。调用方式:

let newPath = path.get(key)

形参key是一个字符串,以 . 隔开。  其源代码:

function get(key, context) {if (context === true) context = this.context;const parts = key.split(".");if (parts.length === 1) {return this._getKey(key, context);} else {return this._getPattern(parts, context);}}

假如当前的代码如下:

var a = 1;

你遍历了  VariableDeclaration 类型,想要获取 右边的这个 1,可以写如下代码:

const visitVar = 
{VariableDeclaration(path){let initPath = path.get('declarations.0.init');......},
}

path.getSibling

根据key值来获取节点,这个方法我很少用,大家可以试试。

path.getPrevSibling

获取当前path的前一个兄弟节点,返回的是path类型。

path.getAllPrevSiblings

获取当前path的所有前兄弟节点,返回的是Array类型,其元素都是path类型。

path.getNextSibling

获取当前path的后一个兄弟节点,返回的是path类型。

path.getAllNextSiblings

获取当前path的所有后兄弟节点,返回的是Array类型,其元素都是path类型。

path.evaluate

用于计算表达式的值,大家可以参考 constantFold 插件的写法。

https://wx.zsxq.com/dweb2/index/topic_detail/185515841482512

path.findParent

向上查找满足回调函数特征的path,即判断上级路径是否包含有XXX类型的节点:

function findParent(callback) {let path = this;while (path = path.parentPath) {if (callback(path)) return path;}return null;}

很简单,先从父级节点开始进行遍历,然后一直循环,直到满足回调函数的条件为止。如果找不到则返回null。回调函数怎么写,可以参考下面的代码:

function getFunctionParent() {return this.findParent(p => p.isFunction());}

path.find

功能与 path.findParent 方法一样,只不过从当前path开始进行遍历。

path.getFunctionParent

获取函数类型父节点,如果不存在,返回 null。

path.getStatementParent

获取Statement类型父节点,这个基本上都会有返回值,如果当前遍历的是 Program 或者 File 节点,则会报错。

path.getAncestry

获取所有的祖先节点,没有实参,返回的是一个Array对象。源码也很简单:

function getAncestry() {let path = this;const paths = [];do {paths.push(path);} while (path = path.parentPath);return paths;}

path.isAncestor

判断当前遍历的节点是否为实参的祖先节点,调用方式:

path.isAncestor(maybeDescendant)

实参传入 path 类型即可。

path.isDescendant

判断当前遍历的节点是否为实参的子孙节点,调用方式:

path.isDescendant(maybeAncestor)

实参传入 path 类型即可。

今天的文章就分享到这里,后续分享更多的技巧,敬请期待。

d4c5b96e138a5dacd2782b87414af72d.jpeg

欢迎加入知识星球,学习更多AST和爬虫技巧。


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部