利用estools修改javascript源代码

工做中须要将javascript的if语句描述进行一些规范化,将相似javascript

if(test) value0
else value1

的语句的所有统一成:java

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

 格式的,便于后续处理。node

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

主要操做以下npm

1) 安装node.js工具

2) mkdir convertui

cd convert
npm install esprima
npm install estraverse
npm install escodegen

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

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

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

 

 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,生成源代码ip

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

相关文章
相关标签/搜索