mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
codex/comment-attachments
129 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2f5cdb1231 |
feat(minifier): add property name mangling (#24740)
Oxc can shorten variable names and private class names, but it cannot shorten property names such as `obj._field`. This change adds optional property mangling. It replaces #23772 and gives bundlers a way to use the same property names across several files. ### Feature - `include` selects names to mangle. `exclude` and `reserved` keep names unchanged. - The cache can give a property a fixed output name or keep it unchanged. - The mangler supports member access, object and class keys, destructuring, optional chains, the left side of `in`, and JSX property names. - `mangle_quoted` also handles strings and template literals used directly as property keys. `/* @__KEY__ */` and `/* #__KEY__ */` can mark one other string or template literal as a property key. - Short names are assigned in a stable order. More common properties get shorter names. Existing and reserved names are avoided. - Bundlers can collect names from several programs, create one shared map, and apply it to every program. - Numeric keys, `__proto__`, `constructor`, `prototype`, TypeScript-only keys, and private names are never changed by this pass. ### Design Property names are part of JavaScript syntax, not local scope. For this reason, the code lives in `oxc_minifier`. It only reuses the short-name generator from `oxc_mangler`. For one program, the order is: ```text collect names → assign names → rewrite once → compress → mangle variables and private names ``` Property names are rewritten before compression because compression can remove information about quotes and comments. For several programs, a bundler collects names from each program, merges the results, assigns one shared map, and rewrites each program once. Collection can run in parallel. All programs must use the same options. The shared map keeps property names consistent inside one build. The cache has a different job: it keeps fixed names and reservations across separate minify calls. ### Example With `include: "^_"` and `mangle_quoted: true`: ```js obj[`_field`] = 1; obj._field = 2; ``` becomes: ```js obj[`e`] = 1; obj.e = 2; ``` ### Limitation - Property mangling is unsafe when other code still uses the old property name. Public APIs and names shared with external code, host APIs, imported namespace objects, or separate builds must be excluded or reserved. - Quote handling is per use. Without `mangle_quoted`, `obj._field` may change while `obj["_field"]` does not. - The mangler cannot find names built at runtime or stored in arbitrary strings. Code that uses `eval`, `Function`, or `with` must reserve any affected names. - Compression may create a matching property after this pass has finished. For example, `'f' + 'oo_'` may later become `foo_` and will not be mangled. - TypeScript enum reverse mappings are not supported because the transform creates quoted strings. - Multi-program support is a caller API. The caller must collect every program that shares mangled properties before assigning names. The public `oxc-minify` API is stacked in #24741. The downstream multi-chunk integration is shown in rolldown/rolldown#10374. Supersedes #23772. AI assistance: OpenAI Codex and Claude were used for research, implementation, review, and testing. The contributor is responsible for reviewing and understanding the changes before submission. |
||
|
|
db446518ca |
fix(napi): disable reuseWorker in browser bindings (#25640)
Fixes #25610 AI assistance: Codex was used to implement this change. |
||
|
|
c07fe7c217 |
feat(oxfmt): support experimentalOperatorPosition (#25643)
Fixes #16366 --- Option name requires `experimental` prefix for now. Values are: - `"start"` - `"end"`(default) This is also available on playground. |
||
|
|
b91dc3a1f1 |
chore(deps): update napi (#25457)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.8.3` → `3.8.5`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.8.3/3.8.5) |  |  |  |  | pnpm.catalog.default | patch | | [napi](https://redirect.github.com/napi-rs/napi-rs) | `3.12.0` → `3.12.1` |  |  |  |  | workspace.dependencies | patch | | [napi-build](https://redirect.github.com/napi-rs/napi-rs) | `2.4.0` → `2.4.1` |  |  |  |  | workspace.dependencies | patch | | [napi-derive](https://redirect.github.com/napi-rs/napi-rs) | `3.6.2` → `3.6.3` |  |  |  |  | workspace.dependencies | patch | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.8.5`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.4...a5b5f277ab56e7e7e903b392b15c79da7a6520ce) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.4...@napi-rs/cli@3.8.5) ### [`v3.8.4`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.3...@napi-rs/cli@3.8.4) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.3...@napi-rs/cli@3.8.4) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Cameron <cclark@cloudflare.com> |
||
|
|
465b723d04 |
refactor(formatter,oxfmt): unify host services as SessionServices on FormatSession (#25388)
- dispatcher - string_embedder - tailwind_sorter Group these 3 together as `SessionServices`, make them available to `FormatSession`, and pass them around. |
||
|
|
d0b8d6ff22 |
chore(deps): update dependency @napi-rs/cli to v3.8.3 (#25434)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.8.2` → `3.8.3`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.8.2/3.8.3) |  |  |  |  | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.8.3`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.2...@napi-rs/cli@3.8.3) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.2...@napi-rs/cli@3.8.3) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0NC4xMi4wIiwidXBkYXRlZEluVmVyIjoiNDQuMTIuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
253075e0cb |
fix(playground): include generated runtime files (#25246)
- add an explicit `files` allowlist for `oxc-playground` - include generated JS/types, WASM binaries, and worker modules - fix `publint` failures under pnpm 11.17.0 affecting oxc-project/playground#414 |
||
|
|
b937e3e2f1 |
chore(deps): update napi (#25019)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.7.4` → `3.8.2`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.7.4/3.8.2) |  |  |  |  | pnpm.catalog.default | minor | | [napi](https://redirect.github.com/napi-rs/napi-rs) | `3.11.0` → `3.12.0` |  |  |  |  | workspace.dependencies | minor | | [napi-build](https://redirect.github.com/napi-rs/napi-rs) | `2.3.2` → `2.4.0` |  |  |  |  | workspace.dependencies | minor | | [napi-derive](https://redirect.github.com/napi-rs/napi-rs) | `3.6.0` → `3.6.2` |  |  |  |  | workspace.dependencies | patch | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.8.2`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.1...@napi-rs/cli@3.8.2) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.1...@napi-rs/cli@3.8.2) ### [`v3.8.1`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.0...@napi-rs/cli@3.8.1) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.8.0...@napi-rs/cli@3.8.1) ### [`v3.8.0`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.7.4...@napi-rs/cli@3.8.0) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.7.4...@napi-rs/cli@3.8.0) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yODAuMCIsInVwZGF0ZWRJblZlciI6IjQ0LjMuMiIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Cameron <cameron.clark@hey.com> |
||
|
|
3d223072c2 |
feat(parser): add ParseOptions::enable_ident_hashes (#24491)
Adds `ParseOptions::enable_ident_hashes` (default `true`) and `Ident::new_unhashed` in `oxc_str`, and turns it off in the parse-only paths of the `oxc-parser` napi crate and the JS/JSON formatters. ### Why `Ident`'s precomputed hash (#19143) is a parse-time investment that pays off in semantic analysis — but parse-only consumers (parse + serialize, formatting) pay it for nothing. Profiling against other native parsers showed identifier hashing at 3.5-4.6% of parse time. Measured on M-series (yuku-style native harness, 50 warmup + 300 runs, median): | fixture | default | option off | |---|---|---| | react.development.js | 0.156 ms | 0.152 ms (−2.3%) | | binder.ts | 0.383 ms | 0.370 ms (−3.5%) | | App.tsx | 1.140 ms | 1.111 ms (−2.5%) | | checker.ts | 7.862 ms | 7.499 ms (−4.6%) | | typescript.js | 25.07 ms | 24.16 ms (−3.6%) | ### Contract Unhashed `Ident`s store hash `0`; `Eq`/`Hash`/`ContentEq` include the stored hash, so unhashed and hashed `Ident`s of the same string do not compare equal. Semantic analysis (or anything relying on `Ident` hashing) must not run on an AST parsed with the option disabled. Default behavior is unchanged. Every `Ident` the parser creates funnels through the `ParserImpl::ident()` helper, so the option applies uniformly. This covers identifiers lexed directly (`parse_identifier_kind`, `parse_private_identifier`) as well as those reconstructed from a `&str`/`Str` — import/export specifier locals, JSX element/member names, the TS `intrinsic` type name, TS import-type option keys (`with`/`assert`), and the `import x = this` recovery path — which would otherwise always be hashed through `Into<Ident>`. Exhaustively checked by parsing the test262/babel/typescript/misc/prettier corpora (96.5k files, 5.6M identifiers) in both option states and walking every `Ident` in the AST. On 64-bit platforms `Ident::new_unhashed` compiles to a no-op: an unhashed `Ident` has the same layout and bit representation as `&str`. ### Opt-outs - **napi `oxc-parser`** ties `enable_ident_hashes` to whether semantic errors are requested. Both parse entry points run `SemanticBuilder` only when `showSemanticErrors` is set, so the common parse-and-serialize path skips hashing while the semantic-errors path keeps it. Serialized output is unchanged — the hash is internal to `Ident` and never emitted. - **JS and JSON formatters** turn it off: they never run semantic analysis and only read `Ident::as_str` / compare idents against string literals. Exception: the JS formatter keeps hashes when built with the `detect_code_removal` feature, whose check runs `SemanticBuilder` on the formatter-parsed AST. |
||
|
|
4eb074e69d |
feat(mangler): add reserved option for names that must not be mangled (#24041)
Adds `MangleOptions::reserved` — equivalent to terser / uglify-js / swc `mangle.reserved`: names in the set are never used as mangled names, and bindings that already carry them keep them. Default empty; default output is byte-identical to main (minsize snapshot unchanged). ## Motivation Node's cjs-module-lexer detects a CommonJS module's named exports by **lexically** scanning for `exports.<name> =` / `module.exports` token patterns — no scope analysis ([its README documents renamed identifiers as "DETECTS: NO EXPORTS"](https://github.com/nodejs/cjs-module-lexer)). UMD / CommonJS wrappers bind `exports` / `module` as ordinary function parameters, and the mangler renames them, erasing every named export the lexer can see. Surfaced by the monitor-oxc mangler runtime test ([failing run](https://github.com/oxc-project/monitor-oxc/actions/runs/28569108563/job/84702922472), previously masked by #24033 / #24036): `archiver` does `import { queue } from "async"`, and `async`'s dist is a UMD bundle — mangled, the factory parameter `exports` became `e` and node fails with `Named export 'queue' not found`. With `reserved: ["exports", "module"]` the output imports correctly (verified end-to-end in node, including running a queue task). ## Why an opt-in list instead of always keeping these names Renaming them is ecosystem-standard. Verified empirically — minifying the same UMD sample and importing it in node: | minifier | renames `exports` param? | `import { queue }` from its output | escape hatch | | --- | --- | --- | --- | | terser 5.48 | yes | fails | `mangle.reserved` (verified working) | | uglify-js 3.19 | yes | fails | `reserved` (verified working) | | esbuild 0.28 `--minify` | yes | fails | none for identifier mangling | | swc | yes | fails | terser-style `mangle.reserved` ([swc#3424](https://github.com/swc-project/swc/issues/3424)) | An earlier revision of this PR kept `exports` / `module` unconditionally; the Minification Size check showed the real cost: ~1% minified on UMD-heavy files (d3: +3.3 kB from ~590 `exports` references, flipping it to *larger than esbuild*), because the point is keeping the literal 7-char token at every export site. No other minifier pays this by default — and rolldown bundles bind `exports` / `module` in every CJS interop wrapper, where node's lexer never looks. So oxc gets the same escape hatch as terser/swc, with the same name. `MangleOptions` loses `Copy` (it now holds the set); construction sites switch to `..MangleOptions::default()` / `clone()`. Exposed in `oxc-minify` NAPI options (`mangle.reserved: string[]`) and the mangler example (`--reserve-exports`). monitor-oxc will pass `["exports", "module"]` for its mangler runtime test (its corpus imports prebuilt CJS/UMD dists directly). For reference, esbuild solves this for its *own* node-platform CJS bundles differently — a dead-code annotation `0 && (module.exports = { a, b })` that cjs-module-lexer recognizes ([esbuild#960](https://github.com/evanw/esbuild/issues/960), [cjs-module-lexer#44](https://github.com/nodejs/cjs-module-lexer/issues/44)); verified that pattern also works appended to fully-mangled output. That could be a future zero-size-cost alternative at the minifier level. |
||
|
|
7a76cd3dc3 |
feat(estree)!: make whether to include TS fields a runtime option (#23574)
Previously, whether to serialize AST to ESTree JSON with/without TS fields was a compile-time option - via 2 different configs `CompactTSSerializer` and `CompactJSSerializer` (and their pretty-printing and with-fixes counterparts). Turn this into a runtime option instead - This make serialization a little slower (more branches in either mode, and dead code in JS-only mode) but reduces the size of `oxc-parser` binary as only one `ESTreeSerializer` is generated, instead of 2 (JS-only, and with-TS). |
||
|
|
e745892d4c |
chore(deps): update napi (#23394)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.7.1` → `3.7.2`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.7.1/3.7.2) |  |  |  |  | pnpm.catalog.default | patch | | [napi](https://crates.io/crates/napi) | `3.9.1` → `3.9.2` |  |  |  |  | workspace.dependencies | patch | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.7.2`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.7.1...@napi-rs/cli@3.7.2) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.7.1...@napi-rs/cli@3.7.2) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4yMTkuMCIsInVwZGF0ZWRJblZlciI6IjQzLjIxOS4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
777f02ae10 |
refactor(diagnostics)!: return a Diagnostics type instead of Vec<OxcDiagnostic> (#23217)
## Summary Introduces `oxc_diagnostics::Diagnostics` — a `Vec<OxcDiagnostic>` newtype that knows the difference between errors and warnings — and makes it the standard diagnostics return value across oxc. - **New type**: `Diagnostics` with `has_errors()`, `has_warnings()`, `errors()`, `warnings()`, plus `Vec`-like ergonomics (Deref, `IntoIterator`, `Extend`, `From`/`Into<Vec>`) so most call sites are unchanged. - **Return types**: `ParserReturn`, `SemanticBuilderReturn`, `IsolatedDeclarationsReturn`, the React Compiler `TransformResult`/`LintResult`, and `TransformerReturn` now expose `diagnostics: Diagnostics` instead of `errors: Vec<OxcDiagnostic>` (the React Compiler's separate `errors`/`warnings` are merged into one severity-tagged list). - **Behaviour**: a React Compiler **error** now stops the transform (no output), while **warnings** flow through and the transform continues. `compile()` aborts codegen only when `diagnostics.has_errors()` — warnings alone no longer abort (previously any diagnostic did). ## Breaking change Consumers reading `*.errors` on these return values must read `*.diagnostics`. React Compiler consumers that read `.errors`/`.warnings` separately should use `diagnostics.has_errors()` / `diagnostics.errors()` / `diagnostics.warnings()`. Parser/semantic/isolated-declarations fatality is otherwise unchanged. Builds on the React Compiler transform feature (#23201). 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
1260f03b4f |
refactor(semantic): don't build the AstNodes store by default (#23005)
## What Make the full `AstNodes` store **opt-in**, so the compiler pipeline (transformer / codegen / minifier) can run semantic analysis without building it at all. Previously every `SemanticBuilder` run allocated and populated the full `AstNodes` store, even for consumers that only need scoping + the syntax checker. This separates the node-related builder state into three independent pieces: - a standalone `NodeId` counter — the source of truth for node ids, valid in either mode; - an **ancestry stack** — an upward-walk-only stack of the current node's ancestors, the only ancestry the syntax checker and binder actually read; - the full **`AstNodes`** store — random access to every node, needed by the linter and mangler. ## How - A new `AstNodeStore` (in `crates/oxc_semantic/src/node/store.rs`) bundles the node-id counter, the current-node cursor/flags, and the storage. The storage is an enum (`AstNodeStoreKind`) with two variants — `Full(AstNodes)` and `Ancestry(AncestryStack)` — so the full store and the ancestry stack are **mutually exclusive by construction**; they can never both be maintained at once. - The checker and binder read ancestry through an `Ancestry` view (`node/ancestry.rs`) that dispatches between the full store (linter / mangler) and the stack (compiler pipeline). They no longer do random `NodeId` access into the store — all ancestry access is upward-walk-only. - `SemanticBuilder` gains `with_build_nodes(bool)`. The default is **off** (ancestry stack only). `new_linter()` turns it on (the linter needs the full store); `new_compiler()` leaves it off. - `CompilerInterface::build_semantic_nodes()` lets `oxc::Compiler` consumers opt back in if their `after_semantic` hook reads `Semantic::nodes`. ## Notes - Behaviour-neutral: semantic conformance snapshots are unchanged. - Allocation snapshots updated — the default (ancestry) path allocates slightly less (the growing `Stack` trades a couple of fixed allocations for a few reallocs). - Builds on the already-merged `SymbolFlags`-based redeclaration checks (#23060) and the `new_linter`/`new_compiler` preset adoption (#23057), which removed the last random node reads from the redeclaration path so the checker works without the store. |
||
|
|
963146f4b6 |
refactor(semantic): use SemanticBuilder presets at remaining call sites (#23057)
Use the `SemanticBuilder::new_linter()` preset at linter call sites that built semantic with ad-hoc `new().with_cfg(true)`-style chains, so they build semantic the same way the linter does instead of replicating its options by hand.
- linter test helpers: `disable_directives`, `utils/{regex,comment,jest,react}`
- playground's lint path
Behaviour-neutral; all linter tests pass.
|
||
|
|
336413bf5d |
refactor(semantic): use new_linter/new_compiler presets at callsites (#23037)
Replaces ad-hoc `SemanticBuilder::new().with_*()` chains with the `new_linter()` / `new_compiler()` presets where the preset already expands to the exact same option set, so the config lives in one place. - linter example + linter benchmark → `new_linter()` (cfg + class table + syntax) - semantic benchmark, cfg example, integration test util → `new_compiler()` (syntax) Behavior-neutral — each preset matches the options the callsite set by hand. Carved out of the larger store-optional refactor so it can land independently on `main` first. |
||
|
|
5778a2dfb5 |
refactor(formatter_core): purify core and define rules (#22952)
The Printer never consumes these; they belong with each language formatter. - Evict `Quote` (each formatter owns `QuoteStyle`) - `normalize_string` takes a quote byte - Evict `Expand` / `BracketSpacing` / `TrailingCommas` into oxc_formatter and oxc_formatter_json - JSON's `TrailingCommas` is now two-variant (`Always`/`Never`) - collapse Prettier's `all`/`es5` at each translation layer - Rename `util/` -> `spec/` (pure shared helpers) - Split `SourceText`: mechanical access stays in core, JS/TS lexis moves to `SourceTextExt` - Drop the `oxc_syntax` dependency from core All behaviros, Prettier conformance are unchanged. |
||
|
|
85efabfe0a |
feat(semantic): make building the class table optional, off by default (#22862)
Rolldown runs semantic multiple times, some runs do not require building the class table. |
||
|
|
705c0e969b |
refactor(formatter): introduce text-in public APIs (#22872)
Align `oxc_formatter` with `oxc_formatter_json`, both now expose `format(...) -> Result<Formatted<'a, _>, OxcDiagnostic>`. - Add text-in `format` and `format_fragment`, also `format_program`, `parse_for_format` and the `FragmentContext` enum - Parse options, JSX enabling, js-in-xxx context aware handlings are applied internally - Make the `Formatter` struct and AST/IR primitives crate-internal - Fold `get_parse_options` / `enable_jsx_source_type` and the `service` module into `parse_for_format` |
||
|
|
5733868456 |
refactor(formatter_core,formatter,formatter_json): share Expand and BracketSpacing options (#22821)
We chose `core` as the location for duplicate `struct`s, but the final options will continue to be built by each formatter. |
||
|
|
c323187f37 |
refactor(formatter): Split oxc_formatter and oxc_formatter_core (#22611)
Split `oxc_formatter` into: - `oxc_formatter(_js)`: JS/TS specific formatter, comment handling, sortImports, jsdoc, etc - `oxc_formatter_core`: Language agnostic IR, printer, etc The naming convention is different from Biome or Ruff (they do not have `_core`, and `_formatter` is equivalent to the core), but this is because in Oxc, items without `_js` are the default. As a basic task, I have added `Context` as a generic to all relevant parts to ensure support for multiple languages. There might still be other components that could be refactored into the core, but I would like to finish them as I implement support for other languages. Also moved some shared utilities to the core in advance. |
||
|
|
b7568d54d7 |
chore(deps): update dependency @napi-rs/cli to v3.7.0 (#22771)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.6.2` → `3.7.0`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.6.2/3.7.0) |  |  |  |  | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.7.0`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.6.2...@napi-rs/cli@3.7.0) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.6.2...@napi-rs/cli@3.7.0) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xOTQuMCIsInVwZGF0ZWRJblZlciI6IjQzLjE5NC4wIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com> |
||
|
|
339a9fb1ce |
refactor(linter): simplify context sub host options (#22056)
Simplifies ContextSubHost construction by replacing constructor variants with a single options struct. |
||
|
|
245273ef0a |
feat(napi/playground): add optimizeEnums and optimizeConstEnums options (#21815)
## Summary This PR adds `optimizeEnums` and `optimizeConstEnums` options to the playground's transformer configuration, enabling TypeScript enum optimization features that are already available in the transformer. ## Changes - Added `optimize_enums: bool` and `optimize_const_enums: bool` fields to the `OxcTransformerOptions` struct in `napi/playground/src/options.rs` - Updated `apply_transformations` method in `napi/playground/src/lib.rs` to apply these options to `options.typescript.optimize_enums` and `options.typescript.optimize_const_enums` ## Reference Resolves https://github.com/oxc-project/oxc/blob/d1cf22efc2bc9cf9fa82e887c34965d2ce3004c3/napi/playground/src/options.rs#L59 These options enable: - `optimize_enums`: Optimize regular (non-const) enums by inlining their member accesses at usage sites when the member value is statically known - `optimize_const_enums`: Optimize const enums by inlining their values at usage sites and removing the enum declaration |
||
|
|
5e755d14f9 |
chore(transformer, playground): enable enum_eval in semantic for transformer (#21671)
close: https://github.com/oxc-project/oxc/issues/21667 |
||
|
|
d8076c9780 |
chore(deps): update rolldown (#21639)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [rolldown](https://rolldown.rs/) ([source](https://redirect.github.com/rolldown/rolldown/tree/HEAD/packages/rolldown)) | [`1.0.0-rc.16` → `1.0.0-rc.17`](https://renovatebot.com/diffs/npm/rolldown/1.0.0-rc.16/1.0.0-rc.17) |  |  |  |  | | [tsdown](http://tsdown.dev/) ([source](https://redirect.github.com/rolldown/tsdown)) | [`0.21.9` → `0.21.10`](https://renovatebot.com/diffs/npm/tsdown/0.21.9/0.21.10) |  |  |  |  | --- ### Release Notes <details> <summary>rolldown/rolldown (rolldown)</summary> ### [`v1.0.0-rc.17`](https://redirect.github.com/rolldown/rolldown/blob/HEAD/CHANGELOG.md#100-rc17---2026-04-22) [Compare Source](https://redirect.github.com/rolldown/rolldown/compare/v1.0.0-rc.16...v1.0.0-rc.17) ##### 🐛 Bug Fixes - link: error on missing export between TS modules ([#​9197](https://redirect.github.com/rolldown/rolldown/issues/9197)) by [@​IWANABETHATGUY](https://redirect.github.com/IWANABETHATGUY) - rolldown\_plugin\_vite\_import\_glob: import path should not be affected by absolute base option ([#​9145](https://redirect.github.com/rolldown/rolldown/issues/9145)) by [@​kermanx](https://redirect.github.com/kermanx) - `this.resolve()` returns null for bare relative paths without importer ([#​9142](https://redirect.github.com/rolldown/rolldown/issues/9142)) by [@​Copilot](https://redirect.github.com/Copilot) - collect destructured bindings in HMR module exports ([#​9146](https://redirect.github.com/rolldown/rolldown/issues/9146)) by [@​h-a-n-a](https://redirect.github.com/h-a-n-a) - esbuild-tests: handle 0.28.0 test cases ([#​9149](https://redirect.github.com/rolldown/rolldown/issues/9149)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - plugin/copy-module: honor external resolutions from other plugins ([#​9139](https://redirect.github.com/rolldown/rolldown/issues/9139)) by [@​TheAlexLichter](https://redirect.github.com/TheAlexLichter) - allow undefined in sourcesContent type ([#​9136](https://redirect.github.com/rolldown/rolldown/issues/9136)) by [@​jurijzahn8019](https://redirect.github.com/jurijzahn8019) - reduce false positives in chunk optimizer circular dependency detection ([#​9049](https://redirect.github.com/rolldown/rolldown/issues/9049)) by [@​AlonMiz](https://redirect.github.com/AlonMiz) ##### 🚜 Refactor - chunk-optimizer: extract runtime-module placement into rehome\_runtime\_module ([#​9163](https://redirect.github.com/rolldown/rolldown/issues/9163)) by [@​IWANABETHATGUY](https://redirect.github.com/IWANABETHATGUY) ##### 📚 Documentation - add design doc for sort\_modules execution ordering ([#​9169](https://redirect.github.com/rolldown/rolldown/issues/9169)) by [@​IWANABETHATGUY](https://redirect.github.com/IWANABETHATGUY) - add document for `RenderedModule` ([#​9147](https://redirect.github.com/rolldown/rolldown/issues/9147)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) ##### ⚡ Performance - rolldown\_plugin\_vite\_import\_glob: skip self-import earlier using raw path comparison ([#​9193](https://redirect.github.com/rolldown/rolldown/issues/9193)) by [@​shulaoda](https://redirect.github.com/shulaoda) ##### 🧪 Testing - lazy: add `playground/lazy-compilation` ([#​7974](https://redirect.github.com/rolldown/rolldown/issues/7974)) by [@​hyf0](https://redirect.github.com/hyf0) ##### ⚙️ Miscellaneous Tasks - use app token for release PR ([#​9198](https://redirect.github.com/rolldown/rolldown/issues/9198)) by [@​Boshen](https://redirect.github.com/Boshen) - upgrade oxc to 0.127.0 ([#​9194](https://redirect.github.com/rolldown/rolldown/issues/9194)) by [@​Dunqing](https://redirect.github.com/Dunqing) - use oxc security action ([#​9196](https://redirect.github.com/rolldown/rolldown/issues/9196)) by [@​Boshen](https://redirect.github.com/Boshen) - esbuild-tests: remove some tests from ignored list as enum inline is now supported ([#​9184](https://redirect.github.com/rolldown/rolldown/issues/9184)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - deps: update dependency vite-plus to v0.1.19 ([#​9183](https://redirect.github.com/rolldown/rolldown/issues/9183)) by [@​renovate](https://redirect.github.com/renovate)\[bot] - use vp instead of pnpm in check-wasi-binding-deps ([#​9182](https://redirect.github.com/rolldown/rolldown/issues/9182)) by [@​shulaoda](https://redirect.github.com/shulaoda) - verify wasm32-wasi binding deps match [@​rolldown/browser](https://redirect.github.com/rolldown/browser) before publish ([#​9162](https://redirect.github.com/rolldown/rolldown/issues/9162)) by [@​shulaoda](https://redirect.github.com/shulaoda) - deps: update esbuild for tests to 0.28.0 ([#​9172](https://redirect.github.com/rolldown/rolldown/issues/9172)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - deps: update rollup submodule for tests to v4.60.2 ([#​9173](https://redirect.github.com/rolldown/rolldown/issues/9173)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - deps: update test262 submodule for tests ([#​9174](https://redirect.github.com/rolldown/rolldown/issues/9174)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - sort\_modules: fix stale async-entry sort key comment ([#​9170](https://redirect.github.com/rolldown/rolldown/issues/9170)) by [@​IWANABETHATGUY](https://redirect.github.com/IWANABETHATGUY) - deps: update npm packages ([#​9157](https://redirect.github.com/rolldown/rolldown/issues/9157)) by [@​renovate](https://redirect.github.com/renovate)\[bot] - deps: update dependency diff to v9 ([#​9158](https://redirect.github.com/rolldown/rolldown/issues/9158)) by [@​renovate](https://redirect.github.com/renovate)\[bot] - deps: update rust crates ([#​9156](https://redirect.github.com/rolldown/rolldown/issues/9156)) by [@​renovate](https://redirect.github.com/renovate)\[bot] - run Windows CI on PRs labeled with `ci: windows` ([#​9153](https://redirect.github.com/rolldown/rolldown/issues/9153)) by [@​hyf0](https://redirect.github.com/hyf0) - update-test-dependencies: run setup-rust before file changes ([#​9151](https://redirect.github.com/rolldown/rolldown/issues/9151)) by [@​sapphi-red](https://redirect.github.com/sapphi-red) - deps: update dependency rust to v1.95.0 ([#​9140](https://redirect.github.com/rolldown/rolldown/issues/9140)) by [@​renovate](https://redirect.github.com/renovate)\[bot] ##### ❤️ New Contributors - [@​jurijzahn8019](https://redirect.github.com/jurijzahn8019) made their first contribution in [#​9136](https://redirect.github.com/rolldown/rolldown/pull/9136) - [@​AlonMiz](https://redirect.github.com/AlonMiz) made their first contribution in [#​9049](https://redirect.github.com/rolldown/rolldown/pull/9049) </details> <details> <summary>rolldown/tsdown (tsdown)</summary> ### [`v0.21.10`](https://redirect.github.com/rolldown/tsdown/releases/tag/v0.21.10) [Compare Source](https://redirect.github.com/rolldown/tsdown/compare/v0.21.9...v0.21.10) ##### 🚀 Features - Upgrade rolldown - by [@​sxzz](https://redirect.github.com/sxzz) [<samp>(8a449)</samp>](https://redirect.github.com/rolldown/tsdown/commit/8a4498d) ##### [View changes on GitHub](https://redirect.github.com/rolldown/tsdown/compare/v0.21.9...v0.21.10) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMzkuNCIsInVwZGF0ZWRJblZlciI6IjQzLjEzOS40IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> |
||
|
|
611b3b69ef |
chore(deps): update dependency rust to v1.95.0 (#21509)
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.94.1` → `1.95.0` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.95.0`](https://redirect.github.com/rust-lang/rust/compare/1.94.1...1.95.0) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.94.1...1.95.0) </details> --- ### Configuration 📅 **Schedule**: (in timezone Asia/Shanghai) - Branch creation - At any time (no schedule defined) - Automerge - At any time (no schedule defined) 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjMuOCIsInVwZGF0ZWRJblZlciI6IjQzLjEyMy44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119--> |
||
|
|
152b37a6e8 |
chore(deps): update napi (#20829)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.5.1` → `3.6.0`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.5.1/3.6.0) |  |  |  |  | pnpm.catalog.default | minor | | [napi](https://redirect.github.com/napi-rs/napi-rs) | `3.8.3` → `3.8.4` |  |  |  |  | workspace.dependencies | patch | | [napi-derive](https://redirect.github.com/napi-rs/napi-rs) | `3.5.2` → `3.5.3` |  |  |  |  | workspace.dependencies | patch | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.6.0`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.5.1...@napi-rs/cli@3.6.0) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.5.1...@napi-rs/cli@3.6.0) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My45NC4xIiwidXBkYXRlZEluVmVyIjoiNDMuMTAyLjciLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=--> |
||
|
|
b3b2d305f9 |
perf(parser): introduce ParserConfig (#19637)
### What this PR does Introduce `ParserConfig` trait (another try at #16785). The aim is to remove the large performance regression in parser that #19497 created, by making whether the parser generates tokens or not a compile-time option. `ParserConfig::tokens` method replaces `ParseOptions::collect_tokens` property. The former can be const-folded at compile time, where the latter couldn't. ### 3 options This PR also introduces 3 different config types that users can pass to the parser: * `NoTokensParserConfig` (default) * `TokensParserConfig` * `RuntimeParserConfig` The first 2 set whether tokens are collected or not at compile time. The last sets it at runtime. All 3 implement `ParserConfig`. `NoTokensParserConfig` is the default, and is what's used in compiler pipeline. It switches tokens off in the parser, and makes all the tokens-related code dead code, which the compiler eliminates. This makes the ability of the parser to generate tokens zero cost when it's not used (in the compiler pipeline). `TokensParserConfig` is the one to use where you *always* want tokens. This is probably the config that linter will use. `RuntimeParserConfig` is the one to use when an application decides whether to generate tokens or not at runtime. This config avoids compiling the parser twice, at the cost of runtime checks. This is what NAPI parser package will use. ### Future extension #### Supporting additional features In future we intend to build the UTF-8 to UTF-16 offsets conversion table in the parser. This will be more performant than searching through the source text for unicode characters in a 2nd pass later on. But this feature is only required for uses of the parser where we're interacting with JS side (NAPI parser package, linter with JS plugins). `ParserConfig` can be extended to toggle this feature on/off at compile time or runtime, in the same way as you toggle on/off tokens. #### Options and configs This PR introduces `ParserConfig` but leaves `ParseOptions` as it is. So we now have 2 sets of options, passed to `Parser` with `with_options(...)` and `with_config(...)`. This is confusing. We could merge the 2 by making `ParseOptions` implement `ParserConfig`, so then you'd define all options with one `with_options` call. This would have the side effect of making all other parser options (e.g. `preserve_parens`) able to be set at either runtime or compile time, depending on the use case. For users consuming `oxc_parser` as a library, with specific needs, they could also configure `Parser` to their needs e.g. create a parser which only handles plain JS code with all the code paths for JSX and TS shaken out as dead code. This would likely improve parsing speed significantly for these use cases. ### Implementation details Why a trait instead of a cargo feature? IMO a trait is preferable for the following reasons: 1. We have 3 different use cases we need to support (the 3 provided configs). 3 different Cargo features would be unwieldy. 2. This situation would become far worse once we introduce more features e.g. UTF-8 -> UTF-16 conversion. 3. No problems around feature unification. We found Cargo features caused headaches when we used them in linter for toggling on/off JS plugins support. 4. No clippy errors which only appear when the feature is/isn't disabled, requiring complex `#[cfg_attr(feature = "whatever", expect(clippy::unused_async))]` etc. The introduction of a trait does not seem to significantly affect compile time: ``` # Before this PR cargo build -p oxc_parser 15.33s user 3.27s system 254% cpu 7.316 total cargo build -p oxc_parser --release 17.36s user 2.26s system 231% cpu 8.477 total cargo build -p oxc_parser --example parser 18.43s user 3.75s system 271% cpu 8.156 total cargo build -p oxc_parser --example parser --release 32.52s user 2.59s system 180% cpu 19.454 total # After this PR cargo build -p oxc_parser 15.00s user 3.24s system 272% cpu 6.692 total cargo build -p oxc_parser --release 16.71s user 2.12s system 287% cpu 6.539 total cargo build -p oxc_parser --example parser 18.50s user 3.91s system 285% cpu 7.845 total cargo build -p oxc_parser --example parser --release 33.48s user 2.63s system 169% cpu 21.263 total ``` Measured on Mac Mini M4 Pro, `cargo clean` run before each. The difference appears to be mostly within the noise threshold. |
||
|
|
9e11dc63a0 |
feat(parser,estree,coverage): collect tokens in parser and convert to ESTree format (#19497)
Implement a `collect_tokens` option for parser. When enabled, the parser stores all tokens produced during parsing in a `Vec`. Implement serializing the tokens to ESTree format. Currently this is not hooked up to NAPI parser or linter. That happens in a later PR in this stack (#19498). Serialization of tokens implementation is in new `oxc_estree_tokens` crate. Unfortunately it can't go in existing `oxc_estree` crate because `oxc_ast` depends on `oxc_estree`, and the tokens serialization code requires AST types - which would be a circular dependency. We may be able to move it into another crate (parser?) later on. |
||
|
|
fc66d6dfd1 |
refactor(formatter): Remove experimental prefix from sort_imports (#19472)
Internal changes that do not affect Oxfmt users. |
||
|
|
1bb0559a32 |
feat(playground): Support more sort-imports options (#19424)
It hadn't been updated for some time, so I made it compatible with the latest state. (I also want to stop manual mapping, but we are not yet ready for that...) |
||
|
|
e48e6b2f77 |
refactor(formatter,oxfmt): Simplify sort_imports options parsing (#19418)
Introduce `GroupEntry::parse()` to reduce redundants. |
||
|
|
9c34f7226b |
feat(formatter/sort_imports)!: Report invalid group name with renaming side-effect > side_effect (#19416)
- Breaking: Rename ambiguous modifier/selector names
- `side-effect` → `side_effect`
- `side-effect-style` → `side_effect_style`
- Now `-` is used only for joiner (`modifier-modifier-selector`)
- before: `value-side-effect-style` 🆚 after: `value-side_effect_style`
- Breaking: Add config-time validation for invalid group names
- previously silently ignored...
- or wrongly applied (and user didn't notice)
|
||
|
|
4baebefa81 |
feat(formatter/sort_imports): Support { newlinesBetween: bool } inside groups (#19358)
Fixes #17830 Introduce new variant for `groups` like: ```json // "newlinesBetween": true, // Default "groups": [ ["value-builtin", "value-external"], { "newlinesBetween": false }, // 👈🏻 "value-parent", "value-sibling" ] ``` This allows you to specify line breaks globally between groups while reverting them at any position. Conversely, you can also add line breaks at any position while specifying `newlinesBetween: false`. |
||
|
|
2bf7293c69 |
feat(mangler)!: enable top_level by default for modules and commonjs (#18278)
I think we can enable `top_level` by default. refs #18233 |
||
|
|
005910a084 |
fix(linter/plugins): support plugins outside of workspace (#18755)
## The problem ### 1. Bug with plugins outside of workspace directory There was a bug in workspaces implementation. `loadPlugin` was assuming that the plugin file is within the workspace, but that's not necessarily the case. e.g.: * Workspace 1: `/path/to/project/packages/foo` * Workspace 2: `/path/to/project/packages/bar` * JS plugin: `/path/to/project/node_modules/eslint-plugin-whatever` This problem arises because `loadPlugin` is determining which workspace to load a plugin for by search for the workspace whose root directory contains the plugin file. ### 2. Performance Every call to `loadPlugin`, `setupRuleConfigs`, or `lintFile` was first searching through all workspaces to find the right one (`getResponsibleWorkspace`). This is really expensive when there are lots of workspaces, and quite expensive even when there's only 1 because iterating hashsets is relatively slow. ## This PR This PR separates out CWD and workspace identifiers into 2 different concerns. * Each workspace has an ID which is unique. * Each workspace has a CWD (path to root directory as a file path). The workspace ID is currently the workspace's root directory as a `file://...` URL. Using that as it's guaranteed unique, even for paths which are not valid UTF-8 (`Path::to_string_lossy` can produce the same `&str` for different paths). But ID it doesn't have to be the URI - we could change it later to an integer ID if we want. Rust-side code passes the workspace ID to every call to `loadPlugin`, `setupRuleConfigs`, or `lintFile`. In CLI, it just passes `null` as the ID. There's only ever 1 workspace in CLI, so no point in the expense of passing a `String` on every call. These functions look up the CWD from the workspace ID in the `cwds` map. Separating these 2 concerns solves both problems listed above: 1. Plugins can be outside of the workspace's CWD (see added test). 2. `getResponsibleWorkspace` is removed, solving the perf issue. Note: The multiple hashmap lookups on each call to `lintFile` remain a perf drain. This is addressed in a later PR in this stack. |
||
|
|
b67ab40408 |
chore(deps): update dependency rust to v1.93.0 (#18406)
This PR contains the following updates: | Package | Update | Change | |---|---|---| | [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.92.0` → `1.93.0` | --- ### Release Notes <details> <summary>rust-lang/rust (rust)</summary> ### [`v1.93.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1930-2026-01-22) [Compare Source](https://redirect.github.com/rust-lang/rust/compare/1.92.0...1.93.0) \========================== <a id="1.93.0-Language"></a> ## Language - [Stabilize several s390x `vector`-related target features and the `is_s390x_feature_detected!` macro](https://redirect.github.com/rust-lang/rust/pull/145656) - [Stabilize declaration of C-style variadic functions for the `system` ABI](https://redirect.github.com/rust-lang/rust/pull/145954) - [Emit error when using some keyword as a `cfg` predicate](https://redirect.github.com/rust-lang/rust/pull/146978) - [Stabilize `asm_cfg`](https://redirect.github.com/rust-lang/rust/pull/147736) - [During const-evaluation, support copying pointers byte-by-byte](https://redirect.github.com/rust-lang/rust/pull/148259) - [LUB coercions now correctly handle function item types, and functions with differing safeties](https://redirect.github.com/rust-lang/rust/pull/148602) - [Allow `const` items that contain mutable references to `static` (which is *very* unsafe, but not *always* UB)](https://redirect.github.com/rust-lang/rust/pull/148746) - [Add warn-by-default `const_item_interior_mutations` lint to warn against calls which mutate interior mutable `const` items](https://redirect.github.com/rust-lang/rust/pull/148407) - [Add warn-by-default `function_casts_as_integer` lint](https://redirect.github.com/rust-lang/rust/pull/141470) <a id="1.93.0-Compiler"></a> ## Compiler - [Stabilize `-Cjump-tables=bool`](https://redirect.github.com/rust-lang/rust/pull/145974). The flag was previously called `-Zno-jump-tables`. <a id="1.93.0-Platform-Support"></a> ## Platform Support - [Promote `riscv64a23-unknown-linux-gnu` to Tier 2 (without host tools)](https://redirect.github.com/rust-lang/rust/pull/148435) Refer to Rust's [platform support page][platform-support-doc] for more information on Rust's tiered platform support. [platform-support-doc]: https://doc.rust-lang.org/rustc/platform-support.html <a id="1.93.0-Libraries"></a> ## Libraries - [Stop internally using `specialization` on the `Copy` trait as it is unsound in the presence of lifetime dependent `Copy` implementations. This may result in some performance regressions as some standard library APIs may now call `Clone::clone` instead of performing bitwise copies](https://redirect.github.com/rust-lang/rust/pull/135634) - [Allow the global allocator to use thread-local storage and `std::thread::current()`](https://redirect.github.com/rust-lang/rust/pull/144465) - [Make `BTree::append` not update existing keys when appending an entry which already exists](https://redirect.github.com/rust-lang/rust/pull/145628) - [Don't require `T: RefUnwindSafe` for `vec::IntoIter<T>: UnwindSafe`](https://redirect.github.com/rust-lang/rust/pull/145665) <a id="1.93.0-Stabilized-APIs"></a> ## Stabilized APIs - [`<[MaybeUninit<T>]>::assume_init_drop`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_drop) - [`<[MaybeUninit<T>]>::assume_init_ref`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_ref) - [`<[MaybeUninit<T>]>::assume_init_mut`](https://doc.rust-lang.org/stable/core/primitive.slice.html#method.assume_init_mut) - [`<[MaybeUninit<T>]>::write_copy_of_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.write_copy_of_slice) - [`<[MaybeUninit<T>]>::write_clone_of_slice`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.write_clone_of_slice) - [`String::into_raw_parts`](https://doc.rust-lang.org/stable/std/string/struct.String.html#method.into_raw_parts) - [`Vec::into_raw_parts`](https://doc.rust-lang.org/stable/std/vec/struct.Vec.html#method.into_raw_parts) - [`<iN>::unchecked_neg`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_neg) - [`<iN>::unchecked_shl`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_shl) - [`<iN>::unchecked_shr`](https://doc.rust-lang.org/stable/std/primitive.isize.html#method.unchecked_shr) - [`<uN>::unchecked_shl`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unchecked_shl) - [`<uN>::unchecked_shr`](https://doc.rust-lang.org/stable/std/primitive.usize.html#method.unchecked_shr) - [`<[T]>::as_array`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_array) - [`<[T]>::as_array_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.as_mut_array) - [`<*const [T]>::as_array`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_array) - [`<*mut [T]>::as_array_mut`](https://doc.rust-lang.org/stable/std/primitive.pointer.html#method.as_mut_array) - [`VecDeque::pop_front_if`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.pop_front_if) - [`VecDeque::pop_back_if`](https://doc.rust-lang.org/stable/std/collections/struct.VecDeque.html#method.pop_back_if) - [`Duration::from_nanos_u128`](https://doc.rust-lang.org/stable/std/time/struct.Duration.html#method.from_nanos_u128) - [`char::MAX_LEN_UTF8`](https://doc.rust-lang.org/stable/std/primitive.char.html#associatedconstant.MAX_LEN_UTF8) - [`char::MAX_LEN_UTF16`](https://doc.rust-lang.org/stable/std/primitive.char.html#associatedconstant.MAX_LEN_UTF16) - [`std::fmt::from_fn`](https://doc.rust-lang.org/stable/std/fmt/fn.from_fn.html) - [`std::fmt::FromFn`](https://doc.rust-lang.org/stable/std/fmt/struct.FromFn.html) <a id="1.93.0-Cargo"></a> ## Cargo - [Enable CARGO\_CFG\_DEBUG\_ASSERTIONS in build scripts based on profile](https://redirect.github.com/rust-lang/cargo/pull/16160/) - [In `cargo tree`, support long forms for `--format` variables](https://redirect.github.com/rust-lang/cargo/pull/16204/) - [Add `--workspace` to `cargo clean`](https://redirect.github.com/rust-lang/cargo/pull/16263/) <a id="1.93.0-Rustdoc"></a> ## Rustdoc - [Remove `#![doc(document_private_items)]`](https://redirect.github.com/rust-lang/rust/pull/146495) - [Include attribute and derive macros in search filters for "macros"](https://redirect.github.com/rust-lang/rust/pull/148176) - [Include extern crates in search filters for `import`](https://redirect.github.com/rust-lang/rust/pull/148301) - [Validate usage of crate-level doc attributes](https://redirect.github.com/rust-lang/rust/pull/149197). This means if any of `html_favicon_url`, `html_logo_url`, `html_playground_url`, `issue_tracker_base_url`, or `html_no_source` either has a missing value, an unexpected value, or a value of the wrong type, rustdoc will emit the deny-by-default lint `rustdoc::invalid_doc_attributes`. <a id="1.93.0-Compatibility-Notes"></a> ## Compatibility Notes - [Introduce `pin_v2` into the builtin attributes namespace](https://redirect.github.com/rust-lang/rust/pull/139751) - [Update bundled musl to 1.2.5](https://redirect.github.com/rust-lang/rust/pull/142682) - [On Emscripten, the unwinding ABI used when compiling with `panic=unwind` was changed from the JS exception handling ABI to the wasm exception handling ABI.](https://redirect.github.com/rust-lang/rust/pull/147224) If linking C/C++ object files with Rust objects, `-fwasm-exceptions` must be passed to the linker now. On nightly Rust, it is possible to get the old behavior with `-Zwasm-emscripten-eh=false -Zbuild-std`, but it will be removed in a future release. - The `#[test]` attribute, used to define tests, was previously ignored in various places where it had no meaning (e.g on trait methods or types). Putting the `#[test]` attribute in these places is no longer ignored, and will now result in an error; this may also result in errors when generating rustdoc. [Error when `test` attribute is applied to structs](https://redirect.github.com/rust-lang/rust/pull/147841) - Cargo now sets the `CARGO_CFG_DEBUG_ASSERTIONS` environment variable in more situations. This will cause crates depending on `static-init` versions 1.0.1 to 1.0.3 to fail compilation with "failed to resolve: use of unresolved module or unlinked crate `parking_lot`". See [the linked issue](https://redirect.github.com/rust-lang/rust/issues/150646#issuecomment-3718964342) for details. - [User written types in the `offset_of!` macro are now checked to be well formed.](https://redirect.github.com/rust-lang/rust/issues/150465/) - `cargo publish` no longer emits `.crate` files as a final artifact for user access when the `build.build-dir` config is unset - [Upgrade the `deref_nullptr` lint from warn-by-default to deny-by-default](https://redirect.github.com/rust-lang/rust/pull/148122) - [Add future-incompatibility warning for `...` function parameters without a pattern outside of `extern` blocks](https://redirect.github.com/rust-lang/rust/pull/143619) - [Introduce future-compatibility warning for `repr(C)` enums whose discriminant values do not fit into a `c_int` or `c_uint`](https://redirect.github.com/rust-lang/rust/pull/147017) - [Introduce future-compatibility warning against ignoring `repr(C)` types as part of `repr(transparent)`](https://redirect.github.com/rust-lang/rust/pull/147185) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi44NS4xIiwidXBkYXRlZEluVmVyIjoiNDIuODUuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> |
||
|
|
984d5c1ca6 |
feat(oxfmt/sort-imports): support options.customGroups (#17576)
#17076 ### Authorship & Use of AI All code changes in this pull request are completed by a human (myself). ChatGPT is used **only** to assist with writing comments and this PR description. ### Commit Structure The changes are split into small, meaningful commits. Each commit should be reviewable independently. ## Current State of the Implementation For easier comparison, I forked [actual](https://github.com/nilptr/actual) and made a few auxiliary changes on a separate branch [nilptr/feat/oxfmt-custom-groups](https://github.com/nilptr/actual/tree/nilptr/feat/oxfmt-custom-groups). The auxiliary changes include: - Upgraded `oxfmt` to address the incompatible binding API. - Updated `eslint.config.mjs` to lint and fix .ts files. - Updated `.oxfmtrc` to enable `experimentalSortImports`, keeping it consistent with `eslint.config.mjs`. ### How to Compare? 1. Clone `git@github.com:nilptr/actual.git` and check out `nilptr/feat/oxfmt-custom-groups` branch. 2. Run `yarn install` 3. Run `NAPI_RS_NATIVE_LIBRARY_PATH=/path/to/binding.node yarn fmt:oxfmt` The native binding can be obtained in one of the following ways: - Download the [oxfmt.darwin-arm64.node.zip](https://github.com/user-attachments/files/24402116/oxfmt.darwin-arm64.node.zip) built by me (if you trust it, or scan it with [VirusTotal](https://www.virustotal.com/gui/home/upload)). - Build it by yourself: clone my repo, run `pnpm build`, and locate the .node binding file under `apps/oxfmt/src-js`. 4. Inspect the results with `git diff` — the diff shows the differences between perfectionist and oxfmt ### Observed Differences There are 9 differences in total: - **4 differences** are unrelevant to `experimentalSortImports`. (be the way, they are introduced after I rebased main branch) - **5 differences** are relevant to `experimentalSortImports`, but are not caused by the group-matching logic, which is the focus of this PR. - 4 of them are blank lines after side-effect imports being removed - 1 of them is the wrong `ImportLineMetadata.source` <img width="4064" height="2152" alt="image" src="https://github.com/user-attachments/assets/8b4cb860-19d6-42b9-a0a4-6db0b3e40194" /> <img width="4064" height="2152" alt="image" src="https://github.com/user-attachments/assets/e2616d7b-b4b2-4dbc-a0d3-ea15d1c0177e" /> ------ I believe we can start review now. While the review is ongoing, I will also try to see whether the observed differences can be fixed in this PR. --------- Co-authored-by: Yuji Sugiura <y.sugiura.0316@gmail.com> |
||
|
|
26ed46bc02 |
feat(formatter): add TailwindCSS support for JS/TS files (#16990)
Based on https://github.com/oxc-project/oxc/pull/16826 ## Summary Add experimental Tailwind CSS class sorting support to Oxfmt via integration with `prettier-plugin-tailwindcss`. This implementation uses a patch-based approach to export necessary functions from `prettier-plugin-tailwindcss`. We've requested better integration support from the Tailwind team at https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/430, and can improve the integration when that's available. ## Features - ✅ Sorts Tailwind CSS classes in `className` and `class` attributes - ✅ Sorts classes in custom JSX attributes (configurable) - ✅ Sorts classes in function calls like `clsx()`, `cn()`, `tw()` (configurable) - ✅ Supports template literals with expressions - ✅ Supports Tailwind v3 config files and v4 stylesheets - ✅ Preserves whitespace and duplicates (configurable) - ✅ **Fixes [prettier-plugin-tailwindcss#426](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/426)** - Correctly handles strings in nested non-Tailwind call expressions - ⏳ Non-JS file support (HTML, Vue, Svelte, etc.) - Coming in follow-up PR - ⏳ Tailwind CSS config migration in `oxfmt --migrate=prettier` - Coming in follow-up PR ## Example Usage ### Basic Usage Enable Tailwind CSS sorting with default options by setting `experimentalTailwindcss` to an empty object in your `.oxfmtrc.json`: ```json { "experimentalTailwindcss": {} } ``` ### With Configuration Options ```json { "experimentalTailwindcss": { "config": "./tailwind.config.js", "functions": ["clsx", "cn", "cva", "tw"], "attributes": ["myCustomClass"], "preserveWhitespace": false, "preserveDuplicates": false } } ``` ### Configuration Options All options from `prettier-plugin-tailwindcss` are supported (with `tailwind` prefix removed): | Option | Type | Description | Default | |--------|------|-------------|---------| | `config` | `string` | Path to your Tailwind CSS v3 configuration file. Paths are resolved relative to the Oxfmt configuration file. | `"./tailwind.config.js"` | | `stylesheet` | `string` | Path to your Tailwind CSS v4 stylesheet. Paths are resolved relative to the Oxfmt configuration file. | `undefined` | | `functions` | `string[]` | List of custom function names that contain Tailwind CSS classes (e.g., `["clsx", "cn", "cva", "tw"]`). | `[]` | | `attributes` | `string[]` | List of custom JSX attributes that should be sorted (e.g., `["myCustomClass"]`). Note: `class` and `className` are always sorted by default. | `[]` | | `preserveWhitespace` | `boolean` | Preserve whitespace around classes. | `false` | | `preserveDuplicates` | `boolean` | Preserve duplicate classes. | `false` | ## Migration from prettier-plugin-tailwindcss If you're currently using `prettier-plugin-tailwindcss`, you can migrate to Oxfmt's built-in support: ### Manual Migration (Current) #### Before (Prettier) ```json { "plugins": ["prettier-plugin-tailwindcss"], "tailwindConfig": "./tailwind.config.js", "tailwindFunctions": ["clsx", "cn"] } ``` #### After (Oxfmt) ```json { "experimentalTailwindcss": { "config": "./tailwind.config.js", "functions": ["clsx", "cn"] } } ``` **Key differences:** - Remove `tailwind` prefix from all option names (e.g., `tailwindConfig` → `config`) - No need to install `prettier-plugin-tailwindcss` separately, it is bundled within Oxfmt ### Automated Migration (Follow-up PR) Tailwind CSS configuration migration will be added to the existing `oxfmt --migrate=prettier` command in a follow-up PR. This will automatically convert your `prettier-plugin-tailwindcss` settings from `.prettierrc` to `.oxfmtrc.json`. ## Implementation Details ### Technical Approach - Uses `pnpm patch` to export necessary functions from `prettier-plugin-tailwindcss` - Implements Rust-side detection for Tailwind contexts (JSX attributes, function calls, template literals) - Passes class strings to the JS plugin for sorting via external callback - Optimized context tracking to avoid repeated AST traversal ### Improvements Over prettier-plugin-tailwindcss - **Context-based quasi position tracking** ([tailwindcss.rs:273-276](https://github.com/oxc-project/oxc/blob/main/crates/oxc_formatter/src/utils/tailwindcss.rs#L273-L276)) - Stores template literal position in context stack instead of traversing AST, improving performance - **Fixes [issue #426](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/426)** - Correctly handles strings in nested non-Tailwind call expressions (e.g., `value.includes("\n")` no longer gets corrupted) - **Comprehensive edge case testing** - Added 58 tests covering edge cases, nested scenarios, error handling, and performance ## Changes - Changed `experimentalTailwindcss` option from `boolean` to `TailwindcssOptions` object - Added all configuration options from `prettier-plugin-tailwindcss` (without `tailwind` prefix) - Exported necessary functions from `prettier-plugin-tailwindcss` via patch - Added comprehensive test suite with 58 tests - Improved documentation for all configuration options ## Test Plan - [x] `pnpm test` passes (58 tests) - [x] `cargo clippy` passes - [x] `just fmt` passes - [x] Basic Tailwind class sorting works with `class` and `className` attributes - [x] `attributes` option sorts custom JSX attributes - [x] `functions` option sorts string arguments in function calls (e.g., `clsx()`, `cn()`) - [x] Template literals with expressions handle whitespace correctly - [x] Edge cases: empty strings, Unicode, emoji, special characters - [x] Nested scenarios: deeply nested template literals, function calls - [x] Strings in nested non-Tailwind calls are preserved (fixes [#426](https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/426)) - [x] Test in https://github.com/tailwindlabs/headlessui and https://github.com/dubinc/dub ## Follow-up Work - **Non-JS file support** - HTML, Vue, Svelte, etc. by enabling original plugin when `experimentalTailwindcss` is set - **Migration support** - Add Tailwind CSS config migration to existing `oxfmt --migrate=prettier` command - **Better integration** - Improve when https://github.com/tailwindlabs/prettier-plugin-tailwindcss/issues/430 is resolved 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
3741b8171c |
chore(deps): update napi (#17481)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | Type | Update | |---|---|---|---|---|---|---|---| | [@napi-rs/cli](https://napi.rs/) ([source](https://redirect.github.com/napi-rs/napi-rs)) | [`3.5.0` → `3.5.1`](https://renovatebot.com/diffs/npm/@napi-rs%2fcli/3.5.0/3.5.1) |  |  |  |  | pnpm.catalog.default | patch | | [napi](https://redirect.github.com/napi-rs/napi-rs) | `3.7.1` → `3.8.1` |  |  |  |  | workspace.dependencies | minor | | [napi-derive](https://redirect.github.com/napi-rs/napi-rs) | `3.4.1` → `3.5.0` |  |  |  |  | workspace.dependencies | minor | --- ### Release Notes <details> <summary>napi-rs/napi-rs (@​napi-rs/cli)</summary> ### [`v3.5.1`](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.5.0...@napi-rs/cli@3.5.1) [Compare Source](https://redirect.github.com/napi-rs/napi-rs/compare/@napi-rs/cli@3.5.0...@napi-rs/cli@3.5.1) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox. 👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://redirect.github.com/renovatebot/renovate/discussions) if that's undesired. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi41OS4wIiwidXBkYXRlZEluVmVyIjoiNDIuNjYuMTQiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=--> |
||
|
|
6cf7173c29 |
chore(deps): update dependency oxfmt to ^0.20.0 (#17263)
This PR contains the following updates: | Package | Change | [Age](https://docs.renovatebot.com/merge-confidence/) | [Adoption](https://docs.renovatebot.com/merge-confidence/) | [Passing](https://docs.renovatebot.com/merge-confidence/) | [Confidence](https://docs.renovatebot.com/merge-confidence/) | |---|---|---|---|---|---| | [oxfmt](https://oxc.rs) ([source](https://redirect.github.com/oxc-project/oxc/tree/HEAD/npm/oxfmt)) | [`^0.19.0` -> `^0.20.0`](https://renovatebot.com/diffs/npm/oxfmt/0.19.0/0.20.0) |  |  |  |  | --- ### Release Notes <details> <summary>oxc-project/oxc (oxfmt)</summary> ### [`v0.20.0`](https://redirect.github.com/oxc-project/oxc/blob/HEAD/npm/oxfmt/CHANGELOG.md#0200---2025-12-22) [Compare Source](https://redirect.github.com/oxc-project/oxc/compare/oxfmt_v0.19.0...oxfmt_v0.20.0) ##### 🚀 Features - [`97a02d1`](https://redirect.github.com/oxc-project/oxc/commit/97a02d1) oxfmt: Add `insertFinalNewline` option ([#​17251](https://redirect.github.com/oxc-project/oxc/issues/17251)) (leaysgur) </details> --- ### Configuration 📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined). 🚦 **Automerge**: Enabled. ♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox. 🔕 **Ignore**: Close this PR and you won't be reminded about this update again. --- - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box --- This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0Mi41OS4wIiwidXBkYXRlZEluVmVyIjoiNDIuNTkuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> |
||
|
|
c8281dd0bb |
chore(pnpm): move workspace devDependencies to used packages (#16982)
To ensure monorepo dependencies are only visible to where they are used. |
||
|
|
4cbedc9437 |
fix(playground): pass transform target to minifier (#16910)
The playground minifier was not respecting the transform target option, causing ES features like optional chaining to be used even when targeting older browsers that do not support them. Closes #16889 |
||
|
|
6fca2f7f60 |
chore(infra): use oxfmt for all files, remove dprint (#16599)
Toml formatting is missing but there's only a few toml files, can wait for oxfmt plugins. - [x] Something is slow, can't figure out why, need #16607 |
||
|
|
afd6c44cd7 |
feat(oxfmt): Support quoteProps: consistent in Oxfmtrc (#16721)
Follow up #16677, fixes #16247. |
||
|
|
083fea9fa6 |
feat(napi/parser)!: represent empty optional fields on JS side as null (#16411)
Follow-on after #16383 and #16403. While working on those I discovered an option NAPI-RS has to represent `Option::None` as `null`, instead of omitting the field entirely. Use that option on the structs used for transferring errors and module record over to JS. I think this is likely more performant because: 1. NAPI-RS can create all properties of the objects using only the faster `node_api_create_object_with_properties` API. 2. It produces consistent object shapes, so JS engine can better optimize code using these objects. It also brings the shape of the data perfectly into line between standard transfer and raw transfer, and is consistent with how empty fields in the AST are represented as `null`. I would have used this option before if I'd known it existed. ### Breaking change I've marked this as a breaking change because code consuming these objects would now need to check for empty fields with `value === null` instead of `value === undefined`. However in practice, most people probably use `!value` or `value ?? ...`, so it's unlikely to affect many users. This only affects module record and errors anyway, not the AST itself, as we transfer that as JSON, not via NAPI. |
||
|
|
8c2d09f39f |
refactor(formatter/sort-imports): Resolve default options.(internalPattern|groups) in options.rs (#16375)
Yet another pure refactoring. |
||
|
|
e5a78ed269 |
refactor(formatter/sort-imports): Move SortImportsOptions to sort_imports/options.rs (#16374)
Pure refactoring. |
||
|
|
73748568af |
feat(formatter/sort-imports): Support options.internalPattern (#16372)
Part of #14253 The original implementation accepts a `RegExp` string, but based on the actual usage, it seems that checking as prefix is sufficient for now. https://github.com/search?q=%22internalPattern%3A+%5B%22&type=code |