Commit Graph
21189 Commits
Author SHA1 Message Date
leaysgur 7bc0c0469e test(oxfmt): stop counting both-error conformance cases as passed (#27826)
- Exclude Prettier's `_errors_/` and `range/` fixtures from `js-in-vue`
- Rename `issue-19667.ts` to `.tsx` so it parses
- Treat both sides failing to parse as a failure
2026-10-16 12:16:17 +00:00
camc314 03b3f6d8ca refactor(mangler): remove redundant comment (#27828)
Remove a comment that repeats the adjacent filtering and sorting operations in the mangler.
2026-10-16 11:49:18 +00:00
camc314 55a13117d1 refactor(minifier): remove redundant comments (#27829)
Remove four comments that repeat the adjacent operations in the minifier peephole optimizations.
2026-10-16 11:41:41 +00:00
camc314 2537ad44b4 refactor(oxlint): remove redundant comments (#27827)
Remove three comments that restate the adjacent operations in the oxlint CLI and test helper.
2026-10-16 11:18:33 +00:00
camc314 5d877b81e7 perf(diagnostics): speed up zero-context span lookups (#27770)
JSON reporting creates a zero-context span scanner per diagnostic. Its prefix scan walks every newline and updates an empty context queue, even though the existing one-context-line path already counts LF breaks in bulk.

Use bulk LF counting and a reverse newline lookup for zero-context prefixes too. Prefixes containing CR retain the existing path. The regression test compares every byte cut against the generic scanner, including empty input, LF, mixed CR/CRLF and multibyte text.

On VS Code with a fixed cached stream of approximately 276,000 diagnostics, the complete JSON-output command fell from 4.79s to 1.74s on an M2 Max. Two release measurement rounds each used one warm-up and three measured runs: wall time improved 62–64%, frontend instructions fell from roughly 59–60B to 35B, and peak RSS stayed broadly unchanged. Complete diagnostic multisets matched. The baseline strips symbols and the patched build retains them; optimization settings match. These are cached-replay command timings, not isolated rendering-phase timings.
2026-10-16 11:10:18 +00:00
camc314 2947917784 fix(linter/eslint/no-lonely-if): check final else blocks in else-if chains (#27759)
Oxlint skipped the final `else { if (b) {} }` in `if (a) {} else if (d) {} else { if (b) {} }`, which ESLint reports. Follow the chain through alternate branches before applying the existing guard for an enclosing `if` body, preserving dangling-`else` protection.

Addresses report 14 (`eslint/no-lonely-if`) in #27746.
2026-10-16 11:02:19 +00:00
camc314 fc039b55ae fix(linter/eslint/sort-imports): check imports after other statements (#27749)
`sort-imports` stopped at the first non-import statement, so leading variable declarations and interleaved statements hid later sorting violations. Check all top-level imports while preserving ESLint's declaration grouping and member-sort options, with regression and autofix coverage.

Addresses report 7 (`eslint/sort-imports`) in #27746.
2026-10-16 10:58:13 +00:00
camc314 1acba97fd1 fix(linter/unicorn/prefer-at): report slice index reads once (#27762)
`arr.slice(-1)[0]` now reports once, including on the right of assignments. Route slice-index checks through the computed-member visitor and distinguish write targets from destructuring default values; keep parentheses balanced in fixes.

Addresses report 6 (`unicorn/prefer-at`) of #27746. Adds diagnostic and autofix regressions.
2026-10-16 10:52:31 +00:00
Anzal Husain AbidiandCameron Clark 6190e26947 fix(linter/eslint/prefer-arrow-callback): ignore functions used as conditional tests (#27533)
## Why

`oxlint --fix` currently turns valid code into a syntax error here
(oxlint 1.87.0, checked with `node --check`):

```js
foo(function() {} ? a : b);        // -> foo(() => {} ? a : b);        SyntaxError
new Foo(function() {} ? a : b);    // -> new Foo(() => {} ? a : b);    SyntaxError
foo(async function() {} ? a : b);  // -> foo(async () => {} ? a : b);  SyntaxError
```

ESLint had the same bug (eslint/eslint#21368) and fixed it in
eslint/eslint#21373 by not treating a function in the test of a
conditional as a callback. This ports that fix.

Found while running ESLint's upstream test file for this rule through
oxlint.

## Problem

`get_callback_info` kept walking up through a `ConditionalExpression`
even when the function was the conditional's `test`. A function used as
a test is not the callback, the conditional's result is. ESLint treats
these as valid (tests/lib/rules/prefer-arrow-callback.js L52-L59).

Before, oxlint reported `Unexpected function expression` for each of
these:

```js
foo(function() {} ? a : b);
foo(function() { this; }.bind(this) ? a : b);
foo(bar ? function() {} ? a : b : c);
new Foo(function() {} ? a : b);
```

After, none are reported. Functions in the consequent or alternate are
still callbacks, for example `foo(bar ? function() {} : function() {})`
is still reported and fixed.

## Changes

- In the `ConditionalExpression` arm, stop when the node is the `test`.
Only continue for the consequent and alternate.
- Add the eight upstream valid cases (L52-L59) to the pass vector. No
snapshot change, since only pass cases were added.

## Testing

`cargo test -p oxc_linter --lib prefer_arrow_callback`, `cargo fmt`,
`cargo clippy -p oxc_linter --all-targets -- -D warnings` all pass.

---
Written with the help of an agent (Claude Code, claude-opus-5-5
orchestrating claude-sonnet-5-5).

---------

Co-authored-by: Cameron Clark <cameron.clark@hey.com>
2026-10-16 10:51:46 +00:00
camc314 b3cdaafe68 fix(linter/eslint/sort-keys): check computed identifier names (#27748)
Oxlint skipped computed identifiers, accepting `{a: 1, [S]: 3, b: 2}` where ESLint reports an ordering error. Compare their identifier names, including parenthesized keys, while keeping dynamic keys ineligible for automatic fixes.

Addresses report 19 (`eslint/sort-keys`) in #27746.
2026-10-16 10:44:56 +00:00
camc314 170e60814b fix(linter/unicorn/prefer-native-coercion-functions): check object methods and function properties (#27750)
Addresses report 18 (`unicorn/prefer-native-coercion-functions`) in #27746.

Oxlint skipped both `{ m(v) { return String(v); } }` and `{ m: function(v) { return String(v); } }`, which Unicorn reports. Restrict the object-property exclusion to the setter's value function, so ordinary methods, function-valued properties, and functions in computed keys are checked while setters remain excluded.
2026-10-16 10:40:46 +00:00
leaysgur eb8731fea5 test(formatter_tests): count conformance rate per option set (#27825)
- Count `(input, option set)` runs instead of files
- Stop counting unparsable runs as passed
- Count matched runs as `1.0` in the match ratio
2026-10-16 10:17:41 +00:00
leaysgur 8a3a6c8764 docs(oxfmt): update stale notes on the JSDoc string-out channel and fixture origins (#27824) 2026-10-16 10:17:41 +00:00
leaysgur d3ff3f6622 fix(formatter/jsdoc): write descriptions as written to not close the comment (#27823)
For example, `__/` should be kept as-is.

Previously converted to `**/` and it closes the block comment itself, then break the code.
2026-10-16 10:17:40 +00:00
leaysgur c4c17279e6 fix(formatter/sort_imports): keep comments after the last import (#27822)
Fixes idempotency issue.
2026-10-16 10:17:40 +00:00
leaysgur a64677e2a7 fix(formatter): print JSDoc embedded snippets with LF (#27821)
Otherwise, CRLF is appeared in IR, then panics.
2026-10-16 10:17:39 +00:00
leaysgur 2c1cc20fa4 fix(formatter): keep comment only Vue bindings as-is (#27820)
Preserve them as-is, incl. spaces.
2026-10-16 10:17:39 +00:00
leaysgur 1bf236d2be fix(formatter/sort_imports): do not use comments as import source (#27819)
`from /* c */ "z"` was wrongly sorted as module `c`.
2026-10-16 10:17:38 +00:00
leaysgur 52ee29d1be fix(formatter_yaml): never start col-0 line with document marker or BOM (#27818)
- Bump `oxc-yaml-parser` to 0.0.7
  - handles NUL as content, BOM only outside a document, markers only at column 0
- Keep `---`/`...` content on the `---` line, keep `?` on a root key starting with a marker, and indent a flow scalar continuation line starting with a marker
- Add `---` before a document whose first text is U+FEFF
2026-10-16 10:17:38 +00:00
camc314 9261df700b fix(linter/unicorn/prefer-string-raw): check object property values (#27758)
Values such as `{ b: "a\\b" }` were skipped whenever the property key was not a string literal. Only exempt non-computed string-literal keys so property values are reported and fixed consistently with Unicorn.

Addresses report 8 (`unicorn/prefer-string-raw`) in #27746.
2026-10-16 09:19:16 +00:00
camc314 ddea86b023 fix(linter/eslint/prefer-template): report separate nested concatenations (#27764)
Oxlint skipped concatenations nested inside an unrelated `+`, such as `a + (b ? "|" + c : "")` or a concatenation in a callback body. ESLint reports those inner chains independently.

Only group directly connected additions through parentheses, and keep string classification consistent at TypeScript expression boundaries.

Addresses report 10 (`eslint/prefer-template`) in #27746.
2026-10-16 09:14:57 +00:00
renovate[bot] 4770423f7b chore(deps): update dependency vite-plus to v1.3.0 (#27815)
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))
| [`1.2.0` →
`1.3.0`](https://renovatebot.com/diffs/npm/vite-plus/1.2.0/1.3.0) |
![age](https://developer.mend.io/api/mc/badges/age/npm/vite-plus/1.3.0?slim=true)
|
![adoption](https://developer.mend.io/api/mc/badges/adoption/npm/vite-plus/1.3.0?slim=true)
|
![passing](https://developer.mend.io/api/mc/badges/compatibility/npm/vite-plus/1.2.0/1.3.0?slim=true)
|
![confidence](https://developer.mend.io/api/mc/badges/confidence/npm/vite-plus/1.2.0/1.3.0?slim=true)
|

---

### 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:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNjQuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjE2NC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-16 06:17:30 +00:00
leaysgur 81c75e75a6 fix(formatter/css): keep glued css-in-js statement placeholders glued (#27814)
Keep them as-is.

```js
css`${a}${b}`;
css`${a} ${b}`;
```

Also noted DIVERGENCES relates to `!important`.
2026-10-16 06:08:38 +00:00
leaysgur a1ef7f4f9b fix(formatter): keep typecast parens in same-operator binary and arrow chain (#27812)
Saves like `x = a && /** @type {T} */ (b && c);` and `f = (a) => /** @type {T} */ ((b) => c);`.
2026-10-16 05:31:33 +00:00
leaysgur de110ced8b fix(formatter): keep more parens around TSInstantiationExpression (#27811)
Like `(make<T>)<U>();`.
2026-10-16 05:26:31 +00:00
Cam McHenry 5b6ae62ffa refactor(linter): remove unreachable from use-isnan (#27806)
Inlining some of the fix code into the specific branches avoids the need
for an `unreachable!` call because we always know what branch we are in.
2026-10-16 01:25:26 -04:00
Cam McHenry 794af07ddb refactor(linter): remove unreachable from sort-vars (#27805)
Instead of accepting `VariableDeclarator` and looking for the
`BindingIdentifier`, we can accept a `BindingIdentifier` directly and
avoid the need for an `unreachable!` call.
2026-10-16 01:25:25 -04:00
Cam McHenry 8542fe928f refactor(linter): remove unreachable from one-var (#27804)
The expression containing the `unreachable!` call is redundant, we
already check those cases elsewhere. Instead of returning `bool` in
`is_statement_list_parent`, we now return the list of statements (if
any) for the given `AstKind` so we don't need to check the node kind
later.
2026-10-16 01:25:25 -04:00
Cam McHenry cb92c43298 refactor(linter): remove unreachable from no-useless-assignment (#27803)
Instead of passing the node ID around, pass the node directly, avoiding
the need for an unreachable case.
2026-10-16 01:25:24 -04:00
Cam McHenry 7509154fde refactor(linter): remove unreachable from no-magic-numbers (#27802)
Adds a new `NumberLiteral` enum to enumerate all (2) cases that we
realistically want to handle, eliminating the need for a `unreachable!`
call and also eliminating the call to a intended-for-debug-only
`debug_name` function.
2026-10-16 01:25:24 -04:00
Cam McHenry 02676f64c4 refactor(linter): remove unreachable from no-inner-declarations (#27801)
Similar to previous PR, instead of having an `unreachable!` case, we can
pass the keyword length directly where we know which branch we're in.
2026-10-16 01:25:24 -04:00
Cam McHenry 49ae8e9f91 refactor(linter): remove unreachable from no-extra-label (#27800)
Passing the keyword length in as a parameter within the matching
branches ensures we never will hit/need the `unreachable!` case.
2026-10-16 01:25:23 -04:00
Cam McHenry 6b6dc68565 refactor(linter): remove unreachable from no-empty-function (#27799)
Similar to https://github.com/oxc-project/oxc/pull/27794/changes,
initializing the parent ensures we always return.
2026-10-16 01:25:23 -04:00
Cam McHenry a70ba5ec1f refactor(linter): remove unreachable from no-duplicate-imports (#27798)
The `ImportImportName` enum supports the smaller set of cases that we
want to handle, so refactoring to use that eliminates the need for
`unreachable!()`.
2026-10-16 01:25:22 -04:00
Cam McHenry 895f8fe73f refactor(linter): remove unreachable from no-console (#27797)
Using the `MemberExpressionKind` enum, we can ensure we exhaustively
handle all member expression cases instead of relying on `unreachable!`.
2026-10-16 01:25:22 -04:00
renovate[bot] 112a7c8ff4 chore(deps): update dependency rust to v1.99.1 (#27813)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://redirect.github.com/rust-lang/rust) | patch | `1.99.0`
→ `1.99.1` |

---

### Release Notes

<details>
<summary>rust-lang/rust (rust)</summary>

###
[`v1.99.1`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1991-2026-10-15)

[Compare
Source](https://redirect.github.com/rust-lang/rust/compare/1.99.0...1.99.1)

\===========================

<a id="1.99.1"></a>

- [library: fix missing symbol `wcslen` on UEFI and embedded
targets](https://redirect.github.com/rust-lang/rust/issues/163614)
- [rustc: fix miscompilation of FFI `bool` return values on
x86_64](https://redirect.github.com/rust-lang/rust/issues/163911)
- [rust-lld: add the rpath for `libLLVM` on
macOS](https://redirect.github.com/rust-lang/rust/issues/163947)

</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:eyJjcmVhdGVkSW5WZXIiOiI0NC4xNjQuMSIsInVwZGF0ZWRJblZlciI6IjQ0LjE2NC4xIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2026-10-16 05:05:50 +00:00
Cam McHenry ffd02b42cf refactor(linter/eslint/no-case-declarations): use Span::sized (#27796)
Small cleanup to use `Span::sized` instead of manually sized spans.
2026-10-16 00:56:32 -04:00
Cam McHenry 63f5410101 refactor(linter): remove unreachable from no-case-declaration (#27795)
Instead of crashing with `unreachable!`, we can simply continue
execution.
2026-10-16 00:56:32 -04:00
Cam McHenry e05f1ec65e refactor(linter): remove unreachable from id-match (#27794)
Using mutable state with initialization via `parent_node()` guarantees a
node will be returned, so no unreachable is necessary.
2026-10-16 00:56:32 -04:00
Cam McHenry 8ac03b7278 refactor(linter): remove unreachable from func-style (#27793)
The unreachable branch is not needed: we can slightly rearrange the
`match` to avoid the early return.
2026-10-16 00:56:31 -04:00
Cam McHenry 536a6df169 refactor(linter): remove unreachable from for-direction (#27792)
The deleted code is not needed because it can be replaced with a
`GetSpan` trait call to `.span()` instead of this helper.
2026-10-16 00:56:30 -04:00
Cam McHenry 71c43c7874 refactor(linter): remove unreachable from eqeqeq (#27791)
The unreachable case here is redundant, because we already check the
same condition earlier in the lint rule. By rearranging, the branch can
be avoided completely.
2026-10-16 00:56:30 -04:00
Cam McHenry 41e37799b1 refactor(linter): remove unreachable return from array-callback-return (#27790)
Ensure that all cases are handled by adding a new `ReturnKind` enum,
which replaces the multiple independent `bool` states. This way, the
boolean states become interconnected and we can exhaustively handle
cases.
2026-10-16 00:56:29 -04:00
Cam McHenry bae1314054 refactor(linter): remove unreachable from array-callback-return (#27789)
Avoids `unreachable!` by adding a new `CallbackFunction` enum that lets
us exhaustively handle all of the cases we care about.
2026-10-16 00:56:29 -04:00
Cam McHenry 601f95ef5f refactor(linter): remove unreachable from parse_jest_fn_call (#27788)
The `unreachable!` call is not needed: we can handle all cases with a
boolean expression.
2026-10-16 00:56:29 -04:00
Cam McHenry 6ada24826c refactor(linter): remove unreachable from variable_declaration_kind (#27787)
`variable_declaration_kind` implicitly relies on the assumption that
`VariableDeclaration` contains a `VariableDeclarator`. _Probably_ this
will always be true, but it seems good to ensure our code will never
crash from this potentially changing in the future. It only requires
minor changes at each call site, since we change the return type to
`Option`.
2026-10-16 00:56:28 -04:00
Cam McHenry 7a9a77cea7 refactor(linter): remove unreachable/unwrap from parsing rule value (#27786)
No need for unreachable/unwrap here, because we can destructure the vec
instead and get type-system guarantees that there's at least 1 element.
2026-10-16 00:56:28 -04:00
leaysgur 8b02e90cf7 fix(formatter_json): reject invalid JSON instead of dropping them (#27785)
Found by Prettier's `_errors_` tests.
2026-10-16 04:21:11 +00:00
leaysgur 814eaeb2c6 fix(formatter_toml): bump oxc-toml to keep commented inline table (#27782)
https://github.com/oxc-project/oxc-toml/releases/tag/v0.15.1
2026-10-16 04:21:11 +00:00
leaysgur 6fe4c1b911 fix(formatter): treat lone CR in JSX text and argument blank lines (#27780)
Also disables BOM and shebang variants.
2026-10-16 04:04:07 +00:00