Существует ли какая-либо инфраструктура, поддерживающая события при посещении узла AST?
Работая с Esprima JavaScript Parser, который генерирует AST в формате JSON из исходного кода JS, я заметил, что было бы удобно, если бы я мог зарегистрировать тип узла (строку) и инициировать события, когда этот тип узла посещается, например, как:
ASTFramework.on("Identifier", function(evt){
/*Some code here*/
});
Проведя некоторые исследования, кажется, что JSHint реализует внутренне такую функциональность, но недоступна из его API. Есть ли какие-либо предложения по этому поводу?
РЕДАКТИРОВАТЬ: То, что я хочу сделать, это иметь возможность регистрировать события, чтобы быть запущенным при посещении узла AST. Проще говоря, для этого случая будет достаточно инфраструктуры, которая запускает события при посещении определенного узла JSON.
2 ответа
Самым близким, что я нашел при поиске обхода узла 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 (и запускать события, как вы хотите).
Я написал простой плагин, который конвертирует 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)) {
...
}
}
}
},
}
Больше информации: Babel Plugin Handbook