You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@Dunqing was asking in #3216 for a more ergonomic way to pass TraverseCtx around in transformers.
#3219 is one option. Here's another, which is more like Babel's Path API:
Instead of receiving AST node and TraverseCtx, you'd only get Path, and have to get the AST node from it:
impl<'a>Traverse<'a>forMyTransform{fnenter_binary_expression(&mutself,path:&mutPath){let bin_expr:&mutBinaryExpression<'a> = path.node();// Do stuff with `bin_expr`}}
Is that any better?
Personally I don't much like it - .node() is boilerplate for every single enter_* or exit_* method.
BUT if we want to support mutating upwards, we'd need an API something like that anyway. That'd work something like this:
impl<'a>Traverse<'a>forMyTransform{fnenter_binary_expression(&mutself,path:&mutPath){match path.parent_mut(){AncestorMut::ExpressionStatement(expr_stmt) => {// `expr_stmt` is a `&mut ExpressionStatement` - you can mutate it}}}}
With upwards mutation, the function params can't include a reference to the current node, as it would be UB to also get a &mut ref to parent at same time. Both current AST node and parent AST node have to both come from path, so path can enforce that you can only get one or the other at any time.
NB: I am not 100% sure upward mutation can be made safe, but I think it can with an API like the above.
The text was updated successfully, but these errors were encountered:
Instead of receiving AST node and TraverseCtx, you'd only get Path, and have to get the AST node from it:
impl<'a>Traverse<'a>forMyTransform{fnenter_binary_expression(&mutself,path:&mutPath){let bin_expr:&mutBinaryExpression<'a> = path.node();// Do stuff with `bin_expr`}}
But your example looks incorrect. What do I get when I call path.node()?
Path is a generic Path<'a, T>. I am hoping that Rust would allow eliding T, but maybe I'm wrong about that - maybe you can only elide lifetimes, not generic types.
With the full function signature, it would be:
impl<'a>Traverse<'a>forMyTransform{fnenter_binary_expression(&mutself,path:&mutPath<'a,BinaryExpression<'a>>){let bin_expr = path.node();// Do stuff with `bin_expr`}}
bin_expr is a &mut BinaryExpression<'a> - same as what gets passed as node param in current API.
@Dunqing was asking in #3216 for a more ergonomic way to pass
TraverseCtx
around in transformers.#3219 is one option. Here's another, which is more like Babel's
Path
API:Instead of receiving AST node and
TraverseCtx
, you'd only getPath
, and have to get the AST node from it:Is that any better?
Personally I don't much like it -
.node()
is boilerplate for every singleenter_*
orexit_*
method.BUT if we want to support mutating upwards, we'd need an API something like that anyway. That'd work something like this:
With upwards mutation, the function params can't include a reference to the current node, as it would be UB to also get a
&mut
ref to parent at same time. Both current AST node and parent AST node have to both come frompath
, sopath
can enforce that you can only get one or the other at any time.NB: I am not 100% sure upward mutation can be made safe, but I think it can with an API like the above.
The text was updated successfully, but these errors were encountered: