Javascript 使用节点js中的抽象语法树获取行号
我正在制作一个程序,通过参数获取一些代码,并在代码中添加一些console.log来转换代码。以下是节目:Javascript 使用节点js中的抽象语法树获取行号,javascript,node.js,abstract-syntax-tree,Javascript,Node.js,Abstract Syntax Tree,我正在制作一个程序,通过参数获取一些代码,并在代码中添加一些console.log来转换代码。以下是节目: const escodegen = require('escodegen'); const espree = require('espree'); const estraverse = require('estraverse'); function addLogging(code) { const ast = espree.parse(code); estraverse.
const escodegen = require('escodegen');
const espree = require('espree');
const estraverse = require('estraverse');
function addLogging(code) {
const ast = espree.parse(code);
estraverse.traverse(ast, {
enter: function(node, parent) {
if (node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression') {
addBeforeCode(node);
}
}
});
return escodegen.generate(ast);
}
function addBeforeCode(node) {
const name = node.id ? node.id.name : '<anonymous function>';
const beforeCode = "console.log('Entering " + name + "()');";
const beforeNodes = espree.parse(beforeCode).body;
node.body.body = beforeNodes.concat(node.body.body);
}
这是该程序的输出:
function foo(a, b) {
console.log('Entering foo()');
var x = 'blah';
var y = function () {
console.log('Entering <anonymous function>()');
return 3;
}();
}
foo(1, 'wut', 3);
函数foo(a,b){
log('输入foo()');
变量x=‘废话’;
变量y=函数(){
console.log('输入
因此,我想在控制台日志中添加更多信息,例如我们所在的行号。据我所知,在ast中,节点有一个标有“开始”和“结束”的值,该值指示节点从哪个字符开始以及在哪里结束。我如何使用该值来获取我们所在的行号?老实说,这对我来说似乎很困惑。我认为It’我正在考虑用“\n”来拆分文件,这样我就可以得到总行号,但是我怎么知道我在哪一行呢
提前谢谢。您的想法很好。首先找到原始代码中每行开始的偏移量。然后将节点的
开始
索引与收集的索引进行比较,以确定行号
这里我假设您希望报告的行号引用原始代码,而不是函数返回的代码
因此,自下而上,进行以下更改。首先,将行号作为addBeforeCode
的参数:
function addBeforeCode(node, lineNum) {
const name = node.id ? node.id.name : '<anonymous function>';
const beforeCode = `console.log("${lineNum}: Entering ${name}()");`;
const beforeNodes = espree.parse(beforeCode).body;
node.body.body = beforeNodes.concat(node.body.body);
}
注意:如果您支持matchAll
,那么上面的内容可以写得更简洁一些
然后在主要功能中使用上述功能:
console.log(addLogging(`
function foo(a, b) {
var x = 'blah';
var y = (function () {
return 3;
})();
}
foo(1, 'wut', 3);
`));
function addLogging(code) {
const lineStarts = getLineOffsets(code); // <---
let lineNum = 0; // <---
const ast = espree.parse(code);
estraverse.traverse(ast, {
enter: function(node, parent) {
if (node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression') {
// Look for the corresponding line number in the source code:
while (lineStarts[lineNum] < node.body.body[0].start) lineNum++;
// Actually we now went one line too far, so pass one less:
addBeforeCode(node, lineNum-1);
}
}
});
return escodegen.generate(ast);
}
函数addLogging(代码){
const linestart=getlineoffset(代码);//由于代码将在最后重新生成,源代码中的行号将与结果中的行号不同。删除空行,可以添加换行符,控制台.log
additions会添加行。那么:行号应该引用哪个版本的代码?源代码还是返回的代码?
function addLogging(code) {
const lineStarts = getLineOffsets(code); // <---
let lineNum = 0; // <---
const ast = espree.parse(code);
estraverse.traverse(ast, {
enter: function(node, parent) {
if (node.type === 'FunctionDeclaration' ||
node.type === 'FunctionExpression') {
// Look for the corresponding line number in the source code:
while (lineStarts[lineNum] < node.body.body[0].start) lineNum++;
// Actually we now went one line too far, so pass one less:
addBeforeCode(node, lineNum-1);
}
}
});
return escodegen.generate(ast);
}