首先我创建了一个esprima
AST,然后我想使用estraverse
删除一个节点,最后使用escodegen
重新生成代码,但是我得到了一个错误。
我尝试的代码是:
var esprima = require('esprima');
var estraverse = require('estraverse');
var escodegen = require('escodegen');
(function () {
//build an ast with 2 lines of code
var ast = esprima.parse("console.log('1');\n console.log('2');")
console.log("original code:\n" + escodegen.generate(ast));
console.log();
//change one of the lines, works
ast = estraverse.replace(ast, {
enter: function (node) {
},
leave: function (node) {
if (node.type === esprima.Syntax.CallExpression) {
this.break();
return esprima.parse("console.log('patch');").body[0].expression;
}
}
});
console.log("patched code:\n" + escodegen.generate(ast));
console.log();
//remove one of the lines, error
ast = estraverse.replace(ast, {
enter: function (node) {
},
leave: function (node) {
if (node.type === esprima.Syntax.CallExpression) {
this.break();
return this.remove();
}
}
});
console.log("removed node:\n" + escodegen.generate(ast));
})()
错误跟踪为:
C:\temp\node_modules\escodegen\escodegen.js:2450
type = expr.type || Syntax.Property;
^
TypeError: Cannot read property 'type' of null
at CodeGenerator.generateExpression (C:\temp\node_modules\escodegen\escodegen.js:2450:20)
at CodeGenerator.ExpressionStatement (C:\temp\node_modules\escodegen\escodegen.js:1335:28)
at CodeGenerator.generateStatement (C:\temp\node_modules\escodegen\escodegen.js:2469:33)
at CodeGenerator.Program (C:\temp\node_modules\escodegen\escodegen.js:1717:43)
at CodeGenerator.generateStatement (C:\temp\node_modules\escodegen\escodegen.js:2469:33)
at generateInternal (C:\temp\node_modules\escodegen\escodegen.js:2490:28)
at Object.generate (C:\temp\node_modules\escodegen\escodegen.js:2558:18)
at C:\temp\bug1.js:35:45
at Object.<anonymous> (C:\temp\bug1.js:38:3)
at Module._compile (module.js:570:32)
我做错了什么吗?这是escodegen
中的错误还是estraverse
中的错误?
先谢了。
2条答案
按热度按时间oyt4ldly1#
我在github上放了一个issue,我得到了一个答案,我正在做一个无效的AST。
删除CallExpression会使其父ExpressionStatement为空,因此无效。解决方法只是删除ExpressionStatement。
此代码按预期工作:
输出:
h43kikqp2#
看起来可能发生这种情况的一个原因是当代码被删除而留下一个空的箭头函数体时。例如,原始代码:
导致:
其中一个解决方案是:
在这种情况下,可以说父对象也应该被删除,但如果实际上是这样的话,可能会有点棘手