# 参考文档

深入学习 JavaScript 转译器 Babel ，AST还原混淆代码

https://blog.csdn.net/weixin_52057903/article/details/129131582

babel文档

https://babeljs.io/docs/babel-types

# 操作AST语法树babel库中path全部方法和属性

## path 属性

`path`属性相关的源代码在如下js文件中

```javascript
\node_modules\@babel\traverse\lib\path
```

**下面是一些常见的path对象的属性API：**

| api                            | 功能                                                                 |
|--------------------------------|--------------------------------------------------------------------|
| path.node                      | 获取当前路径对应的节点。                                                       |
| path.parent                    | 获取当前路径对应节点的父节点。                                                    |
| path.parentPath                | 获取当前路径对应节点的父路径。                                                    |
| path.scope                     | 表示当前path下的作用域，这个也是写插件经常会用到的。                                       |
| path.container                 | 用于获取当前path下的所有兄弟节点(包括自身)。                                          |
| path.type                      | 获取当前path的节点类型。                                                     |
| path.key                       | 获取当前path的key值，key通常用于path.get函数。                                   |

## path 方法

`path`方法相关的源代码在如下js文件中

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

**下面是一些常见的path对象的方法API：**

| api                                | 功能                                                                 |
|------------------------------------|--------------------------------------------------------------------|
| path.get(key)                      | 获取当前路径下指定属性名（key）对应的子路径。例如，path.get("body") 获取当前路径下名为 "body" 的子路径。 |
| path.getSibling(index)             | 获取当前路径对应节点的兄弟节点的路径。通过指定索引（index）可以获取相应的兄弟路径。                       |
| path.getFunctionParent()           | 获取当前路径对应节点的最近的函数父节点的路径。                                            |
| path.getPrevSibling()              | 获取当前path的前一个兄弟节点，返回的是path类型。                                       |
| path.getAllPrevSiblings()          | 获取当前path的所有前兄弟节点，返回的是Array类型，其元素都是path类型。                          |
| path.getNextSibling()              | 获取当前path的后一个兄弟节点，返回的是path类型。                                       |
| path.getAllNextSiblings()          | 获取当前path的所有后兄弟节点，返回的是Array类型，其元素都是path类型。                          |
| path.evaluate()                    | 用于计算表达式的值，大家可以参考 constantFold 插件的写法。                               |
| path.findParent()                  | 向上查找满足回调函数特征的path，即判断上级路径是否包含有XXX类型的节点。                            |
| path.find()                        | 功能与 path.findParent 方法一样，只不过从当前path开始进行遍历。                         |
| path.getFunctionParent()           | 获取函数类型父节点，如果不存在，返回 null。                                           |
| path.getStatementParent()          | 获取Statement类型父节点，这个基本上都会有返回值，如果当前遍历的是 Program 或者 File 节点，则会报错。     |
| path.getAncestry()                 | 获取所有的祖先节点，没有实参，返回的是一个Array对象。                                      |
| path.isAncestor(maybeDescendant)   | 判断当前遍历的节点是否为实参的祖先节点.                                               |
| path.isDescendant(maybeAncestor)   | 判断当前遍历的节点是否为实参的子孙节点.                                               |
| path.traverse(visitor)             | 遍历当前路径下的所有子节点，并应用指定的 visitor。                                      |
| path.replaceWith(node)             | 用指定的节点替换当前路径对应的节点。                                                 |
| path.remove()                      | 从 AST 中移除当前路径对应的节点。                                                |
| path.insertBefore(nodes)           | 在当前路径对应节点之前插入一个或多个节点。                                              |
| path.insertAfter(nodes)            | 在当前路径对应节点之后插入一个或多个节点。                                              | 
| path.toString()                    | 用于将 AST 节点转换回对应的源代码字符串。                                            |

## node 节点

看语法就可以猜到`node`就是path的一个属性

| api                               | 功能                                   |
|:----------------------------------|--------------------------------------|
| path.node.type                    | 获取当前节点的类型。                           |
| path.node.declarations            | 对于 VariableDeclaration 节点, 获取变量声明列表。 |
| path.node.init.value                   | 获取某个节点的值。                            |
| delete path.node.init;            | 删除节点，使用系统的 delete 方法。                |

## AST 节点类型对照表

| 序号 | 类型原名称                | 中文名称      | 描述                                         |
|----|----------------------|-----------|--------------------------------------------|
| 1  | Program              | 程序主体      | 整段代码的主体                                    |
| 2  | VariableDeclaration  | 变量声明      | 声明一个变量，例如 var let const                    |
| 3  | FunctionDeclaration  | 函数声明      | 声明一个函数，例如 function                         |
| 4  | ExpressionStatement  | 表达式语句     | 通常是调用一个函数，例如 console.log()                 |
| 5  | BlockStatement       | 块语句       | 包裹在 {} 块内的代码，例如 if (condition){var a = 1;} |
| 6  | BreakStatement       | 中断语句      | 通常指 break                                  |
| 7  | ContinueStatement    | 持续语句      | 通常指 continue                               |
| 8  | ReturnStatement      | 返回语句      | 通常指 return                                 |
| 9  | SwitchStatement      | Switch 语句 | 通常指 Switch Case 语句中的 Switch                |
| 10 | IfStatement          | If 控制流语句  | 控制流语句，通常指 if(condition){}else{}            |
| 11 | Identifier           | 标识符       | 标识，例如声明变量时 var identi = 5 中的 identi        |
| 12 | CallExpression       | 调用表达式     | 通常指调用一个函数，例如 console.log()                 |
| 13 | BinaryExpression     | 二进制表达式    | 通常指运算，例如 1+2                               |
| 14 | MemberExpression     | 成员表达式     | 通常指调用对象的成员，例如 console 对象的 log 成员           |
| 15 | ArrayExpression      | 数组表达式     | 通常指一个数组，例如 [1, 3, 5]                       |
| 16 | NewExpression        | New 表达式   | 通常指使用 New 关键词                              |
| 17 | AssignmentExpression | 赋值表达式     | 通常指将函数的返回值赋值给变量                            |
| 18 | UpdateExpression     | 更新表达式     | 通常指更新成员值，例如 i++                            |
| 19 | Literal              | 字面量       | 字面量                                        |
| 20 | BooleanLiteral       | 布尔型字面量    | 布尔值，例如 true false                          |
| 21 | NumericLiteral       | 数字型字面量    | 数字，例如 100                                  |
| 22 | StringLiteral        | 字符型字面量    | 字符串，例如 vansenb                             |
| 23 | SwitchCase           | Case 语句   | 通常指 Switch 语句中的 Case                       |
