Commit Graph

1563 Commits

Author SHA1 Message Date
camc314 d7713ad4cb fix(parser): classify Unicode line breaks in block comments (#26536)
Block comments containing U+2028 or U+2029 were marked `SingleLineBlock` unless they also contained LF or CR. Switch to the multiline-comment scanner after either Unicode separator so downstream consumers receive the correct comment kind.

This prevents the formatter from dropping parentheses around a return argument with such a leading comment, which could change the returned value to `undefined`.
2026-09-10 15:28:49 +00:00
camc314 b32d25d418 fix(parser): reject escaped import-phase keywords (#26534)
The parser consumes `source`, `defer`, and sometimes `from` as binding identifiers before resolving their role in an import declaration. Validate escapes once they are known to be keywords, so declarations such as `import s\u006furce wasm from "m"` and `import source fr\u006fm "m"` report an error.

Escaped binding names remain valid, including `import s\u006furce from "m"` and `import source fr\u006fm from "m"`.
2026-09-10 14:55:08 +00:00
camc314 47b83115f0 fix(parser): recognize contextual binding names in type lookaheads (#26532)
Recognize `await` and `yield` as binding names when looking ahead for TypeScript function types and index signatures. This allows valid syntax such as `(await: number) => void` and `interface I { [await: string]: unknown }`, while leaving contextual legality to actual parsing.
2026-09-10 14:05:25 +00:00
camc314 d6b6705f8f fix(parser): require arrow separator in TypeScript function types (#26529)
Require `=>` when parsing TypeScript function and constructor types, while retaining `:` for function, method, and arrow return annotations. Previously, any token could be consumed as the separator, accepting invalid types such as `type F = (): number` and `type F = new () + number`.

This also prevents a valid conditional expression from being silently grouped into the wrong arrows:

```ts
const a = true, b = 1, c = 2;
const f = a ? (b) : (): any => b ? c : (x = 1): any => x;
console.log(typeof f);
```

The transformed program now prints `number`; previously it printed `function`.
2026-09-10 13:05:18 +00:00
camc314 e98beef227 fix(parser): disambiguate await using in for initializers (#26527)
Allow classic `for` initializers such as `for (await using;;)` when `using` is an ordinary identifier. Reuse the statement parser’s `await using` lookahead so resource declarations require a following binding identifier, preserving the existing line-break restrictions.
2026-09-10 10:59:58 +00:00
camc314 92afee6734 fix(parser): allow parenthesized JSX comma expressions with preserve_parens=false (#26524)
Allow parenthesized comma expressions such as `<A>{(a, b)}</A>` and `<A x={(a, b)} />` when `preserve_parens` is false.

Compare the sequence expression's start with the first token's start to retain the grouping distinction after parentheses are omitted from the AST. Ungrouped comma expressions such as `{a, b}` and `{(a, b), c}` remain invalid.
2026-09-10 10:30:38 +00:00
camc314 31508b1be5 fix(parser): reject return types on constructor overloads (#26523)
Constructor overloads and ambient signatures previously bypassed the return type check because it required a body. Reject their return annotations with TS1093, matching constructor implementations.

Highlight only the return type itself, excluding the colon and preceding whitespace.
2026-09-10 10:10:39 +00:00
camc314 a091fc4b42 fix(parser): validate await context for await using declarations (#26495)
Reject `await using` in non-async functions and ordinary generators, including `for` and `for...of` loop heads. Treat top-level `await using` as module syntax when the source type is unambiguous.
2026-09-09 15:21:18 +00:00
camc314 5501e86429 fix(parser): disallow in expressions in using for-loop initializers (#26490)
Reject invalid initializers such as `for (using x = a in b;;);` by parsing `using` and `await using` declarations with `Context::In` disabled, matching ordinary for-loop declarations. Restore the outer context afterward so parenthesized `in` expressions and the remaining loop expressions keep their existing behavior.
2026-09-09 14:03:17 +00: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 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
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 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
camc314 10521b288f fix(parser): allow escaped type default import bindings (#26409)
TypeScript allows a default import binding named `type` to contain Unicode escapes. Oxc currently reports `Keywords cannot contain escape characters` for these valid imports:

```ts
import t\u0079pe from "m";
import t\u0079pe, { x } from "m";
import t\u0079pe, * as ns from "m";
```

In each example, `t\u0079pe` is an identifier whose decoded name is `type`, and the declaration is a value import.

The parser initially recognizes the decoded `type` token before it has enough context to distinguish a default binding from a type-only import modifier. The escape check ran at that point, so it rejected the binding even when the following tokens established that this was a value import.

Move the escape check into the two branches that interpret `type` as a modifier: before a named or namespace import, and before another binding identifier after ruling out `import type from "m"`. The latter check also runs before the early return for a type-only import-equals declaration.

Escaped modifiers remain invalid, including these forms:

```ts
import t\u0079pe Foo = require("m");
import t\u0079pe { x } from "m";
import t\u0079pe * as ns from "m";
import { t\u0079pe Bar } from "m";
```

The change is limited to when the declaration-level escape diagnostic is emitted; import classification and specifier parsing retain their existing behavior.
2026-09-07 16:03:31 +00:00
camc314 72cb5e3539 fix(parser): reject rest parameters in getters (#26400)
## Summary

Getter accessors must have no formal parameters, but Oxc currently accepts a getter whose only parameter is a rest parameter. This affects class and object getters, as well as getter signatures in TypeScript interfaces and type literals.

```ts
class C { get x(...args) {} }
({ get x(...args) {} });
interface I { get x(...args: any[]): string }
type T = { get x(...args: any[]): string };
```

Each declaration above previously parsed without a diagnostic. It now reports the existing error: `A 'get' accessor must not have any formal parameters.`

## Cause and correction

`FormalParameters` stores ordinary parameters in `items` and the rest parameter separately in `rest`. Both getter checks inspected only whether `items` was empty, so a rest-only parameter list looked like a zero-parameter list.

Use `parameters_count() != 0` in both checks so the count includes the rest parameter. The shared `check_getter` path covers class and object getters; `parse_getter_setter_signature_member` covers interface and type-literal getter signatures.

The diagnostic still points at the full parameter list. Zero-parameter getters remain valid, ordinary getter parameters retain their existing diagnostic, and class/object accessors with type parameters retain the current type-parameter diagnostic precedence. Setter validation is unchanged.
2026-09-07 15:34:10 +00:00
camc314 4e76602fdd fix(parser): allow in in arrow block bodies within for initializers (#26395)
## Summary

Allow the `in` operator inside an arrow function’s block body when the arrow appears in a `for` initializer:

```js
for (() => { a in b; };;);
```

This is valid JavaScript, but the parser previously reported a missing semicolon at `in`. The block now parses successfully, including async arrows and arrows with a single unparenthesized parameter.

## Cause and fix

A `for` initializer disables `Context::In` so that an unparenthesized `in` can delimit a `for…in` statement. Arrow block bodies inherited that disabled context through `parse_arrow_function_expression_body`, which called `parse_function_body` directly.

The block-body branch now calls `parse_function_body` through `context_add(Context::In, ...)`. This enables `in` throughout the function body and restores the enclosing context afterward. It also permits nested concise arrows inside that block to use `in`.

The change is confined to block bodies because concise expression bodies inherit the surrounding grammar’s `In` parameter. For example, this remains invalid:

```js
for (var f = () => a in b;;);
```

Restoring the enclosing context also keeps this invalid, rather than accidentally treating `a in b` as a regular initializer expression after parsing the first arrow:

```js
for (var f = () => {}, value = a in b;;);
```
2026-09-07 15:07:31 +00:00
camc314 b20fc1950c fix(parser): reject partially parenthesized mixed coalesce expressions (#26394)
The parser currently accepts mixed nullish and logical expressions when parentheses cover only the first operand of the logical expression:

```js
(a) || b ?? c;
a ?? (b) || c;
(a) && b ?? c;
a ?? (b) && c;
```

These expressions require a syntax error because `??` cannot be mixed directly with `||` or `&&`. Parentheses around `a` or `b` do not group the complete logical expression. This change reports the existing mixed-coalesce diagnostic for all four forms.

Fully grouped operands remain valid:

```js
(a || b) ?? c;
a ?? (b || c);
(a && b) ?? c;
a ?? (b && c);
```

### Why the existing check misses these expressions

`parse_binary_expression_rest` used `lhs_parenthesized` and `rhs_parenthesized` flags captured before parsing an operand. Those flags describe whether the initial token is `(`, but the parser can subsequently accumulate a larger logical expression outside those parentheses. Applying the initial flag to that complete expression incorrectly suppresses the diagnostic.

### Complete-operand checks

Check both operands independently for an `And` or `Or` logical expression whose span starts at the operand's starting position. A logical expression accumulated outside initial parentheses starts at that position and must be rejected. Checking both operands also prevents a grouped right operand from hiding an invalid left operand.

This works with either `preserve_parens` setting. When parentheses are preserved, a fully grouped operand is a `ParenthesizedExpression`. When they are omitted, its inner logical expression retains a span beginning after the opening `(`, so its start differs from the operand start and it remains allowed. For `(a) || b`, the complete logical expression instead starts at the opening `(` and is correctly rejected.
2026-09-07 14:34:52 +00:00
oxc-guard 60fa13878c release(crates): oxc v0.149.0 (#26397)
### 💥 BREAKING CHANGES

- 66744f0 parser: [**BREAKING**] Rename `panicked` to `fatal_error` in `ParserReturn` (#26382) (overlookmotel)
- 2c9a947 parser: [**BREAKING**] Reduce `MAX_LEN` to 256 bytes below `u32::MAX` (#26352) (overlookmotel)

### 🚀 Features

- 32bdc5b allocator: Construct `ArenaHashSet` with any `Default` hasher (#26372) (Dunqing)
- a17de58 minifier: Process of return/throw in non last position and fix async * inlining (#26214) (Armano)
- bfb4c57 parser: Distinguish unapplied no-side-effects comments (#26120) (碳苯 Carbon)
- 1d9b9d3 ast: Add `GetNodeId` trait (#26145) (camc314)

### 🐛 Bug Fixes

- b156333 codegen: Order accessibility before abstract on accessors (#26392) (camc314)
- 116c8b8 transformer/class-properties: Keep private methods in class-expression scope (#26308) (Changsu Seong)
- 1400a0f parser: Require a string source after `export ... from` (#26389) (camc314)
- 2da73b7 codegen: Print matching quoted import names as identifiers (#26386) (camc314)
- 0a81d29 codegen: Preserve private-in left operand precedence (#26383) (camc314)
- 9a02337 parser: Correctly round large nondecimal literals (#26379) (camc314)
- 3d95477 transformer: Gate async-only rewrites by owning transform (#26326) (Dunqing)
- f45a9ee transformer: Limit arguments capture to lowered async functions (#26317) (Dunqing)
- 789969f transformer: Gate this capture by owning async transform (#26227) (Dunqing)
- affeb14 minifier: Mangle class private members in Node API (#26118) (碳苯 Carbon)
- 8b35abd semantic: Detect duplicate private class elements (#26361) (camc314)
- 457ed57 semantic: Reject await and yield in rest parameter defaults (#26359) (camc314)
- 4b89c7b semantic: Reject jumps across arrow functions (#26357) (camc314)
- c966aca parser: Do not omit `<` token opening type argument list (#26328) (overlookmotel)
- f07dca5 ast_visit: Add the trimmed prefix length to translation table offsets (#26173) (Bharadwaj Pendyala)
- 3ab9bd1 parser: Do not re-lex template substitution tail after fatal error (#26230) (overlookmotel)
- 07851b9 parser: Fix debug assert failure when lexer error with tokens enabled (#26229) (overlookmotel)
- 00dea7a allocator: Gate `Allocator::data_end_ptr` behind fixed_size feature (#26248) (camc314)
- 853ffab ecmascript: Avoid `charAt` panic on 32-bit (#26244) (camc314)
- 34feccb runtime: Remove stale regenerator exports (#26243) (camc314)

### ⚡ Performance

- 34a242e minifier: Use `Ident` for property mangler (#26334) (sapphi-red)
- 5303f5c minifier: Unify merging of last expression into target sequence (#26264) (Armano)
- 2ca7d29 minifier: Consume nodes in minimize_statements in reverse order (#26258) (Armano)
- d2354b4 mangler: Use `Ident` for variable names to keep (#26333) (sapphi-red)
- 5b3e335 minifier: Use `Ident` instead of `Str` in `KeepVar` (#26332) (sapphi-red)
- 51366fb minifier: Use `IdentHashSet` in `PrivateMemberUsageStack` (#26331) (sapphi-red)
- d19c42a minifier: Merge nested if stmt in place instead of creating dummies (#26351) (Armano)
- 356def6 parser: Shrink annotation comment ranges (#26356) (overlookmotel)
- a5be474 parser: Shave instruction off `parse_jsx_element_name` (#26355) (overlookmotel)
- 9780663 parser: Remove fatal error guard from `parse_jsx_element_name` (#26354) (overlookmotel)
- 766e12f parser: Remove `token` field from `LexerCheckpoint` (#26350) (overlookmotel)

### 📚 Documentation

- d4b4e61 transformer: Document ES2015 target floor (#26378) (Dunqing)
- 67dd054 ast_visit: Correct out-of-date comments on `Utf8ToUtf16` converter (#26285) (overlookmotel)
- a8ed2a7 minifier: Fix stale validation instructions (#26251) (camc314)
2026-09-07 14:29:34 +00:00
camc314 1400a0f8be fix(parser): require a string source after export ... from (#26389)
Named exports must have a string literal module source once `from` is present. The parser previously combined consuming `from` with checking whether the next token was a literal:

```rust
if self.eat(Kind::From) && self.cur_kind().is_literal()
```

When the next token was not a literal, `from` had already been consumed, but parsing fell back to a local export. This incorrectly accepted `export {} from;`, `export {} from` at EOF, and this input:

```js
export {} from
foo();
```

In the last case, the newline allowed automatic semicolon insertion, so the parser accepted a local empty export followed by `foo()` despite the incomplete `from` clause.

Remove the literal-kind guard so consuming `from` always leads to `parse_literal_string()`. That helper already requires a string literal and handles malformed input through the existing parser diagnostics. A missing source now produces a syntax error instead of becoming a local export, while unterminated strings and comments retain the standard lexer diagnostics.

Valid local exports such as `export { foo };` and re-exports such as `export { foo } from "./module.js";` keep their existing behavior, including a module source placed on the next line.
2026-09-07 12:41:32 +00:00
overlookmotel 66744f0eb9 feat(parser)!: rename panicked to fatal_error in ParserReturn (#26382)
`ParserReturn` contains a property `panicked`.

The name `panicked` is misleading. The parser did _not_ panic. When `true`, it means that the parser encountered a fatal error and is unable to parse the source, because it contains an unrecoverable syntax error.

Rename this property to `fatal_error`, to better describe what it means.

This is a breaking change, but one that's trivial to fix in downstream code - the property doesn't change its meaning or behavior, just its name.

All the changes in this PR in other crates are just reacting to this change and making everywhere use the term "fatal error" instead of "panicked", so the codebase is consistent.
2026-09-07 09:41:52 +00:00
camc314 9a023379c6 fix(parser): correctly round large nondecimal literals (#26379)
Large hexadecimal, binary, and octal literals can round incorrectly when their digits are accumulated with repeated `f64::mul_add` calls. For example, `0x10000000000000801` currently becomes `2^64` instead of the correctly rounded `2^64 + 4096`.

Preserve the leading significant bits and a sticky bit in the nondecimal slow paths, then round once and scale by a power of two. This also covers numeric separators and legacy octal literals, without allocating or changing the existing integer fast paths.
2026-09-07 09:06:48 +00:00
overlookmotel 356def6598 perf(parser): shrink annotation comment ranges (#26356)
`TriviaBuilder::pure_comments` and `no_side_effects_comments` are index ranges into `comments`.

Previously they were stored as `Option<(usize, usize)>` (24 bytes). Instead, store them as `Option<(u32, NonZeroU32)>` (8 bytes, due to `NonZeroU32`'s niche).

`end` is always at least `start + 1`, so it cannot be 0. Comment count cannot exceed `u32::MAX` because of the `MAX_LEN` check in `Source::new`.

`LexerCheckpoint` contains both ranges, so this change shrinks it by 32 bytes.
2026-09-05 19:15:11 +00:00
overlookmotel a5be474fcf perf(parser): shave instruction off parse_jsx_element_name (#26355)
Micro-optimization to `parse_jsx_element_name`.

`parse_jsx_element_name` inspects the first byte of the identifier name to determine if it should be treated as a reference (`<Foo>` vs `<div>`).

`parse_jsx_identifier` already ensured the identifier is valid, so that first byte can only be one of `[A-Za-z$_]` or the identifier starts with a non-ASCII character. Utilize this constraint to make the "is this a reference" check cheaper.

The new version compiles down to a single `cmp` instruction, shaving off one instruction from the previous version.

It's only 1 instruction, but why not?
2026-09-05 19:15:10 +00:00
overlookmotel 9780663c17 perf(parser): remove fatal error guard from parse_jsx_element_name (#26354)
Small perf optimization to parser.

Remove the `if self.fatal_error.is_some()` branch from `parse_jsx_element_name`.

The guard existed so that code below it doesn't try to read the first byte of the dummy identifier's empty name after `parse_jsx_identifier` fails. Instead, make the error path return `contains_dash = true`, which skips reading the name in `parse_jsx_element_name`.

In `parse_jsx_member_expression`, a dash is already treated as an error, and its `fatal_error` call is a no-op because a fatal error has already been recorded. The other callers ignore the flag.

This removes a check, but main motivation is preparation for larger changes to how fatal errors are handled in further PRs to follow.
2026-09-05 19:15:10 +00:00
overlookmotel 2c9a947363 feat(parser)!: reduce MAX_LEN to 256 bytes below u32::MAX (#26352)
Technically a breaking change, but one that's extremely unlikely to affect any real-world applications.

On 64-bit systems, the maximum source text length was exactly `u32::MAX`.

Lower it by 256 bytes, for 2 reasons:

1. `oxc_lexer` will require source text to be followed by 64 bytes of padding. Reducing max source length ensures _padded_ length can always fit in a `u32`.
2. Counts of tokens, comments and errors are all bounded by source length plus a small constant. By reducing max source length, these can all be stored as `u32`s without any possibility of overflow.

`oxc_lexer` only needs 64 bytes of padding. Have gone with 256 to leave headroom in case later redesigns require more than 64. This avoids another breaking change later. We can always switch to 64 later on if we want, and this later relaxation would not be a breaking change.

All the changes to other crates in this PR are just updating comments which talk about max source length.
2026-09-05 15:33:52 +00:00
overlookmotel 766e12f420 perf(parser): remove token field from LexerCheckpoint (#26350)
Small perf optimization to parser.

`Lexer::token` is the token currently being built. Every method which produces a token ends in `finish_next_inner` or `finish_re_lex`, and both reset it to `Token::default()`. So between lexer calls it is always `Token::default()`, so there is no point in saving and restoring it - it's always a no-op.

Remove the `token` field from `LexerCheckpoint`, which reduces its size by 16 bytes.

Add a debug asserts in `checkpoint` and `checkpoint_with_error_recovery` checking this invariant.
2026-09-05 15:33:51 +00:00
overlookmotel b285987970 refactor(parser): remove unused Clone derives from checkpoint types (#26349)
Pure refactor.

`ParserCheckpoint`, `LexerCheckpoint` and `ErrorSnapshot` are never cloned, so remove `#[derive(Clone)]` from them.
2026-09-05 15:33:51 +00:00
overlookmotel 81bd50a675 refactor(parser): rename ParserCheckpoint::prev_span_end to prev_token_end (#26348)
Pure refactor.

Rename the field of `ParserCheckpoint` to match the `ParserImpl` field that it saves and restores.
2026-09-05 15:33:51 +00:00
overlookmotel c966acaac5 fix(parser): do not omit < token opening type argument list (#26328)
Fix tokens produced when `<<` opens a type argument list. e.g.:

```typescript
type Bar = ReturnType<<T>(x: T) => number>;
```

Previously only 1 `<` token was produced between `ReturnType` and `T`. This PR corrects that so 2 `<` tokens are produced.

TS-ESLint get this wrong too - hence why this wasn't noticed before, as our conformance tests compare to TS-ESLint.

PR submitted to fix TS-ESLint: https://github.com/typescript-eslint/typescript-eslint/pull/12821

In meantime, this PR skips the erroneously failing ESTree tokens conformance tests. We can can re-enable those tests once the fix lands in TS-ESLint.
2026-09-04 12:08:49 +00:00
camc314 f6b75b4a6b test(parser): group annotation application cases (#26294)
## Summary

- group independent `PURE` and `NO_SIDE_EFFECTS` application checks
- clarify test names for unapplied annotation cases
2026-09-03 14:50:56 +00:00
碳苯 Carbon bfb4c57a5d feat(parser): distinguish unapplied no-side-effects comments (#26120)
## Summary 

Fixes #26088

`NO_SIDE_EFFECTS` can either be applied to a function:

```rs
/* #__NO_SIDE_EFFECTS__ */ function foo() {}
```

Or be meaningless for its position, since it only works on function
declaration:
```rs
/* #__NO_SIDE_EFFECTS__ */ value;
```

But oxc could not distinguish these two cases. 

This PR adds `CommentContent::NoSideEffectsNotApplied`, mirroring the
existing `PureNotApplied`.

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-09-03 11:14:24 +01:00
overlookmotel 3ab9bd122c fix(parser): do not re-lex template substitution tail after fatal error (#26230)
When the parser records a fatal error it fast-forwards the lexer to end of file. `re_lex_template_substitution_tail` did not check for that, so an incomplete template substitution would still re-lex the `}` and derive the token's start from a cursor which had already jumped to the end.

With tokens enabled, that fails the debug assertion in `finish_next_inner`, because the token being replaced is no longer the one on top of the collected token stream. Release builds silently overwrite an unrelated token instead. Tokens are only collected for Oxlint's JS plugins, which bail out if any parsing error, which is why this hadn't been noticed before.

Fix by adding the same `fatal_error` guard, added to other re-lex methods in #11023.

This does make a difference to diagnostics output for invalid code matching this pattern. TypeScript snapshot loses an "Unterminated string" diagnostic on 2 fixtures. Those errors came from the bogus re-lex reading past end of file. Both these fixtures already have an "Unexpected token" error. The additional "Unterminated string" errors were incorrect, and this fix has the side effect of removing them.
2026-09-02 21:41:11 +00:00
overlookmotel 07851b9c5d fix(parser): fix debug assert failure when lexer error with tokens enabled (#26229)
`Lexer::finalize_tokens` discards the last collected token - the `Eof` that terminates every token stream - and debug asserted that it was `Eof`.

Turns out that assumption does not always hold. Where the lexer cannot lex any further it emits `Kind::Undetermined`, and no `Eof` ever follows, so the last token is `Undetermined` and the debug assertion fails. This can be triggered by an unterminated string, for example:

```js
foo();
'unterminated
```

Like `Eof`, `Undetermined` is not a "real" token, so either way it's fine to remove it from the token stream. The fix is just to relax the debug assertion to accept either.

Release behaviour is unchanged - it was only a debug assert. Only came across this while running the conformance tests which compare current lexer to the new one (`oxc_lexer`).
2026-09-02 21:41:10 +00:00
oxc-guard 894c8f9cd8 release(crates): oxc v0.148.0 (#26198)
### 💥 BREAKING CHANGES

- a31567a allocator: [**BREAKING**] Make `Allocator::cursor_ptr` and `data_end_ptr` private (#26081) (overlookmotel)

### 🚀 Features

- 784e9fa minifier: Invert `!0` and `!1` in place for boolean context to `1` and `0` (#26050) (Armano)
- 1e902cc minifier: Expand fold leading assignments into the var decl (#26142) (Armano)
- 3ed4f6a minifier: Expand de morgan's optimization to allow move of `!` (#25930) (Armano)
- 5672585 parser: Attach all comments to nodes (#25944) (camc314)

### 🐛 Bug Fixes

- 4adfb4c semantic: Validate chained continue labels (#26157) (camc314)
- b874f48 ecmascript: `Math.round` only exact half ties (#26150) (camc314)
- a625378 minifier: Coerce omitted `indexOf` search argument (#26149) (camc314)
- dc7398b ecmascript: Trim trailing whitespace in string to number (#26148) (camc314)
- 243b685 transformer/object-rest: Lower multiple declarators correctly (#26147) (camc314)
- dc09a3a parser: Avoid panic on escaped string export names (#26146) (camc314)
- e412cf2 linter: Clamp invalid JS plugin locations (#26144) (camc314)
- c3dedc9 semantic: Skip function body bindings in parameters (#26099) (Dunqing)
- e74de61 transform-react: Match Babel diagnostic reporting (#26128) (Boshen)
- d5163d0 parser: Correctly classify unapplied pure annotations (#26084) (camc314)
- 8531b9b linter/plugins: Alter method for obtaining mutable `Program` when sending AST to JS plugins (#26077) (overlookmotel)
- 9b51658 regular_expression: Allow oversized decimal escape for Annex B (#26070) (leaysgur)
- c8de4df regular_expression: Reject oversized backreferences (#26055) (camc314)

### ⚡ Performance

- ac4785a diagnostics: Use fixed ANSI styles (#26130) (Boshen)
- 07a0793 packages/codegen: Flatten output in chunks (#26109) (overlookmotel)
- 487427a packages/codegen: Faster string flattening (#26108) (overlookmotel)
- 7785583 packages/codegen: Ensure indent strings are flattened (#26107) (overlookmotel)
- 0dd4db3 packages/codegen: Store mapping positions in an `Int32Array` (#26085) (overlookmotel)
2026-09-01 08:15:07 +00:00
camc314 dc09a3aa9d fix(parser): avoid panic on escaped string export names (#26146)
## Summary

Fix a parser panic when a string-named export decodes to a literal `\u` sequence.

Lone-surrogate validation now uses the metadata captured by the lexer instead of rescanning decoded string contents. This also prevents false diagnostics for names such as `"\\uD800"`.

## Before:

```

thread 'main' (10990283) panicked at crates/oxc_ast/src/ast_impl/literal.rs:89:42:
end byte index 4 is out of bounds for string of length 0
stack backtrace:
   0: __rustc::rust_begin_unwind
   1: core::panicking::panic_fmt
   2: core::str::slice_error_fail_rt
   3: core::str::slice_error_fail
   4: <core::ops::range::RangeTo<usize> as core::slice::index::SliceIndex<str>>::index
   5: <str as core::ops::index::Index<core::ops::range::RangeTo<usize>>>::index
   6: <oxc_ast::ast::literal::StringLiteral>::is_string_well_formed_unicode
   7: <oxc_parser::ParserImpl<oxc_parser::config::NoTokensParserConfig>>::parse_module_export_name
```
2026-08-28 13:37:48 +00:00
camc314 d5163d0faa fix(parser): correctly classify unapplied pure annotations (#26084)
Mark all `#__PURE__` annotations not directly applied to a `NewExpression` or CallExpression` as `PureNotApplied`.

This changes the approach by letting pure annotations start of their life as `CommentContent::PureNotApplied`, and only changing to `CommentContent::Pure` once they have successfully been applied to a node.

This aligns the behaviour with Rollup.

Rollup Playground:

https://rollupjs.org/repl/?version=4.63.0&shareable=eyJleGFtcGxlIjpudWxsLCJtb2R1bGVzIjpbeyJjb2RlIjoidmFyIGZvbyAvKiAjX19QVVJFX18gKi8gPSBwdXJlT3BlcmF0aW9uKCk7XG5mb28gLyogI19fUFVSRV9fICovID0gcHVyZU9wZXJhdGlvbigpO1xuZm9vIC8qICNfX1BVUkVfXyAqLyArIHB1cmVPcGVyYXRpb24oKTtcbmZvbyAvKiAjX19QVVJFX18gKi8gJiYgcHVyZU9wZXJhdGlvbigpOyIsImlzRW50cnkiOnRydWUsIm5hbWUiOiJtYWluLmpzIn1dLCJvcHRpb25zIjp7fX0=

Rolldown Playground: (only the 1st pure comment is marked as not applied).

https://repl.rolldown.rs/#eNqlkU1LxDAQhv/KEGG/LO294kk8K4K3QEnbyW60nYR0uu5S+t9NUlwRPQgLgczHOy/zMJPQopyEoRZP+dsQYxLld56JJqRH5UFbC8UObqrq+fXlsapgV8A9uNHjk0Ov2FjabO+kl3Sd8vbfytXqlzTsi6JkP+KcCW+7rrUflDeWtNnnfMH7o7OAmt5ZzzBBi9oQPqQ2zKC97WH9NbaWJAlPSRqEauzSfxnYTJIADLmRS1gs8x5Z5amUQVEAHxC06XCAATtsGFuoz6laj8yWIDxUzQFY1dEsjFgXIYeY2ZGT9wS9IaPPJURkmCXNW0kisDvVvKs9hhPaALxQ/6gtvGlRKVp0GC5OjcFBiuAbnaJRcDoGWacYBxbzJ8uvunY=

fixes https://github.com/oxc-project/oxc/issues/23669
closes https://github.com/oxc-project/oxc/pull/24161
2026-08-26 10:33:48 +00:00
camc314 5672585a34 feat(parser): attach all comments to nodes (#25944)
## Summary

Comments are now attached to their adjacent tokens using source boundaries.

A leading comment belongs to the token that follows it:

```js
/* leading */ value
              ^ attached_to
```

A trailing comment belongs to the token that precedes it:

```js
value /* trailing */
     ^ attached_to
```

`Comment::attached_to` now consistently represents either:

- the start of the following token for leading comments;
- the end of the preceding token for trailing comments.
2026-08-25 09:38:36 +00:00
oxc-guard 4e258430cd release(crates): oxc v0.147.0 (#26046)
### 🚀 Features

- b6e9e5e minifier: Fold switch stmt whose parent is not block stmt (#25403) (Armano)

### 🐛 Bug Fixes

- 8a9bdbd estree: Include decorators in `FormalParameterRest ` spans (#26021) (camc314)
- 6f0c7cf minifier: Avoid merging `if` to `for` in sloppy mode when containing function declaration (#25638) (sapphi-red)
- 2cde1f6 rust: Address nightly deprecations (#25998) (Boshen)
- 6c5ad1b codegen: Only add mapping names for `PrivateIdentifier`s which have changed (#25958) (overlookmotel)
- 2dad1e0 parser: Track irregular line terminators in trivia (#25947) (camc314)
- 58ba651 minifier: Avoid merging `if` to `for` when the body contains a function declaration (#25637) (sapphi-red)
- a185ac3 codegen: Print `#` before private identifier in TS signature key (#25938) (overlookmotel)
- af82a07 minifier: Keep unary `+` when the other operand has side effects (#25645) (Kotaro Chikuba)

### ⚡ Performance

- 53f6270 packages/codegen: Eagerly initialize `mapNames` (#25979) (overlookmotel)
- 5b43c60 packages/codegen: Split recording mappings into multiple functions (#25978) (overlookmotel)
- cc947b5 packages/codegen: Reduce property lookups (#25977) (overlookmotel)
- c22a9cc packages/codegen: Combine condition checks (#25976) (overlookmotel)
- 215a6a5 packages/codegen: Add functions for writing/marking unnamed mappings (#25975) (overlookmotel)
- fe444cc codegen: Avoid allocations for single comment anchors (#25598) (camc314)
- a0aee81 minifier: Do not rebuild expression when substituting void to null (#25964) (Armano)
- 1004439 packages/codegen: Merge `mark` and `write` calls in `printImportAttributes` (#25972) (overlookmotel)
- 94c8a34 packages/codegen: Remove `node` param from `printString` and `printNonNegativeFloat` (#25971) (overlookmotel)
- 7e2b4b3 packages/codegen: `printNonNegativeFloat` write mapping directly (#25968) (overlookmotel)
- f09c8ab minifier: Avoid creation of unnecessary conditional expressions (#25931) (Armano)
- 53ff080 packages/codegen: Remove `lastWasPostfixClose` (#25888) (overlookmotel)

### 📚 Documentation

- 07de646 packages/codegen: Fix JSDoc comments on `write*` methods (#25966) (overlookmotel)
- 3b09c04 packages/codegen: Clarify comment (#25959) (overlookmotel)
2026-08-24 11:19:12 +00:00
camc314 2dad1e0ec7 fix(parser): track irregular line terminators in trivia (#25947)
## Summary

- notify `TriviaBuilder` when the lexer consumes U+2028 or U+2029
- keep Annex B HTML-close comments after irregular line terminators attached as leading trivia
- add a script-mode regression test covering both Unicode separators
2026-08-20 18:46:29 +00:00
renovate[bot] d5d575c1de chore(deps): update rust to v1.98.0 (#25945)
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [rust](https://rust-lang.org/)
([source](https://redirect.github.com/rust-lang/rust),
[changelog](https://redirect.github.com/rust-lang/rust/blob/main/RELEASES.md))
| toolchain | minor | `1.97.1` → `1.98.0` |

---

### Configuration

📅 **Schedule**: (in timezone Asia/Shanghai)

- Branch creation
  - "before 10am on monday"
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR becomes conflicted, 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:eyJjcmVhdGVkSW5WZXIiOiI0NC4zNS40IiwidXBkYXRlZEluVmVyIjoiNDQuMzUuNCIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOltdfQ==-->

---------

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Cameron <cameron.clark@hey.com>
2026-08-20 18:04:07 +00:00
oxc-guard 0389c4010e release(crates): oxc v0.146.0 (#25912)
### 🚀 Features

- 83cb516 minifier: Improve negation of expressions in boolean context (#25755) (Armano)

### 🐛 Bug Fixes

- 134fb22 isolated-declarations: Preserve unresolved parameter types (#25909) (Dunqing)
- 526c2b3 codegen: Remove deprecated test APIs (#25889) (camc314)
- 344a9b2 codegen: Align enum template sourcemaps (#25872) (camc314)

### ⚡ Performance

- 5ef0c93 minifier: Unwrap all unary exprs without creating dummy expressions (#25891) (Armano)
- 8783524 packages/codegen: Remove loop from `growMappingBuffer` (#25886) (overlookmotel)
- b6b14c0 packages/codegen: Remove redundant branch (#25885) (overlookmotel)
- be6adf0 packages/sourcemap: Make `location` passed to `recordSourceMapping` always a number (#25884) (overlookmotel)
- f720f15 packages/codegen: Take named-mapping only code off hot path in `recordSourceMapping` (#25883) (overlookmotel)
- a734af5 packages/codegen: Remove redundant setting of `last` in `printImportAttributes` and `printIf` (#25882) (overlookmotel)
- c6e44c6 packages/codegen: Combine 2 writes in `printJSXElement` (#25881) (overlookmotel)
- 8801662 packages/codegen: Remove redundant mapping from `printParams` (#25880) (overlookmotel)

### 📚 Documentation

- 5ad330e packages/codegen: Reformat comments (#25876) (overlookmotel)
2026-08-19 08:29:51 +00:00
oxc-guard[bot] 4a4a1fb2e7 release(crates): oxc v0.145.0 (#25865)
### 💥 BREAKING CHANGES

- 365274e packages/codegen: [**BREAKING**] `printSync` return an object
(#25720) (overlookmotel)

### 🚀 Features

- 6a7eb60 packages/codegen: Alter capitalization of `sourceFilename`
option (#25854) (overlookmotel)
- 300763f packages/codegen: Add full source map support (#25585)
(camc314)
- a169e4a napi/minify: Expose property name mangling options (#24741)
(Dunqing)
- 2f5cdb1 minifier: Add property name mangling (#24740) (Dunqing)
- 4922141 mangler: Deduplicate private accessor names (#25601) (camc314)
- 1c4f519 napi: Add Relay transform plugin (#25503) (Boshen)
- a4478e9 codegen: Add `oxc-codegen` package (#25488) (overlookmotel)

### 🐛 Bug Fixes

- 0fbcf64 codegen: Validate sourcemap options (#25860) (camc314)
- 345f981 react_compiler: Skip node_modules by default (#25859) (Boshen)
- ab81f3f minifier: Drop side-effect-free additions (#25639) (Dunqing)
- 241c559 napi/minify: Accept RegExp for property filters (#25827)
(Dunqing)
- 4cc7ea4 codegen: Reject invalid indent options (#25807) (camc314)
- 53f9295 isolated-declarations: Preserve undefined for defaulted any
(#25292) (camc314)
- 8ab883a codegen: Preserve property key annotations (#25766) (Dunqing)
- b13fd48 minifier: Model uninitialized module vars as undefined
(#25497) (Dunqing)
- f6000ac ecmascript: Fold `**` with `Number::exponentiate`, not IEEE
`pow` (#25644) (Kotaro Chikuba)
- b846abc isolated-declarations: Handle ambient expando properties
(#25655) (camc314)
- dec0a86 react-compiler: Standardize diagnostics (#25702) (Boshen)
- fca2e0c parser: Reject initialized lexical declarations in for-in
(#25700) (Boshen)
- ae9be8f parser: Forbid type parameters on quoted constructors (#25696)
(Boshen)
- c5f188a react-compiler: Use Babel v1 validation defaults (#25676)
(Boshen)
- db44651 napi: Disable reuseWorker in browser bindings (#25640)
(leaysgur)
- ce35d47 react_compiler: Preserve JSX import source pragmas (#25592)
(Boshen)
- 059784d semantic: Respect shadowed `Infinity` and `NaN` in enum
evaluation (#25604) (camc314)
- bb5a232 minifier: Keep variable declaration initilized with class when
keepNames is enabled (#25584) (sapphi-red)
- f49229d minifier: Keep side effects when rotating bitwise operands
(#25596) (Kotaro Chikuba)
- e82495b ecmascript: Derive `ToNumber` of `!x` from `ToBoolean`
(#25595) (Kotaro Chikuba)
- 509931b semantic: Classify global references per identifier (#25608)
(camc314)
- 80484ce mangler: Correct base54 safety comment (#25606) (camc314)
- c1369a7 codegen: Resolve private names in class heritage (#25588)
(camc314)
- c002f29 codegen: Escape sources for empty import specifiers (#25586)
(camc314)
- 0c68b7f estree: Emit `decorators` on `FormalParameterRest` (#25582)
(camc314)
- cdf1846 semantic: Allow legacy escapes in JSX attributes (#25576)
(Boshen)
- e75e102 minifier: Preserve block statement in labeled iteration
statements (#25162) (Armano)
- 771d79a mangler: Exclude non-manglable symbols from slot assignment
(#25539) (sapphi-red)
- 76b19f5 minifier: Avoid duplicating large folded strings (#25532)
(Dunqing)
- 59e8895 codegen: Validate starting indent level (#25550) (camc314)
- 88b34f2 clippy: Remove unneeded `unsafe` (#25551) (camc314)
- 23a7ad0 parser: Stop delimited lists at end of file (#25542) (Boshen)
- 73acba9 parser: Preserve fatal errors during await reparse (#25541)
(Boshen)
- c3e99d1 minifier: Avoid invalid octal escapes in template folds
(#25495) (Dunqing)
- b4e6a9e codegen: Output newline after `export default interface`
(#25487) (overlookmotel)
- 5fcf683 minifier: Correct issue with try finally termination (#25185)
(Armano)
- 1645d93 react_compiler: Preserve source spans (#25462) (Boshen)
- 8d7f9cf react_compiler: Honor eslint suppressions (#25394) (Boshen)

### ⚡ Performance

- 568203e ecmascript: Use binary search for known globals (#25817)
(Boshen)
- c84ede3 estree_tokens: Share JS token update entry point (#25826)
(Boshen)
- 9a6e862 minifier: Move owned statements directly (#25835) (Dunqing)
- 61b2aef minifier: Move owned AST nodes directly (#25837) (Dunqing)
- 673b04b minifier: Replace expressions without take_in dummies (#25836)
(Dunqing)
- 63ff8ef linter: Outline diagnostic construction (#25762) (Boshen)
- 621808e diagnostics: Measure graphemes lazily (#25723) (Boshen)
- f62ed0e diagnostics: Optimize graphical number rendering (#25715)
(Boshen)
- 7152834 diagnostics: Reduce graphical formatting overhead (#25714)
(Boshen)
- 10fc4b7 diagnostics: Reduce graphical rendering allocations (#25711)
(Boshen)
- 9c8abab diagnostics: Batch graphical reports (#25710) (Boshen)
- 757f3d4 mangler: Share allocated names across reused slots (#25605)
(camc314)
- 5444cbf codegen: Skip escaping harmless `<` tokens (#25564) (camc314)

### 📚 Documentation

- 58f7ab9 packages/codegen: Reformat docs and comments (#25848)
(overlookmotel)
- 627466e transform-react: Document all options (#25800) (Boshen)
- ce03ac1 packages/codegen: Fix JSDoc comments for `printSync` (#25722)
(overlookmotel)
- 386a699 packages/codegen: Correct JSDoc comment (#25716)
(overlookmotel)
- 31e571d mangler: Update code example (#25599) (camc314)
- fd62354 codegen: Revamp package readme (#25560) (camc314)
- ffa3153 codegen: Clarify raw transfer Node requirement (#25565)
(camc314)
- c5d4063 codegen: Clarify binary walk allocations (#25562) (camc314)
- 5703d7a codegen: Correct stale printer comments (#25561) (camc314)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2026-08-18 22:26:40 +08:00
Dunqing 8ab883afaa fix(codegen): preserve property key annotations (#25766)
`@__KEY__` and `#__KEY__` are currently treated as normal comments. Codegen can drop them before a later property-mangling pass. The property may then be renamed while the annotated string keeps its old name.

This classifies the marker as a property-key annotation. Codegen keeps it next to string and no-substitution template literals when annotation comments are enabled, and the property mangler reads that classification instead of scanning source text. Final output still follows the normal comment options, so whitespace-minified or annotation-disabled output removes the marker.

## Example

Input:

```js
const object = { _field: 1 };
const key = /* #__KEY__ */ "_field";
object[key];
```

Before, an intermediate codegen pass could remove the marker:

```js
const object = { _field: 1 };
const key = "_field";
object[key];
```

After, the marker survives for the later property-mangling pass.

Verified with the affected crate suites, `just minsize`, workspace lint, docs, AST generation, and independent review. `just ready` is only blocked locally by existing Node-version and terminal-color snapshot differences.

Implemented with AI assistance (OpenAI Codex). I reviewed and understand the changes and remain responsible for this contribution under the repository AI usage policy.
2026-08-17 09:23:04 +00:00
Ulrich Stark c1f7d7d1c2 refactor(parser): remove dead match options in get_modifier (#25725)
`cur_kind` can never be `Kind::Get` or `Kind::Set` because then the
`ModifierKind::try_from(cur_kind).ok()?` line above would have returned
earlier.
2026-08-17 09:33:10 +01:00
Boshen fca2e0cfed fix(parser): reject initialized lexical declarations in for-in (#25700)
Rejects initialized `let` and `const` declarations in `for...in` during parsing while preserving Annex B's non-strict `var` form.

Adds misc coverage for valid and invalid initializer forms.

Verified with `just ready` and parser conformance.

Closes #25149.

AI-assisted.
2026-08-15 06:58:08 +00:00
Boshen ae9be8f8bd fix(parser): forbid type parameters on quoted constructors (#25696)
Quoted constructor methods bypassed the AST-based constructor validation. Validate type parameters after resolving the method key, preserving the AST shape.

Validation: `just ready`, parser conformance, and allocation checks.

Closes #25692.

AI-assisted with Codex.
2026-08-15 05:02:23 +00:00
Boshen 23a7ad096a fix(parser): stop delimited lists at end of file (#25542)
Stop parsing delimited-list elements after a separator when EOF or an undetermined token follows, preventing malformed tuple syntax from creating reversed spans during error recovery.

Validated with `cargo coverage -- parser --filter oxc-23670 --detail`.

AI assistance was used to prepare this change.

Closes #23670.
2026-08-12 13:58:51 +00:00
Boshen 73acba93fb fix(parser): preserve fatal errors during await reparse (#25541)
Fixes #23681.

Preserve initial fatal parser errors during top-level `await` reparsing, preventing malformed recovery AST nodes from reaching Oxlint.

Validated with parser unit/conformance suites and allocation snapshots. `just ready` only fails three unrelated ANSI snapshot checks in the current environment.

AI-assisted.
2026-08-12 11:25:27 +00:00
oxc-guard b6f1458dec release(crates): oxc v0.144.0 (#25474)
### 💥 BREAKING CHANGES

- a33788e ast: [**BREAKING**] Group class heritage into `ClassHeritage` (#25360) (camc314)
- 5c5cdcd ast: [**BREAKING**] Narrow `TSInterfaceHeritage::expression` to TSTypeName (#24360) (camc314)
- 6be314f ast: [**BREAKING**] Remove duplicated `VariableDeclarator::kind` (#25319) (camc314)
- 44fd320 ast: [**BREAKING**] Split TS external modules & Namespace Declarations (#25284) (camc314)

### 🚀 Features

- 9a37c41 napi: Restructure React transform options (#25326) (Boshen)
- b3c1b30 allocator: Add `ArenaVec::push_mut` (#25338) (overlookmotel)

### 🐛 Bug Fixes

- bbd6ed3 codegen: Wrap string literal in parens after directives (#25435) (overlookmotel)
- d07a293 codegen: Preserve cast parentheses in conditional tests (#25115) (camc314)
- 8b7d441 codegen: Preserve satisfies parentheses before bitwise operators (#25113) (camc314)
- e0fb2d7 minifier: Avoid unsafe return removal in labeled blocks (#25406) (Armano)
- c49f4ce parser: Preserve terminal license comments (#25400) (camc314)
- 9d19ab3 transform_react: Downgrade nonfatal compiler diagnostics (#25418) (Boshen)
- 937825c react_compiler: Disable exhaustive memo validation by default (#25417) (Boshen)
- 12937b3 parser: Reject comma expressions in class fields (#25385) (Cameron)
- 7d8a9b5 react_compiler: Preserve hook spans for React Refresh (#25393) (Boshen)
- 9e93ba6 parser: Reset auto-accessor initializer context (#25384) (camc314)
- cc2e28d parser: Reject trailing tokens in `Parser::parse_expression` (#25371) (camc314)
- 697c629 minifier: Preserve Annex B labeled-function bindings in implicit-return rewrite (#25349) (Armano)
- 4d723ca parser: Report TS1035 for quoted module names (#25305) (camc314)
- 0c9b980 semantic: Report module declaration diagnostics (#25285) (camc314)
- 2a1058a napi: Omit parser header from WASI declarations (#25254) (camc314)

### ⚡ Performance

- dd1430b semantic: Avoid allocation in class overload check (#25440) (camc314)
- e420816 parser: Optimize trailing comma tracking (#25376) (camc314)
- 6529d1a minifier: Short-circuit scope check when alternate already determines result (#25318) (Armano)

### 📚 Documentation

- fe111eb allocator: Improve doc comments for `Arena` methods (#24922) (overlookmotel)
2026-08-10 09:57:10 +00:00