javascript - 删除 Node 后使用 escodegen 生成代码时出错

标签 javascript node.js esprima escodegen

首先我创建了一个 esprima AST,然后我想使用 estraverse 删除一个 Node ,最后使用 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 中的错误?

提前致谢。

最佳答案

我放了一个 issue在 github 上,我得到了一个答案,我正在制作一个无效的 AST。

删除 CallExpression 会使他的父 ExpressionStatement 为空,因此无效。解决方案是简单地删除 ExpressionStatement。

此代码按预期工作:

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();

  //remove one of the lines, works!
  var done = false;
  ast = estraverse.replace(ast, {
    enter: function (node) {
      if (done)
        return this.break();
      if (node.type === esprima.Syntax.ExpressionStatement) {
        done = true;
        this.remove();
      }
    },
    leave: function (node) {
      if (done)
        return this.break();
    }
  });
  console.log("removed node:\n" + escodegen.generate(ast));
})()

输出:

original code:
console.log('1');
console.log('2');

removed node:
console.log('2');

关于javascript - 删除 Node 后使用 escodegen 生成代码时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45398094/

相关文章:

javascript - NodeJs : fs. 取消链接不会删除文件 [VS]

mysql - 如何使用 Node Js 创建嵌套 JSON 响应

javascript - 如何在客户端使用estraverse js库?

javascript - 死循环保护

javascript - 比较两种不同的日期格式

javascript - 使用带有选择选项的 javascript 进行计算?

javascript - preg_match 不工作 php 和 javascript

javascript - 安全地查找 jQuery 中是否存在元素

javascript - mongoDB 中的字段名称别名

javascript - 无法使用 Esprima/Acorn : unexpected token '(' 解析函数