Open maierfelix opened 7 years ago
Or maybe using different AST library? estraverse
could be more flexible. Estraverse visitor has just enter
and exit
methods:
https://github.com/estools/estraverse
so you could catch every AST node in one function and making something like this:
const stages = [STAGE1, STAGE2, STAGE.......
estraverse.traverse(ast, {
enter: function (node, parent) {
stages.forEach(stage => {
// run each stage
stage[node.type] && stage[node.type](node)
});
},
leave: function (node, parent) {
// similar code
}
});
So you could pass all eight stages in one AST pass :)
The main problem here is not acorn's walker itself, but the colliding patch states. Due to the recursive nature of JS walkers, insertions like adding temporary variables into a scope breaks upper loops (e.g. FunctionExpression.body
) and acorn's walker. So I just splitted everything to get it working, it's stable but pretty inefficient. I think looking into Babel's sauce could be helpful.
Edit: I dont think this is a problem with acorn's walker only - inserting new nodes into the raw AST could possibly break other walkers too if they don't expect it.
Currently the patch phase is splitted into 8 parts, means we re-walk the whole AST 8 times from scratch. Consider writing an own AST walker to better keep track about scopes and to prevent colliding between patch states.