Support for immutable AST modification
Pauan opened this issue · comments
Right now you can use types.visit
which will traverse over the AST, and then you can mutate the AST in whatever way you want.
This works fine, and most of the time it's what you want, but sometimes you want to return a new AST which is exactly like an existing AST but with certain things changed.
So I propose a new types.map
function, which has a similar API as types.visit
, except that in addition to visiting the existing AST, it also returns a fresh new AST:
var newAST = types.map(oldAST, {
visitIdentifier: function (path) {
this.traverse(path);
return {
type: "Identifier",
name: path.node.name.toUpperCase(),
loc: path.node.loc
};
}
});
In the above example, the types.map
function will traverse over oldAST
, and when it encounters an Identifier
it will call the visitIdentifier
method, which returns a new Identifier
.
Therefore the newAST
variable contains an AST which is exactly the same as oldAST
except that all Identifier
s have been replaced by the return value of the visitIdentifier
method.
This does not modify oldAST
, instead it creates a fresh AST. And it should work no matter how deeply nested the Identifier
is in oldAST
.
This makes it quite easy to non-destructively update an AST, even if the modification is buried deep in the AST.