This PR implements folding `foo === undefined || foo === null` into `foo
== null`.
I checked the minified output diff this time, so hoping that there isn't
a bug.
Pure refactor. Re-order imports for clarity:
1. `std`
2. External crates
3. `oxc_*` crates
4. Current crate `use crate::...`
5. Super `use super::...`
6. Local modules
This order is from "furthest away" to "closest". This makes it clearer to see what is coming from where.
`cargo +nightly fmt` (#7877) did a lot of the work, but unfortunately `rustfmt` does not have an option to (a) put workspace crates in a separate block from external crates and (b) move `mod` statements to after `use` statements.
Fix#7254
Changed all "raw" properties of literal types (if they have this property) to `Option<Atom>`.
---------
Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
This PR does not upgrade rustc. Only changes are applied.
We cannot upgrade to the lastet Rust version yet due to wasm-bindgen
breaking some generated types.
THere's also some elided lifetimes in `**/generated/**`, which requires
modification to ast tools.
It's essential to `oxc_traverse`'s safety scheme that the user cannot create a `TraverseAncestry`, because they could then substitute it for the one stored in `TraverseCtx`, and cause a buffer underrun when an ancestor gets popped off stack which should never be empty - but it is because user has sneakily swapped it for another one.
Not being able to create a `TraverseAncestry` also requires that user cannot obtain an owned `TraverseCtx` either, because you can obtain an owned `TraverseAncestry` from an owned `TraverseCtx`.
Therefore, it's unsound for `TraverseCtx::new` to be public.
However, it is useful in minifier to be able to re-use the same `TraverseCtx` over and over, which requires having an owned `TraverseCtx`.
To support this use case, introduce `ReusableTraverseCtx`. It is an opaque wrapper around `TraverseCtx`, which prevents accessing the `TraverseCtx` inside it. It's safe for user to own a `ReusableTraverseCtx`, because there's nothing they can do with it except for using it to traverse via `traverse_mut_with_ctx`, which ensures the safety invariants are upheld.
At some point, we'll hopefully be able to reduce the number of passes in the minifier, and so remove the need for `ReusableTraverseCtx`.But in the meantime, this keeps `Traverse`'s API safe from unsound abuse.
Note: Strictly speaking, there is still room to abuse the API and produce UB by initiating a 2nd traversal of a different AST in an `Traverse` visitor, and then `mem::swap` the 2 x `&mut TraverseCtx`s. But this is a completely bizarre thing to do, and would basically require you to write malicious code specifically designed to cause UB, so it's not a real risk in practice. We'd need branded lifetimes to close that hole too.
So this PR doesn't 100% ensure safety in a formal sense, but it at least makes it very hard to trigger UB *by accident*, which was the risk before.
Because we lack specialization in stable Rust, `Vec::from_iter_in` is unable to take advantage of the fact that `[T; N]` has a statically knowable size.
Introduce `Vec::from_array_in` for this case, which should be able to create the `Vec` with a single static-sized memcpy, or may allow the compiler to see that it can construct the array directly in the arena, rather than construct on stack and then copy to the arena.
Also add a corresponding `AstBuilder::vec_from_array` method, and use it in various places in codebase.
For the test case, Closure Compiler doesn't handle this at all in the REPL! If it's necessary, I will turn it back.
This PR uses builtin `and_then` and `map` method, which is better instead of a lot of `if let Some`.
Preparation for #7073. Avoid using `AstBuilder::*_from_*` methods to construct enums, use explicit construction instead.
Before:
```rs
let ident = self.ast.binding_pattern_kind_from_binding_identifier(ident);
```
After:
```rs
let ident = BindingPatternKind::BindingIdentifier(ident);
```
Often this produces shorter code, as well as (in my opinion) being easier to read.