还原简单的 CallExpression 类型
目标
1 2 3 4 5 6
| var Xor = function (p,q) { return p ^ q; }
let a = Xor(996,250);
|
转化为如下形式
1 2 3 4 5 6
| var Xor = function (p,q) { return p ^ q; }
let a = 996 ^ 250;
|
思路
遍历 VariableDeclarator 路径,对参数及函数主体进行判断校验,筛选出符合条件的节点
遍历函数定义作用域,当 CallExpression 与函数名相同时执行替换
完整代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
| const parser = require("@babel/parser")
const traverse = require("@babel/traverse").default
const t = require("@babel/types")
const generator = require("@babel/generator").default
jscode = "var Xor = function (p,q)\n" + "{\n" + " return p ^ q;\n" + "}\n" + "\n" + "let a = Xor(996,250);"
function call2express(path){ const {init, id} = path.node; const name = id.name; const params = init.params;
if (!params.length === 2) return;
let first_name = params[0].name; let second_name = params[1].name;
let func_body = init.body if (!func_body.body || !func_body.body.length === 1) return;
let return_body = func_body.body[0]; let arguments = return_body.argument; let {operator, left, right} = arguments;
if (!t.isReturnStatement(return_body) || !t.isBinaryExpression(arguments)) return;
if (!t.isIdentifier(left, {name:first_name}) || !t.isIdentifier(right, {name:second_name})) return;
const scope = path.scope;
traverse(scope.block, { CallExpression:{ enter: [ function (_path) { node = _path.node; if (!t.isIdentifier(node.callee, {name:name})) return; args = node.arguments;
_path.replaceWith(t.BinaryExpression(operator, args[0], args[1])); } ] } })
}
const vistor = { VariableDeclarator(path){ let init = path.get('init'); if (init.isFunctionExpression()){ call2express(path); } } }
const ast = parser.parse(jscode) traverse(ast, vistor)
let {code} = generator(ast); console.log(code)
|
查看执行结果