是否有支持AST节点访问事件的框架?
Is there any framework supporting events on AST node visiting?
在使用 Esprima JavaScript Parser 时,它从 JS 源代码生成 JSON 格式的 AST,我注意到如果我可以注册一个节点(字符串)并在访问该类型节点时触发事件,如:
ASTFramework.on("Identifier", function(evt){
/*Some code here*/
});
通过一些研究,JSHint 似乎在内部实现了此类功能,但无法从其 API 中获得。对此有什么建议吗?
编辑:我想做的是能够注册事件,以便在访问 AST 节点时触发。简而言之,在特定 JSON 节点访问中触发事件的框架就足以满足这种情况。
我发现搜索 AST 节点遍历的最接近的东西是工具 estraverse,它使我能够访问节点并检查类型以执行操作:
//Using require from Node.js here to add module.
var estraverse = require("estraverse");
//Rest of code....
estraverse.traverse(astTree, {
enter: function (node) {
if(node.type == "Identifier") {
//Do something
} else if(node.type == "Literal") {
//Do something else, etc
}
}
});
因为 estraverse
访问所有节点(可能使用 DFS),很容易指定要考虑哪些类型的操作,即使它们深深地嵌套在其他节点中。
您可以使用 babel,它可以转换 JS(并触发您想要的事件)。
我写了一个简单的 plugin 将 x[-1]
转换为 x[x.length -1]
,这可以帮助您入门。
代码如下所示:
visitor: {
MemberExpression(path) {
const node = path.node;
/* obj[...] */
if (t.isMemberExpression(node) && node.computed) {
if (t.isUnaryExpression(node.property) && node.property.operator === "-") {
if (t.isNumericLiteral(node.property.argument)) {
...
}
}
}
},
}
在使用 Esprima JavaScript Parser 时,它从 JS 源代码生成 JSON 格式的 AST,我注意到如果我可以注册一个节点(字符串)并在访问该类型节点时触发事件,如:
ASTFramework.on("Identifier", function(evt){
/*Some code here*/
});
通过一些研究,JSHint 似乎在内部实现了此类功能,但无法从其 API 中获得。对此有什么建议吗?
编辑:我想做的是能够注册事件,以便在访问 AST 节点时触发。简而言之,在特定 JSON 节点访问中触发事件的框架就足以满足这种情况。
我发现搜索 AST 节点遍历的最接近的东西是工具 estraverse,它使我能够访问节点并检查类型以执行操作:
//Using require from Node.js here to add module.
var estraverse = require("estraverse");
//Rest of code....
estraverse.traverse(astTree, {
enter: function (node) {
if(node.type == "Identifier") {
//Do something
} else if(node.type == "Literal") {
//Do something else, etc
}
}
});
因为 estraverse
访问所有节点(可能使用 DFS),很容易指定要考虑哪些类型的操作,即使它们深深地嵌套在其他节点中。
您可以使用 babel,它可以转换 JS(并触发您想要的事件)。
我写了一个简单的 plugin 将 x[-1]
转换为 x[x.length -1]
,这可以帮助您入门。
代码如下所示:
visitor: {
MemberExpression(path) {
const node = path.node;
/* obj[...] */
if (t.isMemberExpression(node) && node.computed) {
if (t.isUnaryExpression(node.property) && node.property.operator === "-") {
if (t.isNumericLiteral(node.property.argument)) {
...
}
}
}
},
}