-
-
Notifications
You must be signed in to change notification settings - Fork 515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
traverse: port scope.push
API from Babel
#5049
Comments
When we have this API, we can remove the following code. This implementation appears in many plugins oxc/crates/oxc_transformer/src/es2021/logical_assignment_operators.rs Lines 79 to 100 in 200d887
|
Yes, agreed we need this. Aside from the failing test, the repeated I'm not sure which is best way to implement it though. Ideally it wouldn't be a method on By the way, Babel's implementation is inefficient: // Input
{ obj.a &&= 1; }
{ obj.b &&= 2; } // Output
{
var _obj;
(_obj = obj).a && (_obj.a = 1);
}
{
var _obj2;
(_obj2 = obj).b && (_obj2.b = 2);
} But as they are var _obj, _obj2;
{ (_obj = obj).a && (_obj.a = 1); }
{ (_obj2 = obj).b && (_obj2.b = 2); } This is more compact output (though minifier would probably do that hoisting anyway) but also requires maintaining an entry in As a futher optimization, where the temp var is used only briefly, a single binding could be reused multiple times: var _temp;
{ (_temp = obj).a && (_temp.a = 1); }
{ (_temp = obj).b && (_temp.b = 2); } (again, maybe the minifier will be able to optimize the code down to that anyway) |
We can use The problem with putting this in Maybe should parameterize pub trait Traverse<'a, State> {
fn enter_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a, State>) {}
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TraverseCtx<'a, State>) {}
// etc...
}
pub struct TraverseCtx<'a, State> {
pub ancestry: TraverseAncestry<'a>,
pub scoping: TraverseScoping,
pub ast: AstBuilder<'a>,
pub state: State,
}
struct TransformerState<'a> {
var_declarations: SparseStack<Vec<'a, VariableDeclarator<'a>>>,
}
type TransCtx<'a> = TraverseCtx<'a, TransformerState<'a>>;
struct CommonTransform;
impl<'a> Traverse<'a, TransformerState<'a>> for CommonTransform {
fn enter_statements(&mut self, _stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TransCtx<'a>) {
ctx.state.var_declarations.push(None);
}
fn exit_statements(&mut self, stmts: &mut Vec<'a, Statement<'a>>, ctx: &mut TransCtx<'a>) {
if let Some(declarations) = ctx.state.var_declarations.pop() {
// Insert `var` declaration statement
}
}
} To do:
|
First step towards #5049. Various transforms need to add a `var` statement at top of enclosing statement block. e.g.: ```js // Input a ??= b; ``` ```js // Output var _a; (_a = a) !== null && _a !== void 0 ? _a : (a = b); ``` Each of these transforms previously maintained it's own stack and added `var` statements individually. Share this functionality in a "common" utility transform which maintains a single stack to serve them all.
#6170 fixed the failing test mentioned at top of this issue. Only thing remaining is for arrow functions transform to also use oxc-project/backlog#144 covers moving |
@Dunqing I think arrow functions transform now uses |
Yes, It is done! |
Babel's implementation is here
Why need this API?
We need to combine the variable declarators required by different plugins to be inserted at the top of the statements.
Related tests:
The text was updated successfully, but these errors were encountered: