Commit Graph

20344 Commits

Author SHA1 Message Date
Cameron 991b5e5b03 fix(coverage): support merged TypeScript fixture layout 2026-09-09 14:32:45 +01:00
camc314 c8e5fa7656 fix(parser): allow escaped type names in import and export specifiers (#26487)
Allow escaped value names such as `import { t\u0079pe as x } from "m"` and the equivalent named exports. Reject escapes only after resolving `type` as a type-only modifier.

Preserve the decoded identifier name in the ambiguous `type as as` form so its AST name remains `type`.
2026-09-09 13:22:34 +00:00
camc314 2dcee2f216 fix(parser): reject async modifiers on class fields (#26486)
`class C { async x; }` was accepted in JavaScript and TypeScript, silently discarding `async` from the resulting field. Reject the modifier after parsing a class field, once fields have been distinguished from methods.

Async methods, fields named `async`, and newline-separated fields remain valid.
2026-09-09 13:04:01 +00:00
camc314 9b1aff8c0c perf(linter/unicorn/no-useless-undefined): skip calls without trailing undefined (#26481)
Return early for calls whose last argument is not `undefined`, avoiding unnecessary callee and `bind` checks. Collect trailing undefined spans with pushes followed by one reversal instead of repeated front insertions, preserving diagnostic and fix order.
2026-09-09 12:48:10 +00:00
camc314 973d58e128 fix(parser): require comma after TypeScript this parameter (#26480)
Require a comma after a TypeScript `this` parameter when the parameter list continues. Previously, malformed syntax such as `function f(this: T x: T) {}` parsed without a diagnostic.
2026-09-09 12:26:51 +00:00
renovate[bot] 629719c146 chore(deps): update dependency rolldown to v1.2.8 (#26479)
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.2.7` →
`1.2.8`](https://renovatebot.com/diffs/npm/rolldown/1.2.7/1.2.8) |
![age](https://developer.mend.io/api/mc/badges/age/npm/rolldown/1.2.8?slim=true)
|
![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/rolldown/1.2.8?slim=true)
|
![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/rolldown/1.2.7/1.2.8?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/rolldown/1.2.7/1.2.8?slim=true)
|

---

### Release Notes

<details>
<summary>rolldown/rolldown (rolldown)</summary>

###
[`v1.2.8`](https://redirect.github.com/rolldown/rolldown/blob/HEAD/CHANGELOG.md#128---2026-09-09)

[Compare
Source](https://redirect.github.com/rolldown/rolldown/compare/v1.2.7...v1.2.8)

##### 🚀 Features

- dev: add `hotUpdate` dev option to gate the `hotUpdate` hook
([#&#8203;10837](https://redirect.github.com/rolldown/rolldown/issues/10837))
by [@&#8203;h-a-n-a](https://redirect.github.com/h-a-n-a)
- docs: add wrangler
([#&#8203;10821](https://redirect.github.com/rolldown/rolldown/issues/10821))
by [@&#8203;mdong1909](https://redirect.github.com/mdong1909)

##### 🐛 Bug Fixes

- dev: clean stale dynamic entry references after partial scans
([#&#8203;10846](https://redirect.github.com/rolldown/rolldown/issues/10846))
by [@&#8203;shulaoda](https://redirect.github.com/shulaoda)
- include external wildcard re-exports in `OutputChunk.imports`
([#&#8203;10845](https://redirect.github.com/rolldown/rolldown/issues/10845))
by [@&#8203;isker](https://redirect.github.com/isker)

##### 📚 Documentation

- document dynamic entry cache merging after partial scans
([#&#8203;10848](https://redirect.github.com/rolldown/rolldown/issues/10848))
by [@&#8203;shulaoda](https://redirect.github.com/shulaoda)

##### ⚡ Performance

- cache `getModuleInfo` during code splitting
([#&#8203;10838](https://redirect.github.com/rolldown/rolldown/issues/10838))
by [@&#8203;hyfdev](https://redirect.github.com/hyfdev)

##### 🧪 Testing

- dev: cover stale dynamic entry references after partial scans
([#&#8203;10847](https://redirect.github.com/rolldown/rolldown/issues/10847))
by [@&#8203;shulaoda](https://redirect.github.com/shulaoda)

##### ⚙️ Miscellaneous Tasks

- deps: update dependency
[@&#8203;napi-rs/cli](https://redirect.github.com/napi-rs/cli) to v3.9.0
([#&#8203;10816](https://redirect.github.com/rolldown/rolldown/issues/10816))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update dependency rolldown-plugin-dts to v0.28.5
([#&#8203;10827](https://redirect.github.com/rolldown/rolldown/issues/10827))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update dependency vite-plus to v0.3.1
([#&#8203;10842](https://redirect.github.com/rolldown/rolldown/issues/10842))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: upgrade oxc to 0.149.0
([#&#8203;10834](https://redirect.github.com/rolldown/rolldown/issues/10834))
by [@&#8203;camc314](https://redirect.github.com/camc314)
- deps: update rust crates
([#&#8203;10830](https://redirect.github.com/rolldown/rolldown/issues/10830))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update npm packages
([#&#8203;10832](https://redirect.github.com/rolldown/rolldown/issues/10832))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update crate-ci/typos action to v1.50.1
([#&#8203;10824](https://redirect.github.com/rolldown/rolldown/issues/10824))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update test262 submodule for tests
([#&#8203;10836](https://redirect.github.com/rolldown/rolldown/issues/10836))
by
[@&#8203;rolldown-guard](https://redirect.github.com/rolldown-guard)\[bot]
- deps: update github actions
([#&#8203;10831](https://redirect.github.com/rolldown/rolldown/issues/10831))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]
- deps: update dependency rust to v1.98.1
([#&#8203;10819](https://redirect.github.com/rolldown/rolldown/issues/10819))
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot]

##### ❤️ New Contributors

- [@&#8203;isker](https://redirect.github.com/isker) made their first
contribution in
[#&#8203;10845](https://redirect.github.com/rolldown/rolldown/pull/10845)

</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:eyJjcmVhdGVkSW5WZXIiOiI0NC43MS4wIiwidXBkYXRlZEluVmVyIjoiNDQuNzEuMCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-09 12:04:51 +00:00
overlookmotel 88872b75ab refactor(lexer): add bm_clear function to clear a bitmap bit (#26478)
Pure refactor.

Add `bm_clear` function that clears a bit in a bitmap at specified index. This is the converse of `bm_set`, and single-bit version of `bm_clear_range`.

This operation is performed in various places across `classify`, `carve`, and `coalesce` stages. Replace the duplicated code with `bm_clear` calls. This makes the logic easier to read.

`bm_clear` is `#[inline(always)]` so this change makes zero difference to codegen. The changes in `carve_jsx` look more substantive, but compiling to ASM and diffing it before/after this PR shows 0 difference. The compiler is able to identify the repeated terms across the 4 calls - there's no need to perform that optimization manually.
2026-09-09 11:50:32 +00:00
overlookmotel 54aab0ce3d refactor(lexer): rename bm_set1 to bm_set (#26477)
Pure refactor. Just rename a function.

The `1` in `bm_set1` was unnecessary - "set" means set bit to 1, "clear" means unset bit to 0.
2026-09-09 11:50:31 +00:00
overlookmotel 3f0318739f refactor(lexer): deduplicate bitmap access code (#26461)
Code to read the nth bit of a bitmap was duplicated in several places across pipeline code:

- `wordbit` in `carve`
- `bit_at` in `regex_div`
- Various places inline in `carve`, `classify`, and `coalesce`

Add a function `bm_get` for this purpose to `bitmap` module (which feels like its natural home) and replace all usages with calls to this function.

This reduces repetition, and makes the call sites easier to read.

`bm_get` is marked `#[inline(always)]`, so extracting it into a function should have no effect on perf.
2026-09-09 08:12:06 +00:00
overlookmotel 2de2e0e578 docs(lexer): document bitmap functions (#26453)
Docs-only change. Add doc comments to all functions in `bitmap` module.
2026-09-09 08:12:06 +00:00
overlookmotel 639b7fe8eb refactor(lexer): re-order functions in bitmap module (#26452)
Pure refactor. No code changes, just moving code around.

Re-order the functions in `bitmap` module, moving `bm_next0` up to the top with the other getters.

Add line breaks between all the functions.
2026-09-09 08:12:06 +00:00
overlookmotel 6b242bae30 refactor(lexer): move write_sentinels into root of compress module (#26444)
Pure refactor. No code changes, just moving code around.

After #26443, main exported logic for `compress` stage is in `compress/mod.rs`.

`write_sentinels` is also exported from the module, so move it out of `common.rs` and into `mod.rs`, alongside `compress`. `common.rs` not only contains functions internal to the `compress` stage, shared between AVX2 and generic implementations.
2026-09-09 08:12:05 +00:00
overlookmotel 24bbc4fc1e refactor(lexer): move compress logic out of lex_raw (#26443)
Pure refactor. No code changes, just moving code around.

`compress` stage of pipeline involves several separate steps. Previously this compress-specific logic was in `lex_raw`, mixed with the logic for other stages.

This PR moves it into the `compress` module, so all that remains in `lex_raw` is a single call to `compress`.

The function that was previously called `compress` is renamed to `compress_blocks` to avoid duplicated names.
2026-09-09 08:12:05 +00:00
overlookmotel b1d2656f7d refactor(lexer): split compress pipeline stage into multiple files (#26437)
Pure refactor. No code changes, just moving code around.

Split `compress` pipeline stage into multiple files.

- `avx2.rs` / `generic.rs` - SIMD and generic impls.
- `common.rs` - Code shared between both impls.
- `mod.rs` - Minimal entry point, chooses which impl to load dependent on target.

Additionally, apply the same kinds of stylistic changes as #26390.
2026-09-09 08:12:04 +00:00
overlookmotel c2c2f2af5e refactor(lexer): group coalesce pipeline stage code into directory (#26422)
Pure refactor. No code changes, just moving code around.

Move all code for `coalesce` pipeline stage into a directory together.

`coalesce/mod.rs` contains same code as `coalesce.rs` did previously. `keyword.rs` moves into the same directory, since `kw_verify_batch` is only used in `coalesce` stage. `kw_flush` moves into `keyword.rs` as it's keyword-related.

Additionally, apply the same kinds of stylistic changes as #26390.
2026-09-09 08:12:04 +00:00
overlookmotel 6744ab8a3a refactor(lexer): move carve implementation selection out of lex_raw (#26417)
Pure refactor.

`carve` has 2 different implementations for JS and JSX. Move selecting which to use to within the `carve` module, to make `lex_raw` clearer to read.

`carve` function is marked `#[inline]` so this should make no difference whatsoever to codegen.
2026-09-09 08:12:03 +00:00
overlookmotel 9cc095c0f3 refactor(lexer): split carve pipeline stage into multiple files (#26416)
Pure refactor. No code changes, just moving code around.

Split `carve` pipeline stage into multiple files.

Unlike #26390, here there's little platform-specific code to split up. Aim is just to separate out code which is specific to JS / JSX, and split JSX code up into separate sub-systems.

Additionally, apply the same kinds of stylistic changes as #26390.
2026-09-09 08:12:03 +00:00
overlookmotel 3e8114a279 refactor(lexer): split classify pipeline stage into multiple files (#26390)
Pure refactor. No code changes, just moving code around.

Split `classify` pipeline stage into multiple files.

- `avx2.rs` / `generic.rs` - SIMD and generic impls.
- `common.rs` - Code shared between both impls.
- `mod.rs` - Minimal entry point, chooses which impl to load dependent on target.

Additionally, a few stylistic changes in Oxc "house style":

- Re-order code so it reads top-to-bottom - imports and consts first, then entry points, private fns/helpers lower down.
- Combine imports into a single `use` statements.
- Line breaks between functions.

The split of SIMD/generic into separate files is the main point. This is a precursor to switching over to runtime feature detection, instead of compile-time.
2026-09-09 08:12:02 +00:00
leaysgur 9dbddcaf48 fix(formatter): keep group flat for own-line comment in JSX (#26475)
Fixes #26466
2026-09-09 07:40:23 +00:00
leaysgur f579ec235c test(formatter_json): run json-test-suite snippets (#26473)
Follow up on https://github.com/oxc-project/oxc/pull/26469 for JSON.
2026-09-09 06:40:18 +00:00
leaysgur d226e6f43c fix(formatter_yaml): bump oxc-yaml-parser to 0.0.6 (#26472)
> https://github.com/oxc-project/oxc-yaml-parser/releases/tag/oxc-yaml-parser-v0.0.6

Fixed scanner bugs to parse more files.
2026-09-09 06:40:18 +00:00
leaysgur 8b41fc0904 fix(formatter_yaml): clamp tab_width: 0 to 1 to keep semantics (#26471)
`tabWidth: 0` is valid for many languages like:

```js
const a = {
k: "0 indent!"
}
```

But not for YAML.
2026-09-09 06:40:17 +00:00
leaysgur 4846f8d37d test(formatter_yaml): adjudicate the snippet-suite failures (#26470)
Follow up on #26469 for YAML.
2026-09-09 06:40:17 +00:00
leaysgur dc45cc3403 feat(formatter_test): test Prettier dynamic snippet tests (#26469)
Enable Prettier's dynamic snippet tests with `xxx-test-suite` module.

They do not have physical file, so need to slice during conformance run.
2026-09-09 06:40:17 +00:00
leaysgur dea2ba0f98 fix(formatter_core): do not panic with align(0) (#26468)
Prevent YAML formatter panic in certain case. And also supports `tabWidth: 0` as valid case.
2026-09-09 06:40:16 +00:00
leaysgur bf1d3f60bd fix(formatter): check this_param for simple parameters test (#26474)
Fixes #26465, also fixes test-call does not count `this` params as well.
2026-09-09 06:33:58 +00:00
Armano 80a76a0a2b feat(minifier): negate binary comparison for typeof x < 'u' (#26367)
Allow inversion of binary operation when comparing `'u'` string with
`typeof

`!(typeof a < "u")` => `typeof a > "u"`
`!(typeof a > "u")` => `typeof a < "u"`

this is needed to support negation of short version of `typeof x ===
"undefined"` -> `typeof a > "u"` generated by
`substitute_typeof_undefined`

fixes #25294
related #26460
2026-09-09 09:19:02 +08:00
camc314 d198982c08 perf(codegen): outline postfix source mapping work (#26450)
Keep the precedence and source-map availability checks in an inline wrapper, and move the remaining postfix mapping work into an `#[inline(never)]` helper. This keeps the call sites unchanged while separating the mapping work from the inline path.
2026-09-08 15:30:31 +00:00
camc314 1e5d5d7962 perf(linter/eslint/no-unused-vars): skip absent global declaration checks (#26457)
Skip the scope-ancestor walk in `is_in_declare_global` when the file contains no `TSGlobalDeclaration` nodes. Files containing global declarations retain the existing scope checks, using `nodes().kind()` directly when inspecting ambient module scopes.
2026-09-08 15:11:33 +00:00
renovate[bot] 3e5cd72aa5 chore(deps): update dependency vite-plus to v0.3.1 (#26458)
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/) |
|---|---|---|---|---|---|
| [vite-plus](https://viteplus.dev/guide)
([source](https://redirect.github.com/voidzero-dev/vite-plus/tree/HEAD/packages/cli))
| [`0.3.0` →
`0.3.1`](https://renovatebot.com/diffs/npm/vite-plus/0.3.0/0.3.1) |
![age](https://developer.mend.io/api/mc/badges/age/npm/vite-plus/0.3.1?slim=true)
|
![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite-plus/0.3.1?slim=true)
|
![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite-plus/0.3.0/0.3.1?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite-plus/0.3.0/0.3.1?slim=true)
|

---

### Release Notes

<details>
<summary>voidzero-dev/vite-plus (vite-plus)</summary>

###
[`v0.3.1`](https://redirect.github.com/voidzero-dev/vite-plus/releases/tag/v0.3.1):
vite-plus v0.3.1: manage package-manager versions with vp env

[Compare
Source](https://redirect.github.com/voidzero-dev/vite-plus/compare/v0.3.0...v0.3.1)

`vp env` now manages Node.js and package-manager versions together. This
release also fixes TanStack Start routing and stale Vitest aliases.

##### Breaking Changes

##### Package-manager setup

Vite+ replaces Corepack with managed `npm`, `pnpm`, `yarn`, and `bun`
commands. It removes the `corepack` shim and legacy global
package-manager installations
([#&#8203;2391](https://redirect.github.com/voidzero-dev/vite-plus/pull/2391)),
by [@&#8203;liangmiQwQ](https://redirect.github.com/liangmiQwQ).

Replace Corepack setup commands in shell profiles, CI jobs, and
Dockerfiles:

| Previous setup | Replacement |
| ------------------------------ |
------------------------------------------------- |
| `corepack enable` | `vp env setup` |
| `vp install -g pnpm@<version>` | `vp env default pnpm@<version>` |
| `vp install -g yarn@<version>` | `vp env default yarn@<version>` |
| `vp install -g bun@<version>` | `vp env default bun@<version>` |
| `vp install -g corepack` | Use the managed package-manager commands
directly |

Use `vp env pin <manager>@<version>` to set a project version.

##### `vp env` command scope and JSON output

Unscoped `vp env` commands now operate on Node.js and package managers.
Package managers support independent defaults, project pins, session
overrides, and installation commands
([#&#8203;2398](https://redirect.github.com/voidzero-dev/vite-plus/pull/2398)),
by [@&#8203;liangmiQwQ](https://redirect.github.com/liangmiQwQ).

Add `node` to limit an operation to Node.js, for example, `vp env off
node` or `vp env unpin node`. Bare versions, such as `vp env default
22.19.0`, still select Node.js.

Update scripts that read JSON output:

| Command | New output structure |
| ------------------------------------------------- |
------------------------------------ |
| `vp env current --json` | `node` and `package_manager` objects |
| `vp env list --json`, `vp env list-remote --json` | `node` and
`package_managers` groups |

See the [environment guide](https://viteplus.dev/guide/env).

##### `vp pack` migration to `tsdown@0.23`

`vp pack` now uses `tsdown@0.23`, which removes deprecated options and
changes defaults
([#&#8203;2614](https://redirect.github.com/voidzero-dev/vite-plus/pull/2614)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).

1. Run `vp migrate` to update supported static configurations and
package scripts, including projects that already use Vite+.
2. Check migration warnings in `vite.config.*`, `tsdown.config.*`, and
`package.json`.
3. Update dynamic configurations manually. Arrays built with `.map()`
require manual changes, even when migration reports no warning.
4. Run `vp pack` to check the result.

| Previous option | Replacement |
| ------------------------------------------------------------------ |
------------------------------------------------ |
| `bundle: false` | `unbundle: true` |
| `outExtension` | `outExtensions` |
| `publicDir` / `--public-dir` | `copy` / `--copy` |
| `removeNodeProtocol: true` | `nodeProtocol: 'strip'` |
| `injectStyle` | `css.inject` |
| `inlineOnly` / `deps.onlyAllowBundle` | `deps.onlyBundle` |
| `noExternal` | `deps.alwaysBundle` |
| `skipNodeModulesBundle: true` / `deps.skipNodeModulesBundle: true` |
`deps.neverBundle: true` |
| `dts.tsgo: true` / `dts.oxc: true` | `dts.generator: 'tsgo'` /
`dts.generator: 'oxc'` |

Migration preserves the previous defaults for dependency resolution and
[ATTW](https://tsdown.dev/options/lint#attw-are-the-types-wrong).

`tsdown` no longer supports Node.js `25`. Use Node.js `^22.18.0`,
`^24.11.0`, or `>=26.0.0`. The programmatic `build()` API now returns `{
bundles, watch }`.

See the [complete migration
guide](https://redirect.github.com/rolldown/tsdown/releases/tag/v0.23.0)
for declaration and TypeScript module-resolution changes.

##### CLI argument validation

`vp staged`, `vp config`, `vp hooks`, `vp migrate`, and `vp create` now
reject unsupported options and extra positional arguments
([#&#8203;2523](https://redirect.github.com/voidzero-dev/vite-plus/pull/2523)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).

Remove unsupported arguments from scripts. For example, replace `vp
config --hooks-only` with `vp config --no-agent`.

##### Highlights

- Fix TanStack Start HTTP `404` responses caused by separate Vite
runtime copies
([#&#8203;2617](https://redirect.github.com/voidzero-dev/vite-plus/pull/2617)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Reduce the Windows `vp-shim.exe` size from `214 KiB` to `14 KiB`
([#&#8203;2466](https://redirect.github.com/voidzero-dev/vite-plus/pull/2466)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Add `vp check --quiet` to hide lint warning diagnostics while
retaining errors and summary counts
([#&#8203;2593](https://redirect.github.com/voidzero-dev/vite-plus/pull/2593)),
by [@&#8203;RSS1102](https://redirect.github.com/RSS1102).

##### Features

- Add `vp sync-versions --json` so automation can request dependency
alignment plans from manifest snapshots without changing project files
([#&#8203;2600](https://redirect.github.com/voidzero-dev/vite-plus/pull/2600)),
by [@&#8203;afonsojramos](https://redirect.github.com/afonsojramos).
- Make `vp create --git` suggest an initial commit command after Git
initialization
([#&#8203;2581](https://redirect.github.com/voidzero-dev/vite-plus/pull/2581)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Make `vp migrate` replace frozen `voidzero-dev/setup-vp@v1` workflow
references with the supported version pin
([#&#8203;2540](https://redirect.github.com/voidzero-dev/vite-plus/pull/2540)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Upgrade `rolldown` from `1.2.5` to `1.2.7`, `tsdown` from `0.22.14` to
`0.23.0`, and Oxc from `0.146.0` to `0.148.0`. Upgrade `oxlint` from
`1.79.0` to `1.81.0` and `oxfmt` from `0.64.0` to `0.66.0`. These
versions can flag code that passed before. Run `vp fmt` after upgrading
if CI runs `vp check`
([#&#8203;2580](https://redirect.github.com/voidzero-dev/vite-plus/pull/2580),
[#&#8203;2613](https://redirect.github.com/voidzero-dev/vite-plus/pull/2613)),
by
[@&#8203;voidzero-guard](https://redirect.github.com/voidzero-guard)\[bot].

##### Fixes & Enhancements

- Resolve package-manager versions without rewriting `package.json`. Use
`vp env pin` or `vp env unpin` to change project declarations explicitly
([#&#8203;2399](https://redirect.github.com/voidzero-dev/vite-plus/pull/2399)),
by [@&#8203;liangmiQwQ](https://redirect.github.com/liangmiQwQ).
- Let `vp migrate` repair stale `vitest` aliases that previously
prevented the CLI from starting
([#&#8203;2605](https://redirect.github.com/voidzero-dev/vite-plus/pull/2605)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Keep Vite DevTools within the version ranges supported by the bundled
Vite
([#&#8203;2559](https://redirect.github.com/voidzero-dev/vite-plus/pull/2559)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Keep automatic Vitest upgrades on the supported `4.x` major
([#&#8203;2612](https://redirect.github.com/voidzero-dev/vite-plus/pull/2612)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Remove a deprecated `tsdown` option from the prompts package build
([#&#8203;2597](https://redirect.github.com/voidzero-dev/vite-plus/pull/2597)),
by [@&#8203;jong-kyung](https://redirect.github.com/jong-kyung).

##### Refactor

- Use the updated `which` dependency to resolve relative `PATH` entries
([#&#8203;2583](https://redirect.github.com/voidzero-dev/vite-plus/pull/2583)),
by [@&#8203;RSS1102](https://redirect.github.com/RSS1102).
- Remove the unused `async-trait` annotation from `JsRuntimeProvider`
([#&#8203;2538](https://redirect.github.com/voidzero-dev/vite-plus/pull/2538)),
by [@&#8203;jong-kyung](https://redirect.github.com/jong-kyung).

##### Docs

- Add Azure Pipelines setup instructions
([#&#8203;2553](https://redirect.github.com/voidzero-dev/vite-plus/pull/2553)),
by [@&#8203;naokihaba](https://redirect.github.com/naokihaba).
- Correct Zed Oxc formatter settings and include JSX and TSX
([#&#8203;2592](https://redirect.github.com/voidzero-dev/vite-plus/pull/2592)),
by [@&#8203;joschuba](https://redirect.github.com/joschuba).
- Add Wrangler deployment configuration for the documentation site
([#&#8203;2596](https://redirect.github.com/voidzero-dev/vite-plus/pull/2596)),
by [@&#8203;mdong1909](https://redirect.github.com/mdong1909).
- Explain conflicts between pnpm and Vite+ runtime management, including
the `runtimeOnFail` setting
([#&#8203;2620](https://redirect.github.com/voidzero-dev/vite-plus/pull/2620)),
by [@&#8203;liangmiQwQ](https://redirect.github.com/liangmiQwQ).

##### Chore

- Run CLI snapshots without published release packages
([#&#8203;2625](https://redirect.github.com/voidzero-dev/vite-plus/pull/2625)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Update the release-manager skill with package-install checks,
changelog guidance, and announcement handling
([#&#8203;2548](https://redirect.github.com/voidzero-dev/vite-plus/pull/2548)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Wait for npm dependencies to become available before publishing
dependent release packages
([#&#8203;2601](https://redirect.github.com/voidzero-dev/vite-plus/pull/2601)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Remove old Docker preview images
([#&#8203;2539](https://redirect.github.com/voidzero-dev/vite-plus/pull/2539)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Stabilize external-tool snapshots and isolate npm network cases
([#&#8203;2577](https://redirect.github.com/voidzero-dev/vite-plus/pull/2577),
[#&#8203;2604](https://redirect.github.com/voidzero-dev/vite-plus/pull/2604)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Avoid unreliable Fish PPA setup in CI
([#&#8203;2560](https://redirect.github.com/voidzero-dev/vite-plus/pull/2560)),
by [@&#8203;fengmk2](https://redirect.github.com/fengmk2).
- Update the `vinext` fixture to an upstream fix
([#&#8203;2571](https://redirect.github.com/voidzero-dev/vite-plus/pull/2571)),
by [@&#8203;jong-kyung](https://redirect.github.com/jong-kyung).
- Stabilize the pnpm snapshot and Nuxt build in CI
([#&#8203;2591](https://redirect.github.com/voidzero-dev/vite-plus/pull/2591)),
by
[@&#8203;voidzero-guard](https://redirect.github.com/voidzero-guard)\[bot].
- Pin pnpm in project-creation build-approval fixtures
([#&#8203;2616](https://redirect.github.com/voidzero-dev/vite-plus/pull/2616)),
by [@&#8203;liangmiQwQ](https://redirect.github.com/liangmiQwQ).
- Remove unused documentation components, assets, and the typewriter
dependency
([#&#8203;2550](https://redirect.github.com/voidzero-dev/vite-plus/pull/2550),
[#&#8203;2562](https://redirect.github.com/voidzero-dev/vite-plus/pull/2562)),
by [@&#8203;jong-kyung](https://redirect.github.com/jong-kyung).
- Remove duplicate `tempfile` dependencies, an unused runtime helper,
and unused error variants. Update the `unit_bindings` lint name
([#&#8203;2555](https://redirect.github.com/voidzero-dev/vite-plus/pull/2555),
[#&#8203;2558](https://redirect.github.com/voidzero-dev/vite-plus/pull/2558),
[#&#8203;2566](https://redirect.github.com/voidzero-dev/vite-plus/pull/2566),
[#&#8203;2567](https://redirect.github.com/voidzero-dev/vite-plus/pull/2567)),
by [@&#8203;jong-kyung](https://redirect.github.com/jong-kyung).
- Update GitHub Actions dependencies, including `actions/setup-node`
`v7`
([#&#8203;2544](https://redirect.github.com/voidzero-dev/vite-plus/pull/2544),
[#&#8203;2545](https://redirect.github.com/voidzero-dev/vite-plus/pull/2545),
[#&#8203;2582](https://redirect.github.com/voidzero-dev/vite-plus/pull/2582),
[#&#8203;2618](https://redirect.github.com/voidzero-dev/vite-plus/pull/2618)),
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot].
- Update `crate-ci/typos` through `v1.50.1`
([#&#8203;2584](https://redirect.github.com/voidzero-dev/vite-plus/pull/2584),
[#&#8203;2589](https://redirect.github.com/voidzero-dev/vite-plus/pull/2589),
[#&#8203;2609](https://redirect.github.com/voidzero-dev/vite-plus/pull/2609)),
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot].
- Update repository pnpm to `11.24.0`
([#&#8203;2590](https://redirect.github.com/voidzero-dev/vite-plus/pull/2590)),
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot].
- Update `voidzero-dev/setup-vp` to `v1.19.0`
([#&#8203;2619](https://redirect.github.com/voidzero-dev/vite-plus/pull/2619)),
by [@&#8203;renovate](https://redirect.github.com/renovate)\[bot].

##### Bundled Versions

| Tool | Version | Source |
| ----------------- | ---------- |
-------------------------------------------------------------------------------------------------
|
| `vite` | `8.2.2` |
[`de1111a`](https://redirect.github.com/vitejs/vite/commit/de1111ab0be00879b404e7ed3b2a80e264edddc1)
|
| `rolldown` | `1.2.7` |
[`26b4c6e`](https://redirect.github.com/rolldown/rolldown/commit/26b4c6e56c5553d72a910d0f73d60fa331c0ed88)
|
| `tsdown` | `0.23.0` | [npm](https://npmx.dev/package/tsdown/v/0.23.0)
|
| `vitest` | `4.1.11` | [npm](https://npmx.dev/package/vitest/v/4.1.11)
|
| `oxlint` | `1.81.0` | [npm](https://npmx.dev/package/oxlint/v/1.81.0)
|
| `oxlint-tsgolint` | `7.0.2001` |
[npm](https://npmx.dev/package/oxlint-tsgolint/v/7.0.2001) |
| `oxfmt` | `0.66.0` | [npm](https://npmx.dev/package/oxfmt/v/0.66.0) |

##### Upgrade

```bash
vp upgrade
```

##### New Contributors

[@&#8203;afonsojramos](https://redirect.github.com/afonsojramos),
[@&#8203;joschuba](https://redirect.github.com/joschuba)

**Full Changelog**:
<https://github.com/voidzero-dev/vite-plus/compare/v0.3.0...v0.3.1>

##### Published Packages

- `@voidzero-dev/vite-plus-core@0.3.1`
- `vite-plus@0.3.1`

##### Installation

**macOS/Linux:**

```bash
curl -fsSL https://vite.plus | bash
```

**Windows:**

```powershell
irm https://vite.plus/ps1 | iex
```

Or download and run `vp-setup.exe` from the assets below.

**Docker:**

```bash
docker run --rm -it -v "$PWD:/app" -w /app ghcr.io/voidzero-dev/vite-plus:0.3.1 vp build
```

Run any `vp` command without installing it; see the [Docker
guide](https://viteplus.dev/guide/docker) for more.

</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:eyJjcmVhdGVkSW5WZXIiOiI0NC42OS4xIiwidXBkYXRlZEluVmVyIjoiNDQuNjkuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-09-08 15:10:51 +00:00
camc314 403f899aba perf(linter/eslint/no-undef): check globals once per unresolved name (#26456)
Check configured globals once per unresolved name instead of once per reference. Names with only type references skip the global lookup, while undefined value references retain their individual `typeof` and function-scope `arguments` checks.
2026-09-08 15:03:04 +00:00
camc314 118adb0ea2 perf(linter/eslint/no-restricted-imports): avoid redundant import scans (#26455)
Skip the rule when neither paths nor patterns are configured. For side-effect import detection, build a set of import statement spans once instead of scanning every import entry for each request, and return early when the file has no requested modules.
2026-09-08 14:58:24 +00:00
camc314 dbe4fac500 perf(react-compiler): check component parameters before scanning bodies (#26451)
Check component parameter validity before scanning for hooks or JSX. Invalid parameter lists now short-circuit the body scan without changing component classification.
2026-09-08 13:44:15 +00:00
camc314 ab848f2f20 perf(linter/eslint/no-useless-assignment): skip tracking exported symbols (#26449)
Skip exported symbols before collecting their operations and assigning liveness bitset indices. These symbols were already excluded from diagnostics, so tracking them added reference scans and dataflow work without producing reports. Local symbols referenced inside exported declarations and assignments continue to be analyzed independently.
2026-09-08 13:38:08 +00:00
camc314 1b6e4098d8 perf(linter/unicorn/prefer-object-from-entries): avoid allocating configured paths (#26448)
Compare configured function paths directly through their split iterators instead of collecting a temporary vector for each candidate call. The shared matcher accepts iterators while preserving exact segment and length matching; its other caller, `no-array-method-this-argument`, is adapted to the new signature.
2026-09-08 13:32:14 +00:00
camc314 2206875def perf(linter/eslint/new-cap): avoid unnecessary callee name allocations (#26447)
Check the terminal callee name's capitalization before constructing its full property path, so ordinary calls and constructors return early. Borrow terminal names directly from the AST to avoid copying identifiers and computed property names; full paths are still constructed when exception matching requires them.
2026-09-08 13:26:11 +00:00
camc314 53f006e5fb perf(ecmascript): format small integer literals with itoa (#26446)
Format non-negative integers below 1000 directly with `itoa`, avoiding Dragonbox formatting and the intermediate `InlineString` copy. Larger numbers and fractions retain the existing shortest-literal logic.
2026-09-08 13:19:40 +00:00
camc314 8bfb8c0aad perf(codegen): avoid duplicate sourcemap name lookups (#26441)
Use `HashMap::entry` to reuse the lookup when inserting a new source-map name, avoiding the second hash and table search from `get` followed by `insert`. Existing name IDs and insertion order are preserved.
2026-09-08 12:31:30 +00:00
Ari Perkkiö b927e0a01f docs(linter/typescript/await-thenable): add missing lang for markdown doc comment (#26438)
Noticed that examples in
https://oxc.rs/docs/guide/usage/linter/rules/typescript/await-thenable.html#examples
don't have syntax highlighting.

Signed-off-by: Ari Perkkiö <ari.perkkio@gmail.com>
2026-09-08 09:45:26 +00:00
leaysgur a7f02a320c refactor(formatter): share the gap-segment walk and cursor helpers in Comments (#26433)
Pure refactoring;
2026-09-08 06:02:03 +00:00
leaysgur 44694ddc43 refactor(formatter): group Comments methods by cursor-based, position-based, and state (#26432)
Just reordering `impl` methods, and also update comments.
2026-09-08 06:02:02 +00:00
leaysgur 70918a3448 refactor(formatter): make is_cast_target position-based (#26431)
We use `preserve_parens: false`, need to detect typecast `()` from source, always.
2026-09-08 06:02:02 +00:00
leaysgur b26bf56cd5 refactor(formatter): route every assignment RHS shape rule through a cast-aware accessor (#26430)
Follow up on #26429, apply cast-aware behavior to assignment call sites.
2026-09-08 06:02:01 +00:00
leaysgur 33cdc841ac fix(formatter): keep cast-target assignment and commented parameter patterns (#26429)
Fixes #26425, #26426.

- Exclude cast target from never-break check
- Use position based comment check
2026-09-08 06:02:01 +00:00
leaysgur 876fbe30f1 fix(oxfmt): expand Fill parts in tsx-in-vue (#26427)
Fixes #26398, closes #26399.

---

Our Rust printer knows how to expand `Fill` with `Interned`, but Prettier printer does not.
2026-09-08 01:29:38 +00:00
camc314 32d00c55bc fix(codegen): preserve instantiation expression precedence (#26424)
Preserve parentheses around TypeScript instantiation expressions in postfix contexts. Previously, `(f<T>).x` and `(f<T>)[x]` were emitted as `f<T>.x` and `f<T>[x]`, producing invalid syntax or changing how the expression is parsed.

The printer now respects the surrounding precedence while retaining grouping for lower-precedence operands.
2026-09-07 18:20:11 +00:00
camc314 cfa47ab396 fix(parser): allow in expressions in class static blocks (#26423)
Class static blocks inherit the disabled `in` context of a surrounding `for` initializer, causing valid code such as `for (class { static { a in b; } };;);` to report a missing semicolon at `in`. Enable `Context::In` while parsing the static block, with the existing context helper restoring the surrounding flags afterward.
2026-09-07 18:06:57 +00:00
camc314 598618793c fix(packages/codegen): preserve private-in right operand precedence (#26420)
`packages/codegen` drops required parentheses around the right operand of a private-in expression when that operand is another relational expression. This changes which value the private-field check receives and can change observable behavior.

For example, this input throws a `TypeError`:

```js
class C {
  #x;
  test(a, b) {
    return #x in (a instanceof b);
  }
}
new C().test({}, Object);
```

`a instanceof b` evaluates to `true`, but a private-field check requires an object on its right-hand side.

The JavaScript printer previously emitted:

```js
return #x in a instanceof b;
```

Relational operators associate to the left, so that output is parsed as `(#x in a) instanceof b`. The private-field check on `{}` produces `false`, and `false instanceof Object` returns `false` instead of throwing.

The printer now preserves the original grouping:

```js
return #x in (a instanceof b);
```

`printPrivateInExpression` now prints its right operand with `PREC_COMPARE` instead of `PREC_EQUALS`. The expression printers wrap operands whose precedence is equal to or lower than the requested precedence, so the comparison threshold retains parentheses around `<`, `<=`, `>`, `>=`, `instanceof`, and nested private-in expressions. The now-unused `PREC_EQUALS` import is removed.

Equality and lower-precedence operands continue to retain their required grouping. Shift, arithmetic, and exponentiation operands can still omit unnecessary parentheses. The existing `CTX_FORBID_IN` handling remains in place.

This applies to both ordinary and source-map-enabled printer builds and brings the JavaScript implementation in line with the Rust fix in #26411. It addresses grouping of the private-in right operand, separately from the left-operand correction in #26403.
2026-09-07 17:54:59 +00:00
camc314 f8e6c6ccf8 fix(packages/codegen): preserve in restriction through yield arguments (#26421)
`packages/codegen` can turn valid JavaScript into unparseable output when a `yield` expression appears in a classic `for` loop initializer and its argument contains an `in` operator.

For example, this input is valid:

```js
function* g(o) {
  for (yield (1 in o); false;);
}
```

The JavaScript printer previously dropped the required grouping:

```js
function* g(o) {
  for (yield 1 in o; false;);
}
```

An unparenthesized `in` is not allowed at this position in a classic `for` initializer. The same problem affects `yield*`, nested yields, and assignments inside the yield argument.

The printer now preserves the parentheses:

```js
function* g(o) {
  for (yield (1 in o); false;);
}
```

The `for` printer already marks its initializer with `CTX_FORBID_IN`, but `printYieldExpression` discarded that context and printed its argument with `CTX_NONE`. The yield dispatch now passes its incoming context to `printYieldExpression`, which forwards only `CTX_FORBID_IN` to the argument when the yield expression is unwrapped. The argument retains its existing `PREC_YIELD` precedence.

When precedence requires parentheses around the entire yield expression, those parentheses already permit `in` inside. The argument context is cleared in that case, avoiding redundant inner parentheses:

```js
// Input
function* g(o) {
  for ((yield (1 in o)) + 1; false;);
}

// Output
function* g(o) {
  for ((yield 1 in o) + 1; false;);
}
```

Both `yield` and `yield*` use this path. Outside a restricted initializer, ordinary yields continue to omit unnecessary grouping: `yield (1 in o)` prints as `yield 1 in o`.

The correction applies to both ordinary and source-map-enabled builds and brings the JavaScript printer in line with the Rust fix in #26413.
2026-09-07 17:47:59 +00:00
camc314 d61e3bf887 fix(parser): validate TS named tuple rest elements (#26419)
## Problem

Named tuple rest elements bypass the parser's existing checks for optional elements after an array rest and for multiple array rests. For example, both of these declarations currently parse successfully even though TypeScript rejects them:

```ts
type OptionalAfterRest = [...a: string[], b?: number];
type RestAfterRest = [...a: string[], ...b: number[]];
```

The equivalent unnamed forms already produce TS1266 and TS1265, respectively. Mixed named and unnamed array rests have the same gap when either rest is named.

## Cause and change

`parse_tuple_type` inspects `TSRestType.type_annotation` to decide whether an element is an array rest. For a named element, that annotation is a `TSNamedTupleMember`, and the actual type is stored in its `element_type`. Matching directly on the outer annotation therefore skips the array check and fails to track the rest element.

Unwrap the named member with `as_ts_type()` before applying the existing classification. Named and unnamed elements then share the same validation and existing diagnostics:

- An optional element after an array rest reports TS1266.
- A second array rest reports TS1265, including mixed named and unnamed forms.

The diagnostic spans continue to use the complete tuple elements, including their labels. The change borrows the underlying type without changing the AST representation or introducing allocations.

## Preserved behavior

A rest marker alone does not make a spread an unbounded array. Fixed-tuple and generic variadic spreads continue to be accepted, including:

```ts
type FixedBeforeOptional = [...a: [string], b?: number];
type RestBeforeFixed = [...a: string[], ...b: [number]];
type VariadicBeforeOptional<T extends unknown[]> = [...a: T, b?: number];
type RestBeforeVariadic<T extends unknown[]> = [...a: string[], ...b: T];
type MultipleVariadic<T extends unknown[], U extends unknown[]> = [...a: T, ...b: U];
```

This change preserves the existing type-reference classification; it does not add type resolution or change how shadowed `Array` references are handled.
2026-09-07 17:43:20 +00:00