const fs = require("fs");//文件读写
const parse = require("@babel/parser"); //解析为ast
const traverse = require('@babel/traverse').default;//遍历节点
const t = require('@babel/types');//类型
const generator = require('@babel/generator').default;//ast解析为代码
const code = `
const example = function () {
let a;
if (false) {
a = 1;
} else {
if (1) {
a = 2;
}
else {
a = 3;
}
}
return a;
};
`
// 默认为 script,当代码中含有 import 、export 等关键字时会报错,需要指定为 module
const ast = parse.parse(code, {sourceType: "module"})
// 判断条件对应的是 test 节点,if 对应的是 consequent 节点,else 对应的是 alternate 节点
// AST 处理思路以及代码:
//
// 筛选出 BooleanLiteral 和 NumericLiteral 节点,取其对应的值,即 path.node.test.value;
// 判断 value 值为真,则将节点替换成 consequent 节点下的内容,即 path.node.consequent.body;
// 判断 value 值为假,则判断else节点是否存在,存在时替换成 alternate 节点下的内容,即 path.node.alternate.body;
// 有的 if 语句可能没有写 else,也就没有 alternate,所以这种情况下判断 value 值为假,则直接移除该节点,即 path.remove()
function replace_if_else(path) {
const test = path.node.test
// if (t.isBooleanLiteral(test) || t.isNumberLiteral(test)) { //if(当前的筛选节点)
if (t.isBooleanLiteral(test) || t.isNumericLiteral(test)) { //if(当前的筛选节点) 注意:别写错节点名称
if (test.value) { // 如果if括号里面的内容为真,则将if包含的内容节点替换判断节点
path.replaceInline(path.node.consequent.body)
} else {
if (path.node.alternate) { // 如果else节点存在则,则else里面的内容节点替换判断节点
path.replaceInline(path.node.alternate.body)
} else {
path.remove() // 如果else节点不存在,则直接删除if节点,注意:当前path是if节点
}
}
}
}
const visitor = {
enter: [replace_if_else]
}
traverse(ast, visitor)
const result = generator(ast, {jsescOption: {"minimal": true}}).code
console.log(result)
备注:学习K哥AST笔记
这篇博客介绍了如何利用AST(抽象语法树)来处理JavaScript代码中的if-else语句。通过@babel/parser、@babel/traverse、@babel/types和@babel/generator库,将代码解析为AST并遍历节点,筛选出BooleanLiteral和NumericLiteral节点,根据其值替换或删除if-else结构。具体实现包括检查test节点值,替换consequent或alternate节点内容,以及在else缺失时删除整个if节点。

被折叠的 条评论
为什么被折叠?



