利用estools修改javascript源代码

规范JS条件语句,简化代码处理流程
本文介绍了一种方法,通过AST替换技术,将JavaScript中的条件语句规范化,便于后续处理。具体步骤包括安装环境、解析代码、遍历并修改AST节点,最终生成符合规范的代码。

工作中需要将javascript的if语句描述进行一些规范化,将类似

if(test) value0
else value1

的语句的全部统一成:

if (test)
    result = value0;
else
    result = value1;

 格式的,便于后续处理。

方法之一使用AST替换来完成,主要用到estools提供的javascript解析和代码生成工具。

主要操作如下

1) 安装node.js

2) mkdir convert

cd convert
npm install esprima
npm install estraverse
npm install escodegen

3) 编写AST解析代码,并且查看生成的AST树

var ast = esprima.parse(code);
console.log(JSON.stringify(ast,null,4));

4)编写遍历if语句的代码,如果不符合格式,就改变AST的节点。

 

 ast = estraverse.replace(ast, {
        leave: function(node, parent)
        {
            modifiedNode = node;
            if (node.type === 'IfStatement') {
                if (node.consequent.type === 'ExpressionStatement') 
                {
                    if (node.consequent.expression.type === 'Literal'){
                            modifiedNode['consequent'] = {
                                        "type": "ExpressionStatement",
                                        "expression": {
                                            "type": "AssignmentExpression",
                                            "operator": "=",
                                            "left": {
                                                "type": "Identifier",
                                                "name": "result"
                                            },
                                            "right": node.consequent.expression
                                        }
                                    }
                    };
                    if (node.alternate != null && node.alternate.expression.type === 'Literal'){
                            modifiedNode['alternate'] = {
                                        "type": "ExpressionStatement",
                                        "expression": {
                                            "type":
"AssignmentExpression",
                                            "operator": "=",
                                            "left": {
                                                "type": "Identifier",
                                                "name": "result"
                                            },
                                            "right": node.alternate.expression
                                        }
                                    }
                    };
                }
            };
            return modifiedNode;
        }
    });

5)修改好后的ast,生成源代码

var modifiedCode = escodegen.generate(ast);

6)运行

获得结果

$ node exc1.js test1.js
Reading test1.js
=============
if (var1 > 2) result = 3;
else result = 0;
if(var2 < 3) 0
else 1
if (var3 === 9) 1;
=============
if (var1 > 2)
    result = 3;
else
    result = 0;
if (var2 < 3)
    result = 0;
else
    result = 1;
if (var3 === 9)
    result = 1;

7) 完整代码

exc1.js
-----------
/*
 */
var fs = require('fs'),
    esprima = require('esprima'),
    estraverse = require('estraverse'),
    escodegen = require('escodegen');
function analyzeCode(code) {
    var ast = esprima.parse(code);
    //console.log(JSON.stringify(ast,null,4));
    ast = estraverse.replace(ast, {
        leave: function(node, parent)
        {
            modifiedNode = node;
            if (node.type === 'IfStatement') {
                if (node.consequent != null && node.consequent.type === 'ExpressionStatement') 
                {
                    if (node.consequent.expression.type === 'Literal'){
                            modifiedNode['consequent'] = {
                                        "type": "ExpressionStatement",
                                        "expression": {
                                            "type": "AssignmentExpression",
                                            "operator": "=",
                                            "left": {
                                                "type": "Identifier",
                                                "name": "result"
                                            },
                                            "right": node.consequent.expression
                                        }
                                    }
                    };
                    if (node.alternate != null && node.alternate.expression.type === 'Literal'){
                            modifiedNode['alternate'] = {
                                        "type": "ExpressionStatement",
                                        "expression": {
                                            "type": "AssignmentExpression",
                                            "operator": "=",
                                            "left": {
                                                "type": "Identifier",
                                                "name": "result"
                                            },
                                            "right": node.alternate.expression
                                        }
                                    }
                    };
                }
            };
            return modifiedNode;
        }
    });
    var modifiedCode = escodegen.generate(ast);
    console.log('=============');
    console.log(modifiedCode);
    //console.log(JSON.stringify(ast,null,4));
}
if (process.argv.length < 3) {
    console.log('Usage: zz.js file.js');
    process.exit(1);
}
var filename = process.argv[2];
console.log('Reading ' + filename);
var code = fs.readFileSync(filename);
console.log('=============');
console.log(''+code);
analyzeCode(code);
console.log('Done');
--------------
test1.js
if (var1 > 2) result = 3;
else result = 0;
if(var2 < 3) 0
else 1
if (var3 === 9) 1

8)

各种语言用来修改ast语法树的一些方法收集见:

http://adamrehn.com/articles/ast-instrumentation-examples-by-language#sec___javascript


转载于:https://my.oschina.net/hxapp/blog/601959

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值