mirror of
https://github.com/oxc-project/oxc.git
synced 2026-09-14 19:36:11 +08:00
agent/fix-react-compiler-numeric-object-keys
798 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
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=--> |
||
|
|
38aea543e4 |
release(crates): oxc v0.124.0 (#21084)
### 🐛 Bug Fixes - |
||
|
|
71604dda84 |
chore(deps): update dependency esbuild to ^0.28.0 (#21075)
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/) | |---|---|---|---|---|---| | [esbuild](https://redirect.github.com/evanw/esbuild) | [`^0.27.0` → `^0.28.0`](https://renovatebot.com/diffs/npm/esbuild/0.27.7/0.28.0) |  |  |  |  | --- ### Release Notes <details> <summary>evanw/esbuild (esbuild)</summary> ### [`v0.28.0`](https://redirect.github.com/evanw/esbuild/blob/HEAD/CHANGELOG.md#0280) [Compare Source](https://redirect.github.com/evanw/esbuild/compare/v0.27.7...v0.28.0) - Add support for `with { type: 'text' }` imports ([#​4435](https://redirect.github.com/evanw/esbuild/issues/4435)) The [import text](https://redirect.github.com/tc39/proposal-import-text) proposal has reached stage 3 in the TC39 process, which means that it's recommended for implementation. It has also already been implemented by [Deno](https://docs.deno.com/examples/importing_text/) and [Bun](https://bun.com/docs/guides/runtime/import-html). So with this release, esbuild also adds support for it. This behaves exactly the same as esbuild's existing [`text` loader](https://esbuild.github.io/content-types/#text). Here's an example: ```js import string from './example.txt' with { type: 'text' } console.log(string) ``` - Add integrity checks to fallback download path ([#​4343](https://redirect.github.com/evanw/esbuild/issues/4343)) Installing esbuild via npm is somewhat complicated with several different edge cases (see [esbuild's documentation](https://esbuild.github.io/getting-started/#additional-npm-flags) for details). If the regular installation of esbuild's platform-specific package fails, esbuild's install script attempts to download the platform-specific package itself (first with the `npm` command, and then with a HTTP request to `registry.npmjs.org` as a last resort). This last resort path previously didn't have any integrity checks. With this release, esbuild will now verify that the hash of the downloaded binary matches the expected hash for the current release. This means the hashes for all of esbuild's platform-specific binary packages will now be embedded in the top-level `esbuild` package. Hopefully this should work without any problems. But just in case, this change is being done as a breaking change release. - Update the Go compiler from 1.25.7 to 1.26.1 This upgrade should not affect anything. However, there have been some significant internal changes to the Go compiler, so esbuild could potentially behave differently in certain edge cases: - It now uses the [new garbage collector](https://go.dev/doc/go1.26#new-garbage-collector) that comes with Go 1.26. - The Go compiler is now more aggressive with allocating memory on the stack. - The executable format that the Go linker uses has undergone several changes. - The WebAssembly build now unconditionally makes use of the sign extension and non-trapping floating-point to integer conversion instructions. You can read the [Go 1.26 release notes](https://go.dev/doc/go1.26) for more information. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "before 10am on monday" in timezone Asia/Shanghai, 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:eyJjcmVhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ1cGRhdGVkSW5WZXIiOiI0My4xMDIuMTEiLCJ0YXJnZXRCcmFuY2giOiJtYWluIiwibGFiZWxzIjpbXX0=--> |
||
|
|
a4ac3ce514 |
refactor(linter/plugins): import getNodeLoc instead of injecting it (#21026)
Refacfor. In a strange pattern, we were injecting `getNodeLoc` into `deserialize.js` module on every call to `deserializeProgramOnly`. It's a static function, so just import it. |
||
|
|
fb52383874 |
perf(napi/parser, linter/plugins): clear buffers and source texts earlier (#21025)
There's no need to defer clearing vars containing buffers and source text in raw transfer deserializer module until end of linting. It was a left-over from when this module contained code which lazily deserialized comments, but that's now done elsewhere. Clear these vars as soon as deserialization is complete. Buffer and `sourceText` are still held in vars in other modules until linting completes, but `sourceTextLatin` (introduced in #21021) can be freed immediately. |
||
|
|
3b7dec4dbb |
perf(napi/parser, linter/plugins): use utf8Slice for decoding UTF-8 strings (#21022)
Optimize raw transfer string decoding.
Replace `TextDecoder("utf8")` with `Buffer.prototype.utf8Slice` to decode Rust UTF-8 strings to JS strings.
Benchmarks show this is an average 5% speed-up in `deserializeStr`, though the reason why is unclear. It skips various checks, and avoids creating a temporary `Uint8Array` (which is required with `TextDecoder.decode`) which trims 60 bytes of the size of the assembly created for `deserializeStr`. But that's not enough to explain the speed-up 🤷. Anyway, take the win.
|
||
|
|
012c924a04 |
perf(napi/parser, linter/plugins): speed up decoding strings in raw transfer (#21021)
Improve perf of deserializing strings in raw transfer. This PR combines several optimizations, which have been tested and benchmarked in https://github.com/overlookmotel/oxc-raw-str-bench. This PR implements the version "latin-slice-onebyte64" from that repo, which is the current winner. String deserialization is the main bottleneck in raw transfer, so speeding it up will likely make a large impact on deserialization overall. This work follows on from #20834 which produced a major speed-up in many files by making files which contain some non-ASCII characters take the fast path of slicing `sourceText` more often. This PR tackles the remainder - speeding up the fallback path where the fast path can't be taken. ## Optimizations The optimizations in this PR are: ### Latin1 When source is not 100% ASCII, decode source text from buffer as Latin1. A Latin1-decoded string represents each UTF-8 byte as a single Latin1 character, so it can be indexed into using UTF-8 offsets. So when we can't slice the string from `sourceText` because the UTF-8 and UTF-16 offsets differ (after any non-ASCII character), loop through the string's bytes and check if they're all ASCII. If they are, the string can be sliced from `sourceTextLatin` instead, with the original UTF-8 offsets. This is way faster than calling `textDecoder.decode`, as it avoids a call into C++. [Benchmarks show](https://github.com/overlookmotel/oxc-raw-str-bench/blob/4f96275efa9a35d5d27615abb27f21a137149cc0/README.md#apply30-vs-latin-vs-latin-source64) speed up of 55% on average, and up to 70% on some files. ### Latin1 decoding method It turns out that `new TextDecoder("latin1").decode(arr)` doesn't actually decode to Latin1! Per the WHATWG Encoding Standard, "latin1" is mapped to "windows-1252". The result is that with `TextDecoder("latin1")`: 1. `decode` is quite complicated, requiring a 2-pass scan of the bytes to determine if they're all ASCII, followed by a 2nd pass to do the actual `windows-1252` decoding. If the string *does* contain any non-ASCII characters (which it always does in our usecase), NodeJS implements the decoding in JS, not native code. Slow. 2. `decode` produces a 2-byte-per-char string (`TWO_BYTE` in V8), which takes more memory, and is slower for all operations on it e.g. string comparison, hashing for use as an object key etc. Instead, use `Buffer.prototype.latin1Slice` which: 1. Does a pure Latin1 decode, which is just a single `memcpy` call. 2. Produces a 1-byte-per-char string (`ONE_BYTE` in V8). `latin1Slice` involves a call into C++, but we only do it once per file, so this cost is tiny in context of deserializing the whole AST. ### Latin1 string slicing In the fast path, slice from the Latin1-decoded string, instead of `sourceText`. In the fast path, we know that all bytes of source comprising the string are ASCII, so no further checks are required. This makes no difference on benchmarks for `deserializeStr` itself, but it may have beneficial effects downstream for code (e.g. lint rules) which access strings in the AST, e.g. `Identifier` names. Because Latin1-decoded source text is `ONE_BYTE`-encoded, slices of it are too. In comparison, slices of `sourceText` may be `ONE_BYTE` or `TWO_BYTE`. If a file's source is pure ASCII, it'll be `ONE_BYTE`, if source contains any non-ASCII characters, it'll be `TWO_BYTE`. Files in a repo will likely be a mix of both, which makes strings returned from `deserializeStr` and placed in the AST a mix too. This in turn makes functions (e.g. lint rule visitors) polymorphic. V8 cannot optimize them as aggressively as if they see only `ONE_BYTE` strings. We cannot make sure that all strings returned by `deserializeStr` are `ONE_BYTE`. Some string may contain non-ASCII characters, and they *have* to be represented in `TWO_BYTE` form. But we can minimize it - now only strings which *themselves* contain non-ASCII characters are `TWO_BYTE`, whereas before they would be if the source text as a whole contains a single non-ASCII byte. Code which accesses `Identifier` names, for example will exclusively see `ONE_BYTE` strings and will be more heavily optimized, because Unicode `Identifier`s are rarer than hen's teeth in real-world code. ### Remove string-concatenation loop Previously strings which are outside of source text were assembled byte-by-byte in a loop via concatenation. Instead, check that all the bytes are ASCII first, copy them into an array and pass that array to `String.fromCharCode` with `fromCharCode.apply(null, array)`. To avoid allocating a fresh array every time, hold a stock of arrays for all string lengths that this path can require, and reuse them. This is a variation on the approach that #20883 took, but without the massive switch. This produces much tighter assembly, and avoids regressing the fast path due making `deserializeStr` a very large function. Despite the complexity, and multiple operations, [this is up to 3x faster](https://github.com/overlookmotel/oxc-raw-str-bench/blob/4f96275efa9a35d5d27615abb27f21a137149cc0/README.md#apply30-vs-switch30) than the switch approach, and gives an average 30% speed-up. ### Increase native call threshold The above optimizations make the slow path much faster. This shifts the tipping point at which it's faster to make a native call to `TextDecoder.decode` from 9 bytes to 64 bytes. Most strings now avoid the native call and stay in JS code which is heavily optimized by Turbofan. The tipping point of 64 is something of a guesstimate. Benchmarking shows its in the right ballpark, but we could finesse it, and probably squeeze out another couple of %. ## Credit The Latin1 string technique was cooked up by @joshuaisaact in https://github.com/overlookmotel/oxc-raw-str-bench/pull/1. All credit to him for this masterstroke which cracks the whole problem! |
||
|
|
55e1e9b1d2 |
perf(napi/parser, linter/plugins): initialize vars as 0 (#21020)
Tiny optimization to raw transfer string deserialization. Initialize vars which contain integers as `0`. This may help V8 optimize usage of these variables as they always have SMI type. The effect, if there is one, is too small to register on benchamarks. But it's certainly not a regression, and may be a tiny gain, so why not? |
||
|
|
c25ef02453 |
perf(napi/parser, linter/plugins): simplify branch condition in deserializeStr (#21019)
Follow-on after #20834. Simplify the branch condition in `deserializeStr` for detemining if can take the fast path of just slicing `sourceText`. There's no need to check `sourceIsAscii`, just compare the offset to `firstNonAsciiPos` (the position in buffer of first non-ASCII byte in source code). When source is 100% ASCII, `firstNonAsciiPos = sourceEndPos`, so `pos < firstNonAsciiPos` passes for all positions in source. The implementation is different for parser and for Oxlint, as the source text sits in a different location in buffer - at the start in parser, at the end in Oxlint - but the principle is the same in both. [Benchmarking](https://github.com/overlookmotel/oxc-raw-str-bench) showed this speeds up `deserializeStr` by a small percentage. |
||
|
|
9f494c3bc8 |
perf(napi/parser, linter/plugins): raw transfer use String.fromCharCode in string decoding (#21018)
Small optimization to raw transfer string deserialization. Use `String.fromCharCode`instead of `String.fromCodePoint`. [Benchmarking](https://github.com/overlookmotel/oxc-raw-str-bench) showed it's slightly faster, as it's simpler - doesn't need to handle astral code points. |
||
|
|
15546c0261 |
refactor(napi/parser, linter/plugins): shorten raw transfer deserializers for Options (#20924)
Refactor. Just shorten the code generated for deserializing `Option`s in raw transfer deserializer. |
||
|
|
0503a78b8b |
perf(napi/parser, linter/plugins): faster deserialization of raw fields (#20923)
`raw` field of `NumericLiteral`, `StringLiteral`, `BigIntLiteral`, `RegExpLiteral`, and `JSXText` are slices of source text. So in raw transfer deserializer, skip going through `deserializeStr`, which can be slow when source contains any non-ASCII characters. Instead just slice the string from the source text directly with `sourceText.slice(start, end)`. String decoding is the slowest part of raw transfer, so this should be a significant speed gain. |
||
|
|
a24f75e9e8 |
perf(napi/parser): optimize string deserialization for non-ASCII sources (#20834)
**AI Disclosure:** Developed with Claude Code (Opus). The winning approach came out of an automated experiment loop ([auto-claude](https://github.com/joshuaisaact/auto-claude)) — I was looking for a tight feedback loop to test the tool on and the `TODO: Find best switch-over point` comment in `deserializeStr` caught my eye. 20 experiments, keep-or-revert on each (all 20 summarized in an expandable section at the bottom). All code reviewed and understood. Happy to close this if it's not useful or doesn't meet the bar. ## Why I was profiling the raw transfer deserialization path (`node --prof` on `checker.ts`) and noticed `StringAdd_CheckNone` at 13.7% of time — the single hottest function. It comes from the byte-by-byte `out += fromCodePoint(c)` loop in `deserializeStr` when `sourceIsAscii` is false. The thing is, `sourceIsAscii` is false for almost everything. All 5 NAPI bench fixtures are non-ASCII. `checker.ts` has literally one Bengali character at position 2.1M out of 2.9M. That one character disables the fast `substr` path for all ~148K strings. ## What Two changes to the generator (`tasks/ast_tools/src/generators/raw_transfer.rs`) — that's the only file with real changes. The 9 generated JS files in the diff are the mechanical output of `cargo run -p oxc_ast_tools`. **1. `firstNonAsciiPos` scan at init** — On non-ASCII sources, find the first non-ASCII byte once upfront. Strings ending before that position can still use `sourceText.substr()` since byte offsets equal char offsets in the ASCII prefix. For `checker.ts` this covers 73% of the file, for `pdf.mjs` 98%. **2. Lower TextDecoder threshold from 50 to 9** — The existing TODO asked for the right switch-over point. Experimentally, 9 is the sweet spot: `TextDecoder` beats the `fromCodePoint` concat loop for strings of 10+ bytes, and the concat loop is still faster for very short strings where the native call overhead dominates. Benchmarked on the `complicated()` test set (5 rounds of 30 iters, dropping round 1 for JIT warmup): ``` Before After checker.ts 26.7ms 13.0ms -51% cal.com.tsx 15.4ms 9.1ms -41% antd.js 53.8ms 44.7ms -17% pdf.mjs 3.8ms 4.3ms noise binder.ts 0.7ms 0.5ms noise Total 100.5ms 71.6ms -29% ``` Also verified across 15 files — the 10 non-ASCII files above plus 5 ASCII files (`react.development.js`, `binder.ts`, `moment.js`, `jquery.js`, `vue.js`). ASCII files are unchanged (our code only touches the non-ASCII path). -16% across non-ASCII files, no regressions. ## References - Addresses the `TODO: Find best switch-over point` in `STR_DESERIALIZER_BODY` - Related to perf goals in #19918 <details> <summary>I appreciate this is already a bloated PR description (sorry @overlookmotel) but given the fairly unusual approach I thought you might want to see a very short summary of all 20 experiments Claude clauded through:</summary> The loop works like this: edit code, benchmark, keep if faster, `git reset --hard` if not. Metric is total deserialization time across the benchmark corpus. **Baseline: 97.7ms** (5-file corpus, all non-ASCII) | # | Idea | Result | Verdict | |---|------|--------|---------| | 1 | Always use TextDecoder, delete the loop entirely | 99.2ms | Revert. TextDecoder's ~78ns fixed overhead kills short strings. | | 2 | Lower TextDecoder threshold from 50 to 10 (ts.js only) | 89.8ms | **Keep.** First real win — moves 50% of strings off the concat loop. | | 3 | Threshold 5 | 91.3ms | Revert. Too aggressive, too many short strings go to TextDecoder. | | 4 | Threshold 8 | 95.0ms | Revert. Worse than 10. | | 5 | Threshold 12 | 91.2ms | Revert. Worse than 10. | | 6 | Threshold 10 + unrolled `switch` on len for inline `String.fromCharCode(uint8[pos], ...)` | 90.9ms | Revert. Switch dispatch overhead eats the gain. | | 7 | Threshold 10 + special fast path for len=1 | 94.8ms | Revert. Extra branch hurts more than the 1-byte optimization helps. | | 8 | Threshold 10 + accumulate char codes in array, single `fromCharCode.apply` at end | 90.5ms | Revert. Array allocation overhead. | | 9 | Threshold 15 | 93.2ms | Revert. 10 is still the sweet spot. | | 10 | Unrolled ASCII check for bytes 1-4, TextDecoder for 5+ | 94.7ms | Revert. Branching overhead. | | 11 | **Apply threshold 10 to js.js too** (had only been changing ts.js) | 82.5ms | **Keep.** Facepalm moment — antd.js uses the JS deserializer. | | 12 | Threshold 9 in both files | 77.9ms | **Keep.** New best. | | 13 | Threshold 7 | 79.0ms | Revert. 9 wins. | | 14 | Threshold 11 | 84.8ms | Revert. 9 confirmed. | | 15 | Replace `fromCodePoint` with `String.fromCharCode` in the loop | 82.5ms | Revert. V8 optimizes the pre-extracted `fromCodePoint` better. | | 16 | Various unrolled `fromCharCode` approaches for short strings | — | Abandoned, too complex for marginal gain. | | 17 | Always TextDecoder for non-source strings (remove loop) | 96.1ms | Revert. Confirms the short-string loop IS valuable for 1-9 bytes. | | 18 | `Buffer.from().toString()` instead of TextDecoder | 80.4ms | Revert. TextDecoder is faster. | | 19 | `firstNonAsciiPos` only (use substr before it, TextDecoder after, no loop) | 84.9ms | Revert. checker.ts loved it (-34%) but antd.js hated it (+20%) because its first non-ASCII byte is at 1.3%. | | 20 | **`firstNonAsciiPos` + threshold 9 + keep the loop** | 76.4ms | **Keep.** Best of both worlds — substr where possible, TextDecoder for medium strings, loop for short. | Three things I (Claude) learned: - Experiment 11 was the biggest single win and it was just... applying the change to the other file. Embarrassing. - Every attempt to replace the `fromCodePoint` loop for short strings (1-9 bytes) made things worse. The loop is genuinely good for that range. - `firstNonAsciiPos` only works when combined with the threshold change. On its own it hurts files where non-ASCII appears early (antd.js, cal.com.tsx). </details> |
||
|
|
990763453c | release(crates): oxc v0.123.0 (#20862) | ||
|
|
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. |
||
|
|
b4408a3dd3 |
chore(deps): update npm packages (#20845)
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/) | |---|---|---|---|---|---| | [@typescript-eslint/parser](https://typescript-eslint.io/packages/parser) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser)) | [`8.57.1` → `8.57.2`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fparser/8.57.1/8.57.2) |  |  |  |  | | [@typescript-eslint/scope-manager](https://typescript-eslint.io/packages/scope-manager) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/scope-manager)) | [`8.57.1` → `8.57.2`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fscope-manager/8.57.1/8.57.2) |  |  |  |  | | [@typescript-eslint/visitor-keys](https://typescript-eslint.io) ([source](https://redirect.github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/visitor-keys)) | [`8.57.1` → `8.57.2`](https://renovatebot.com/diffs/npm/@typescript-eslint%2fvisitor-keys/8.57.1/8.57.2) |  |  |  |  | | [@vitest/browser](https://vitest.dev/guide/browser/) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/browser)) | [`4.1.0` → `4.1.2`](https://renovatebot.com/diffs/npm/@vitest%2fbrowser/4.1.0/4.1.2) |  |  |  |  | | [@vitest/browser-playwright](https://vitest.dev/config/browser/playwright) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/browser-playwright)) | [`4.1.0` → `4.1.2`](https://renovatebot.com/diffs/npm/@vitest%2fbrowser-playwright/4.1.0/4.1.2) |  |  |  |  | | [diff](https://redirect.github.com/kpdecker/jsdiff) | [`8.0.3` → `8.0.4`](https://renovatebot.com/diffs/npm/diff/8.0.3/8.0.4) |  |  |  |  | | [vitest](https://vitest.dev) ([source](https://redirect.github.com/vitest-dev/vitest/tree/HEAD/packages/vitest)) | [`4.1.0` → `4.1.2`](https://renovatebot.com/diffs/npm/vitest/4.1.0/4.1.2) |  |  |  |  | --- ### Release Notes <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/parser)</summary> ### [`v8.57.2`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/parser/CHANGELOG.md#8572-2026-03-23) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.57.1...v8.57.2) This was a version bump only for parser to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/scope-manager)</summary> ### [`v8.57.2`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/scope-manager/CHANGELOG.md#8572-2026-03-23) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.57.1...v8.57.2) This was a version bump only for scope-manager to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> <details> <summary>typescript-eslint/typescript-eslint (@​typescript-eslint/visitor-keys)</summary> ### [`v8.57.2`](https://redirect.github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/visitor-keys/CHANGELOG.md#8572-2026-03-23) [Compare Source](https://redirect.github.com/typescript-eslint/typescript-eslint/compare/v8.57.1...v8.57.2) This was a version bump only for visitor-keys to align it with other projects, there were no code changes. See [GitHub Releases](https://redirect.github.com/typescript-eslint/typescript-eslint/releases/tag/v8.57.2) for more information. You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website. </details> <details> <summary>vitest-dev/vitest (@​vitest/browser)</summary> ### [`v4.1.2`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.2) [Compare Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2) This release bumps Vitest's `flatted` version and removes version pinning to resolve `flatted`'s CVE related issues ([#​9975](https://redirect.github.com/vitest-dev/vitest/issues/9975)). ##### 🐞 Bug Fixes - Don't resolve `setupFiles` from parent directory - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9960](https://redirect.github.com/vitest-dev/vitest/issues/9960) [<samp>(7aa93)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7aa937776) - Ensure sequential mock/unmock resolution - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) and **Claude Opus 4.6** in [#​9830](https://redirect.github.com/vitest-dev/vitest/issues/9830) [<samp>(7c065)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7c06598db) - **browser**: Take failure screenshot if `toMatchScreenshot` can't capture a stable screenshot - by [@​macarie](https://redirect.github.com/macarie) in [#​9847](https://redirect.github.com/vitest-dev/vitest/issues/9847) [<samp>(faace)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/faace1fbe) - **coverage**: Correct `coverageConfigDefaults` values and types - by [@​Arthie](https://redirect.github.com/Arthie) in [#​9940](https://redirect.github.com/vitest-dev/vitest/issues/9940) [<samp>(b3c99)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/b3c992cb2) - **pretty-format**: Fix output limit over counting - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9965](https://redirect.github.com/vitest-dev/vitest/issues/9965) [<samp>(d3b7a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/d3b7a40fa) - Disable colors if agent is detected - by [@​sheremet-va](https://redirect.github.com/sheremet-va) and [@​AriPerkkio](https://redirect.github.com/AriPerkkio) in [#​9851](https://redirect.github.com/vitest-dev/vitest/issues/9851) [<samp>(6f97b)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/6f97b55dd) ##### [View changes on GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.1...v4.1.2) ### [`v4.1.1`](https://redirect.github.com/vitest-dev/vitest/releases/tag/v4.1.1) [Compare Source](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.0...v4.1.1) ##### 🚀 Features - **experimental**: - Expose `matchesTags` to test if the current filter matches tags - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9913](https://redirect.github.com/vitest-dev/vitest/issues/9913) [<samp>(eec53)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/eec53d9f5) - Introduce `experimental.vcsProvider` - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9928](https://redirect.github.com/vitest-dev/vitest/issues/9928) [<samp>(56115)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/561150036) ##### 🐞 Bug Fixes - Mark `TestProject.testFilesList` internal properly - by [@​sapphi-red](https://redirect.github.com/sapphi-red) in [#​9867](https://redirect.github.com/vitest-dev/vitest/issues/9867) [<samp>(54f26)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/54f2660f5) - Detect fixture that returns without calling `use` - by [@​oilater](https://redirect.github.com/oilater) in [#​9831](https://redirect.github.com/vitest-dev/vitest/issues/9831) and [#​9861](https://redirect.github.com/vitest-dev/vitest/issues/9861) [<samp>(633ae)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/633ae2303) - Drop vite 8.beta support - by [@​AriPerkkio](https://redirect.github.com/AriPerkkio) in [#​9862](https://redirect.github.com/vitest-dev/vitest/issues/9862) [<samp>(b78f5)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/b78f5389d) - Type regression in vi.mocked() static class methods - by [@​purepear](https://redirect.github.com/purepear) and [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9857](https://redirect.github.com/vitest-dev/vitest/issues/9857) [<samp>(90926)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/90926641b) - Properly re-evaluate actual modules of mocked external - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9898](https://redirect.github.com/vitest-dev/vitest/issues/9898) [<samp>(ae5ec)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/ae5ec03ef) - Preserve coverage report when html reporter overlaps - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9889](https://redirect.github.com/vitest-dev/vitest/issues/9889) [<samp>(2d81a)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/2d81ad897) - Provide `vi.advanceTimers` to the preview provider - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9891](https://redirect.github.com/vitest-dev/vitest/issues/9891) [<samp>(1bc3e)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/1bc3e63be) - Don't leak event listener in playwright provider - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9910](https://redirect.github.com/vitest-dev/vitest/issues/9910) [<samp>(d9355)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/d93550ff7) - Open browser in `--standalone` mode without running tests - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9911](https://redirect.github.com/vitest-dev/vitest/issues/9911) [<samp>(e78ad)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/e78adcf97) - Guard disposable and optional `body` - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9912](https://redirect.github.com/vitest-dev/vitest/issues/9912) [<samp>(6fdb2)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/6fdb2ba61) - Resolve `retry.condition` RegExp serialization issue - by [@​nstepien](https://redirect.github.com/nstepien) and [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9942](https://redirect.github.com/vitest-dev/vitest/issues/9942) [<samp>(7b605)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/7b6054328) - **collect**: - Don't treat extra props on `test` return as tests - by [@​sheremet-va](https://redirect.github.com/sheremet-va) in [#​9871](https://redirect.github.com/vitest-dev/vitest/issues/9871) [<samp>(141e7)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/141e72aa1) - **coverage**: - Simplify provider types - by [@​AriPerkkio](https://redirect.github.com/AriPerkkio) in [#​9931](https://redirect.github.com/vitest-dev/vitest/issues/9931) [<samp>(aaf9f)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/aaf9f18ae) - Load built-in provider without module runner - by [@​AriPerkkio](https://redirect.github.com/AriPerkkio) in [#​9939](https://redirect.github.com/vitest-dev/vitest/issues/9939) [<samp>(bf892)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/bf8920817) - **expect**: - Soft assertions continue after .resolves/.rejects promise errors - by [@​mixelburg](https://redirect.github.com/mixelburg), **Maks Pikov**, **Claude Opus 4.6 (1M context)** and [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9843](https://redirect.github.com/vitest-dev/vitest/issues/9843) [<samp>(6d74b)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/6d74b4948) - Fix sinon-chai style API - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) in [#​9943](https://redirect.github.com/vitest-dev/vitest/issues/9943) [<samp>(0f08d)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0f08dda2c) - **pretty-format**: - Limit output for large object - by [@​hi-ogawa](https://redirect.github.com/hi-ogawa) and **Claude Opus 4.6 (1M context)** in [#​9949](https://redirect.github.com/vitest-dev/vitest/issues/9949) [<samp>(0d5f9)</samp>](https://redirect.github.com/vitest-dev/vitest/commit/0d5f9d6ef) ##### [View changes on GitHub](https://redirect.github.com/vitest-dev/vitest/compare/v4.1.0...v4.1.1) </details> <details> <summary>kpdecker/jsdiff (diff)</summary> ### [`v8.0.4`](https://redirect.github.com/kpdecker/jsdiff/blob/HEAD/release-notes.md#804) [Compare Source](https://redirect.github.com/kpdecker/jsdiff/compare/v8.0.3...8.0.4) - [#​667](https://redirect.github.com/kpdecker/jsdiff/pull/667) - **fix another bug in `diffWords` when used with an `Intl.Segmenter`**. If the text to be diffed included a combining mark after a whitespace character (i.e. roughly speaking, an accented space), `diffWords` would previously crash. Now this case is handled correctly. </details> --- ### Configuration 📅 **Schedule**: Branch creation - "before 10am on monday" in timezone Asia/Shanghai, 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:eyJjcmVhdGVkSW5WZXIiOiI0My45NC4xIiwidXBkYXRlZEluVmVyIjoiNDMuOTQuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==--> |
||
|
|
9dd33b080c | release(crates): oxc v0.122.0 (#20648) | ||
|
|
5e0c7e518b | chore(deps): update npm packages (#20409) | ||
|
|
9a622c79b4 |
perf(linter/plugins): lazy deserialize tokens and comments (#20474)
Performance improvement to tokens and comments APIs. ## The problem Previously, all tokens and comments methods would deserialize *all* tokens/comments into an array of `Token` / `Comment` / `Token | Comment` objects, and then binary search through those arrays to find the token(s) / comment(s) they're looking for. This has 2 major disadvantages: 1. Files typically contain *a lot* of tokens (even more than the number of AST nodes). Deserializing them all is very costly (up to 30% of total Oxlint runtime when run with only a JS rule which just calls a tokens-related method). 2. The binary searches these methods do are quite expensive. Even in TurboFan-optimized code, accessing `token.start` involves getting pointer to the `Token` object from the `tokens` array, an "is this object a `Token`?" safety check, then reading the `start` field from the `Token` - all just to access a single `u32`, and that happens over and over. ## This PR's solution Solve both these problems by making tokens and comments methods read `start` / `end` offsets directly from the buffers which contain the tokens/comments data. This data is tightly packed in memory, and strongly typed (read from `Uint32Array`s), so getting `start` / `end` of a token requires no indirection and no type checks. More importantly, it removes the need to deserialize all tokens / comments upfront. The desired token(s) are located, touching only the buffer, and then *only* the ones which need to be returned to rule code are deserialized into JS objects. If a rule accesses `ast.tokens`, `ast.comments`, or `sourceCode.tokensAndComments` then all tokens / comments need to be deserialized, as they're all returned to the rule as an array - but that's unavoidable. This PR doesn't make that any cheaper, but it doesn't make it measurably more costly either. But where no rule requires the full array of tokens / comments, and they only use token/comment search methods (e.g. `getFirstToken`, `getCommentsBefore`), a great deal of work will be saved. This covers the vast majority of rules. ## Implementation details The main complication is the `includeComments` option to tokens methods. When `true`, search needs to be over a combined set of both tokens and comments. When `includeComments: true` option is passed to a tokens method, a buffer is created containing data about all tokens and comments, interleaved in source code order. This buffer can then be used for binary search in tokens methods. Whether each token / comment has been deserialized already or not is tracked by a "deserialized" flag in the tokens/comments buffers. Each token / comment in the buffer is 16 bytes. This flag lives in byte 15. For tokens, this byte is always already 0 in the buffer when it arrives from Rust side. For comments, we manually set `comment.content = CommentContent::None;` for every comment on Rust side. `comment.content` is positioned at byte 15 in the `Comment` struct, and `CommentContent::None` is stored as 0. ## Possible future improvements ### SoA storage Binary search operates only on `start` field of tokens / comments, which are 16 bytes apart in the buffer. It would be more efficient if tokens were stored in struct-of-arrays (SoA) style so all `start` values were tightly packed together. This would reduce CPU cache misses in the hot loops of binary searches. ### Pre-compute tokens-and-comments buffer on Rust side The buffer containing tokens and comments, required to support `includeComments: true`, is currently generated on JS side (but lazily). We could move that to Rust side, which would be faster. However, it might be redundant work in many cases because the buffer is only required if a rule uses `includeComments: true`. We could alternatively keep the laziness optimization, by calling back into Rust to build the buffer on demand - but JS-Rust calls have a cost too. Maybe communicating via `Atomics` would be faster than an actual function call? If we had a way to share buffers with WASM, optimal solution might be to generate the buffer lazily (as now) but in WASM, which would be faster for this kind of pure number-crunching, but without the overhead of calling into Rust. |
||
|
|
c6ea0a068d |
perf(ast): place NodeId field after Span in structs (#20584)
Alter the code in `ast_tools` which re-orders struct fields, to make `NodeId` always occupy a consistent "slot" in every AST node - at byte position 8, just after `Span`. This will be a sizeable gain once we start utilizing the `NodeId` fields more. Because, for example, every variant of `Expression` has its `NodeId` stored in same location as all the other variants, `Expression::node_id()` is just 1 operation - a pointer read - rather than a nest of branches, or a lookup table. Also alter the algorithm for ordering struct fields to fill in the 4-byte gap after `NodeId` field with other field(s), to avoid excess padding. The new algorithm also prioritizes keeping fields in definition order as much as possible, rather than sorting them strictly in order of size and alignment. This is mildly advantageous because field definition order is the order the AST is walked in, so it avoids bouncing between cache lines while iterating through the fields of a struct when visiting the AST. No types change size in the process. Fields remain packed to keep type sizes the minimum they can be - they just change order. |
||
|
|
e98466632e |
refactor(ast): re-order layout assertions in memory order (#20583)
Refactor. Generate assertions for type sizes in the order which they are in memory. This makes it easier to see how these types are laid out in memory. |
||
|
|
1be1ebe1ae |
refactor(ast_tools): search all crates which depend on oxc_ast_macros (#20577)
One annoyance with `ast_tools`, our codegen, has been that when you want it to generate code from types in some file, you had to manually add the file paths to a list in `ast_tools` itself. This PR removes that list and instead finds crates in the monorepo which depend on `oxc_ast_macros` crate, via `cargo metadata`, and searches all files in those crates for types with `#[ast]` attributes etc - types that it need to act on. There is no longer a list to keep updated, you just mark types `#[ast]` and the codegen will find them. This produces some churn in generated files. None of the generated code changes, it just gets re-ordered in some places, due to the different order that files get found in now. This order is deterministic, and it should not change again. |
||
|
|
d176eccdbf |
perf(napi/parser, oxlint/plugins): shorten deserializer for WithClause (#20575)
Small optimization to ESTree serialization and raw transfer. Shave off a little work when serializing/deserializing `WithClause`. |
||
|
|
33993feb98 |
refactor(estree): simplify ESTree converter for VariableDeclarator (#20574)
Belated follow-on after #15925. `VariableDeclarator` doesn't need a whole-struct ESTree converter. Switch to a converter just for the `id` field, to reduce custom conversion code. |
||
|
|
6cd513ffae |
release(crates): oxc v0.121.0 (#20515)
### 🚀 Features - |
||
|
|
8741e6532a |
release(crates): oxc v0.120.0 (#20422)
### 🐛 Bug Fixes - |
||
|
|
9cd612f1e9 |
perf(linter/plugins): recycle comment objects (#20362)
Apply the same optimization as #19978 to comments - hold a pool of `Comment` objects, and re-use those objects rather than creating new objects each time. Same as with `Token`s, `loc` property is a getter which calculates `loc` lazily, and caches it in a private property. |
||
|
|
e9b5546ed2 |
release(crates): oxc v0.119.0 (#20371)
### 🚀 Features - |
||
|
|
e4aa5b51c1 |
docs(parser/napi, linter/plugins): add JSDoc comments to raw transfer constants (#20286)
Comments-only change. Add JSDoc comments to the constants related to raw transfer in generated files `constants.js` / `constants.ts`. There are now a lot of constants, and it wasn't clear what they all mean. |
||
|
|
ce4ecb0ffe |
release(crates): oxc v0.118.0 (#20266)
Co-authored-by: leaysgur <6259812+leaysgur@users.noreply.github.com> |
||
|
|
1606bd1feb |
refactor(apps, napi, tasks): remove noUnusedLocals from tsconfigs (#20155)
Remove `noUnusedLocals` option from `tsconfig.json` files. It's redundant, as Oxlint `no-unused-vars` covers this for us. It's an annoyance to have `noUnusedLocals` enabled, as in VS Code TypeScript complains about unused vars, even if they're prefixed with `_`. Removing this option allows simplifying type tests added in #20066. Only reason these types had to be exported was to stop TS complaining that they were unused. |
||
|
|
dafe4ad8cc |
release(crates): oxc v0.117.0 (#20142)
### 🚀 Features - |
||
|
|
92cfb14aa4 |
fix(linter/plugins): fix types for walkProgram and walkProgramWithCfg (#20081)
Fix a mistake in our (internal) types: `walkProgramWithCfg` was missing that elements can be `CfgVisitFn`. Also refactor the types for `walkProgram`, importing the original `VisitFn` and `EnterExit` types from where they're defined. |
||
|
|
ee0491e937 |
fix(apps,napi): explicitly specify libs in tsconfigs (#20071)
Replaces #20064 The `dom` lib was implicitly being injected, this means stuff like `Token` and `Comment` were in the global scope, which was incorrect. cc @overlookmotel |
||
|
|
3a8c4a4cad |
release(crates): oxc v0.116.0 (#19911)
### 🚀 Features - |
||
|
|
05ccf9f21e |
perf(linter/plugins): transfer tokens via raw transfer (#19893)
Transfer tokens via raw transfer in Oxlint JS plugins. Deserializer is written by hand. `Token` is not a normal struct, so deserializer cannot be generated. |
||
|
|
1f9c115632 |
test(estree/tokens): add tests for tokens via raw transfer (#19885)
Implement the beginnings of support for tokens in `napi/parser`. This PR only adds support for tokens via raw transfer, and behind an undocumented `experimentalTokens` option. Add tests checking that tokens received on JS side via raw transfer match snapshots for all Test262, AcornJSX, and TypeScript test cases. They do! The tests are the main purpose of this PR, making sure it works before we switch over to tokens via raw transfer in Oxlint. We can add full tokens support to `napi/parser` (including via JSON transfer) later on. |
||
|
|
8b89309f57 |
test(napi/parser): fix tests for range, parent, and lazy on TS fixtures (#19884)
`napi/parser`'s tests for raw transfer ranges, parents, and lazy deserialization were incorrect. They were testing parsing the entire TS fixture file, which can contain multiple parts, instead of testing each part individually. Fix that. |
||
|
|
6a6513c6ab |
perf(linter/plugins): use Oxc tokens in plugins (#19498)
Builds on #19497. Use the tokens generated by Oxc's parser in linter plugins, instead of running TS parser to tokenize source. This is a sizeable perf gain, and also allows us to remove TS parser from `oxlint`'s bundle (#19531). Additionally, our parser is more accurate than TypeScript - we handle HTML comments and space before slash in closing JSX elements (`< /div>`) - so this fixes a few conformance tests. |
||
|
|
2fa936fd2b |
docs(README.md): map npm package links to npmx.dev (#19666)
## Summary - replace npm package links from npmjs.com to https://npmx.dev - only update documentation files --------- Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> |
||
|
|
7675bc43e7 |
release(crates): oxc v0.115.0 (#19626)
### 🚀 Features - |
||
|
|
08b0218dd6 | chore(submodules): update submodule SHAs to latest commits (#19518) | ||
|
|
704c109d6d |
release(crates): oxc v0.114.0 (#19429)
### 🚀 Features - |
||
|
|
ebb80b32ff |
feat(ast): add node_id field to all AST struct nodes (#18138)
## Summary - Add `pub node_id: NodeId` as the first field in all AST structs (~190 structs across js.rs, ts.rs, jsx.rs, literal.rs) - Update codegen to special-case `node_id`: - `Dummy`: Use `NodeId::DUMMY` instead of `Dummy::dummy(allocator)` - `CloneIn`: Use `NodeId::DUMMY` for regular clone, preserve ID for semantic clone - `ContentEq`: Skip `node_id` from equality comparisons - `ESTree`: Skip `node_id` from serialization - `AstBuilder`: Exclude `node_id` from builder parameters, use `NodeId::DUMMY` - Update pattern matching in minifier and transformer to use `..` for new field - Update traverse script to include `NodeId` import This is the foundational step for assigning unique IDs to AST nodes. The `node_id` defaults to `NodeId::DUMMY` (value 0) for uninitialized nodes. ## Test plan - [x] `cargo build` succeeds - [x] `cargo test` passes - [x] `just ast` regenerates code correctly 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
bcd0f6430f | fix(napi): disable mimalloc global allocator on android targets (#19214) | ||
|
|
acdb40ed42 |
release(crates): oxc v0.113.0 (#19210)
### 💥 BREAKING CHANGES - |
||
|
|
00d431d957 |
chore(oxlint,parser,e2e): explicitly set strict: false in tsconfigs (#19129)
fixes the failures seen in https://github.com/oxc-project/oxc/pull/19128 |
||
|
|
79689ba59b |
chore(napi/parser): use dot reporter in CI to reduce log output (#18974)
## Summary - Use `dot` reporter in CI to avoid logging ~58,000 test names from `parse-raw.test.ts` - `parse-raw.test.ts` runs test cases via `it.each()` from Test262 (~46k), TypeScript (~11k), and JSX (~40) fixtures 🤖 Generated with [Claude Code](https://claude.ai/code) Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> |
||
|
|
57917eef0f |
fix(parser): parse decorators on rest parameters (#18938)
## Summary - Add `decorators` field to `FormalParameterRest` to support decorators on rest parameters in TypeScript - Parse decorators before checking for rest parameters in formal parameter lists - Update semantic builder to visit decorators on rest parameters Fixes parsing of `typescript/tests/cases/compiler/sourceMapValidationDecorators.ts` 🤖 Generated with [Claude Code](https://claude.com/claude-code) |
||
|
|
487601baca |
fix(napi): disable mimalloc on Windows to fix worker_threads crash (#18923)
## Summary - Disable mimalloc as the global allocator on Windows for all NAPI packages (`oxc-parser`, `oxc-minify`, `oxc-transform`) - On Windows, packages now use the system allocator instead Fixes #15518 ## Root Cause mimalloc has known issues with DLL unloading on Windows when the DLL is loaded by the main thread but unloaded by a worker thread ([mimalloc issue #288](https://github.com/microsoft/mimalloc/issues/288)). The cleanup code has `_mi_is_main_thread()` checks that prevent proper memory cleanup when called from a non-main thread, causing `STATUS_ACCESS_VIOLATION` crashes. ## Platforms with mimalloc enabled | Platform | mimalloc | |----------|----------| | macOS | ✅ | | Linux x86_64 | ✅ | | Linux aarch64 | ✅ | | Windows | ❌ (disabled) | | FreeBSD | ❌ | | ARM 32-bit | ❌ | | WASM | ❌ | 🤖 Generated with [Claude Code](https://claude.ai/code) |