Commit Graph

28 Commits

Author SHA1 Message Date
Boshen baf022d74d refactor(ast)!: remove old AstBuilder methods (#24563)
Closes the migration tracked in #23043.

The new builder API (methods on the AST types themselves) has been in place for a while, all Oxc crates are migrated, and every crate which uses `AstBuilder` already enables `disable_old_builder` in its tests. The module docs said "after a few weeks, we will remove `AstBuilder`'s own methods entirely" — this does that.

## What's removed

- `crates/oxc_ast/src/generated/ast_builder.rs` and `builder/methods.rs` — `AstBuilder`'s own node and primitive constructors.
- `AstBuilderGenerator`, which produced the former.
- The `disable_old_builder` Cargo feature, plus the dev-dependency hacks it required across 33 manifests. Eight crates depended on `oxc_ast` *purely* to turn the feature on; those deps and their `cargo-shear` ignore entries are gone too.

## One thing worth reviewing

`AstBuilderGenerator` owned the `#[builder(default)]` / `#[builder(skip)]` attr registration that `BuilderMethodsGenerator` only *reads* — its doc comment said as much. Deleting it naively would have silently dropped `skip`/`default` handling for the 12 AST types using those attrs, so `attrs()` and `parse_attr()` move to `BuilderMethodsGenerator`.

The evidence this was faithful: after regenerating, `builder_methods.rs` and every other generated file are **byte-identical**. The only generated change in the diff is the deletion.

## Breaking changes

- `AstBuilder`'s own methods are gone. Use the AST type methods: `Statement::new_expression_statement(span, expr, &builder)` instead of `builder.statement_expression(span, expr)`.
- `AstBuilder` is no longer `Copy`/`Clone`, and its `allocator` field is private — use the `allocator` method from `GetAllocator`.
- `AstBuilder` and `NONE` are no longer re-exported from the crate root; import them from `oxc_ast::builder`. (The `disable_old_builder` feature already gated these off, so nothing in-tree used the root path.)
- The `disable_old_builder` feature no longer exists — remove it from any manifest that sets it.

A migration note covering all of the above is in `crates/oxc_ast/src/builder/mod.rs`.

---

Implemented with AI assistance (Claude Code); design, review, and verification driven by the author per the repo AI-usage policy.
2026-07-21 15:22:46 +00:00
overlookmotel 85a6853e0b fix(tasks): enable disable_old_builder Cargo feature for oxc_ast crate for all tasks (#23885)
Part of #23043.

We don't enable `oxc_ast`'s `disable_old_builder` Cargo feature in any of our published crates, or crates that are depended on by published crates.

Tasks are private to the repo, so enable this feature on them, to ensure no usage of legacy `AstBuilder` methods sneak in during the transition period before we delete these methods.
2026-06-28 12:13:17 +00:00
overlookmotel 382958afa8 feat(span)!: remove re-exports of string types from oxc_span crate (#21246)
For historical reasons, `oxc_span` crate was re-exporting string types which now live in `oxc_str` crate.

Remove these re-exports, and import these types directly from `oxc_str`.

Main motivation is just that it makes sense, but it should also have a minor positive effect on compile times - `oxc_span` and `oxc_str` crates can now be compiled in parallel.
2026-04-09 12:06:21 +00:00
Dunqing 3cfe8ede95 feat(semantic): add MemberWriteTarget flag to ReferenceFlags (#20772)
## Summary

Add a new `MemberWriteTarget` bit to `ReferenceFlags` ~~Store member write target references in a separate `FxHashSet<ReferenceId>` on `Semantic` rather than adding a flag to `ReferenceFlags`.~~

This marks identifier references read as the object of a member expression in a simple assignment target position (e.g., `A` in `A.foo = 1`).

- Set during `visit_member_expression` when flags indicate write-only context (simple `=`, not compound `+=` or update `++`)
- Stored in `Semantic::member_write_references` (`FxHashSet<ReferenceId>`)
- Queryable via `Semantic::is_member_write_reference(reference_id)` and `Semantic::member_write_references()`
- Does not affect existing `ReferenceFlags` — no changes to the shared bitflags type

## Motivation

Distinguishing "reads that exist only to serve a property write" from "real reads" is broadly useful:

### Minifier: dead code elimination of property-write-only symbols

```js
function A() {}
A.from = () => {}  // A's only reference is a member write target
// → both can be eliminated when property_write_side_effects: false
```

Without this info, the minifier sees `A` as "referenced" and cannot remove the function declaration. With it, the minifier knows all of `A`'s reads are property-write targets and can safely drop them. (See stacked PR #20773 — will be updated to use the new API in a follow-up)

### Linter: `no_unused_vars` improvement

```js
const config = {};
config.debug = true;
config.verbose = false;
// config is never read — only mutated via property writes
```

Currently `config` is considered "used" because `config.debug = ...` creates a read reference. With member write target tracking, `no_unused_vars` could detect that `config`'s only reads are property-write targets and report it as unused.

### Linter: simplify `no_param_reassign` property detection

`no_param_reassign` has a complex `is_modifying_property()` function that manually walks the ancestor chain to detect property modifications like `param.foo = 1`. With member write target tracking, this can be checked directly on the reference.

### Rolldown: replace `MemberExprIsWrite` traversal state

Rolldown already maintains its own [`MemberExprIsWrite` flag](https://github.com/rolldown/rolldown/blob/eec7d7320cc991e1efd5ed8264d02c6889a223c3/crates/rolldown/src/ast_scanner/mod.rs#L130-L131) as local traversal state in the AST scanner to [detect member expressions in write context](https://github.com/rolldown/rolldown/blob/eec7d7320cc991e1efd5ed8264d02c6889a223c3/crates/rolldown/src/ast_scanner/impl_visit.rs#L55-L73). Having this on `Semantic` means Rolldown can consume it directly instead of re-detecting it during scanning. There's also a [TODO in Rolldown's treeshake options](https://github.com/rolldown/rolldown/blob/main/crates/rolldown_common/src/inner_bundler_options/types/treeshake.rs#L255-L259) to wire `property_write_side_effects` to oxc_minifier — our stacked PR #20773 provides that.

### General: escape analysis for local objects

Any analysis that needs to know "is this object only mutated locally, never passed elsewhere?" benefits from knowing which reads are purely for property writes vs. reads that pass the value to other functions.

## Test plan

- [x] Semantic snapshot tests updated
- [x] Conformance snapshots updated
- [x] Clippy clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-04-07 06:11:34 +00:00
overlookmotel c9cd809e50 refactor(str)!: rename Atom to Str (#20835)
Pure refactor.

Rename `Atom` to `Str`. The name "Atom" is a leftover from when we used to intern strings (years ago), and is misleading now.

Just call it `Str`. This follows the naming convention we have for arena-allocated versions of other types e.g. `Box`, `Vec`, `HashMap` - which we name the same as the native equivalents but with a lifetime (`Box<'a>` not `ArenaBox<'a>`, so `Str<'a>` not `ArenaStr<'a>`).

Rename all variables that contained "atom", and methods which relate to `Str`s to match the new type name.

Rename `as_atom` methods to `as_arena_str`. The longer name is required here to disambiguate from `as_str` methods which return a `&str`.

Some variables called "atom" still exist in `oxc_regular_expression` crate - that's a different meaning of "atom" - the meaning defined in regexp spec.

The diff of this PR is large but it's 100% renaming. No substantive or unrelated changes whatsoever.
2026-03-30 02:40:33 +00:00
Dunqing 22dec6ace5 feat(semantic)!: remove Scoping::scope_build_child_ids and all related APIs (#18362)
Remove `Scoping::scope_build_child_ids` and all related APIs to make the semantics cleaner. This could also make it easier for us to sync Scoping data since we don't need to worry about child scope IDs.

This is a breaking change, but it is okay because all use of `scope_build_child_ids` in the Oxc and Rolldown has been removed.
2026-01-22 07:46:26 +00:00
Boshen 777fc40d90 feat(ast)!: add Ident type (#18354)
feat(span): add `Ident` type

Add a dedicated identifier string type that mirrors the `Atom` API.
This provides a foundation for future optimizations like pre-computed
hashing while maintaining API compatibility.

refactor(ast): use `Ident` type for identifier names in JS AST

Replace `Atom<'a>` with `Ident<'a>` for the `name` field in:
- `IdentifierName`
- `IdentifierReference`
- `BindingIdentifier`
- `LabelIdentifier`
- `PrivateIdentifier`

This builds on the `Ident` type added in the previous commit, providing
semantic distinction for identifier strings and enabling future
optimizations like pre-computed hashing.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-22 05:12:58 +00:00
overlookmotel 3175aa3b77 refactor(semantic)!: Scoping::get_resolved_reference_ids return slice (#12665)
It's more conventional for methods to return a `&[T]` instead of a `&Vec<T>`.
2025-07-31 15:31:57 +00:00
Dunqing b804f7c23b feat(semantic): introduce Redeclaraion for Scoping::symbol_declarations (#10059)
Introduce the `Redeclaration` struct so that we can add more information to it later.
2025-03-28 04:12:21 +00:00
Boshen 3c6f1405af refactor(semantic)!: make Scoping methods consistent (#9628) 2025-03-09 12:00:00 +00:00
Boshen ef6e0cca39 refactor(semantic)!: combine SymbolTable and ScopeTree into Scoping (#9615)
closes #9607
2025-03-09 10:28:12 +00:00
Boshen 7331656286 refactor(semantic)!: rename SymbolTable and ScopeTree methods (#9613)
part of #9607
2025-03-09 10:28:11 +00:00
Boshen 23738bf9db refactor(semantic)!: introduce Scoping (#9611)
part of #9607
2025-03-09 10:28:11 +00:00
Boshen a5cde10ecc feat(visit_ast)!: add oxc_visit_ast crate (#9428)
closes #9384
2025-02-28 08:03:54 +00:00
Boshen 1d81adac48 Rust Edition 2024 (#9289)
closes #9271

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-22 11:56:25 +08:00
branchseer ac4f98e376 refactor(span): derive Copy on Atom (#8596)
Follow up from
https://github.com/oxc-project/oxc/pull/8543#discussion_r1918592423

> I agree. https://github.com/oxc-project/backlog/issues/155

> Originally we were considering some form of interning and
reference-counting, so we didn't make it Copy to leave the door open for
that. But now all strings are stored in the arena anyway, so even if we
did decide to intern strings, reference-counting would be irrelevant -
our bump allocator doesn't allow freeing individual allocations anyway.

Most of the changes are done automatically by `just fix` (`cargo clippy
--fix` && `cargo fmt --all`). See the commit list for the manual edits.
2025-01-19 16:14:23 +08:00
Boshen 2736657dcd perf(semantic): allocate UnresolvedReferences in allocator (#8046) 2024-12-20 15:18:16 +00:00
Boshen 414e8285cd perf(semantic): allocate symbol data in Allocator (#8012) 2024-12-20 14:13:41 +00:00
Boshen 7aebed012d perf(semantic): allocate Bindings in allocator (#8021) 2024-12-19 15:16:03 +00:00
Boshen 02f968d02d refactor(semantic): change Bindings to a plain FxHashMap (#8019)
`IndexMap` was needed for the insertion order requirement in mangler.

Bindings (symbol ids) are monotonically increasing by binding
positions, which means we can get insertion order by sorting the symbol ids in
mangler.

Previous attempt: https://github.com/oxc-project/oxc/pull/4228
2024-12-19 14:16:28 +00:00
Boshen ed75e42ed6 refactor(semantic)!: make SymbolTable fields pub(crate) instead of pub (#7999)
SymbolTable needs some internal changes.
2024-12-18 16:38:58 +00:00
overlookmotel 3858221f45 refactor(global): sort imports (#7883)
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.
2024-12-14 15:07:21 +00:00
Boshen 7fb9d47460 style(rust): cargo +nightly fmt (#7877) 2024-12-14 06:03:31 +00:00
Boshen d942a8d41a chore: Rust v1.83.0 changes (#7535)
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.
2024-11-29 11:59:45 +08:00
overlookmotel d21448bf65 refactor(semantic, transformer): simplify FxIndexMap type aliases (#7524)
Pure refactor. Simplify `FxIndexMap` type aliases by using `rustc_hash`'s `FxBuildHasher`, instead of longhand `BuildHasherDefault<FxHasher>`.
2024-11-28 12:01:17 +00:00
Boshen 423d54cb74 refactor(rust): remove the annoying clippy::wildcard_imports (#6860) 2024-10-24 13:57:19 +00:00
Boshen 2b7be08af4 feat(ast)! add source_text to Program (#6444) 2024-10-11 04:13:41 +00:00
overlookmotel e19deaa102 ci(transformer): move post-transform checker to tasks crate (#6288)
Move post-transform checker into a `tasks` crate. It doesn't feel like it belongs in `oxc_semantic`. It also feels like too heavy a lump of code to put in `tasks/common`.
2024-10-05 14:48:37 +00:00