Commit Graph

181 Commits

Author SHA1 Message Date
Dunqing c3dedc9b0c fix(semantic): skip function body bindings in parameters (#26099)
Function parameters, TypeScript signatures, and function bodies currently share one Oxc semantic scope. A reference in a parameter can therefore bind to a declaration inside the body, even though JavaScript does not make body declarations visible there. Rolldown may then treat a global as local, skip a configured define, or remove live code.

## Example

```js
export function load(value = typeof window !== "undefined") {
  var window;
  return value;
}
```

The body `var window` is not visible to the default value. Before this change, Oxc resolved `window` in the default value to that body declaration. It should remain a global reference.

The workaround resolves parameter and signature references before visiting the body, while only parameter bindings are present. If a reference is still unresolved, its `lookup_scope_id` advances to the function's parent. Final resolution resumes there, so declarations added while visiting the body are skipped. References created in the body still begin at the function scope and resolve normally.

```text
Before: parameter reference -> completed function scope -> body binding (wrong)

After:  parameter reference -> parameter bindings -> parent scopes
        body reference      -> completed function scope -> parent scopes
```

Parameter decorators already begin in the enclosing class scope, so they are left for normal final resolution. This emulates separate parameter and body scopes until https://github.com/oxc-project/backlog/issues/176 is implemented.

The corrected semantic data also exposes the transformer case covered by #26105.

Verified with semantic and transformer-plugin tests, Clippy, coverage, allocation snapshots, and diff checks. `just ready` completed workspace checks but stopped at a codegen snapshot recorded with Node.js v26.5.0; the local version is v25.8.1.

Closes #20427
Closes #22783

Downstream reports:

- https://github.com/rolldown/rolldown/issues/10722
- https://github.com/rolldown/rolldown/issues/10779

AI assistance: OpenAI Codex was used to investigate, implement, and test this change. The contributor is responsible for the submitted change.
2026-08-27 17:23:18 +00:00
camc314 65cda29177 fix(transform_conformance): record missing expected errors (#25306)
Fix the transformer conformance runner incorrectly marking a fixture as passed that specified `throws` when Oxc produces no error.

Failed conformance cases now always record a diagnostic. This exposes previously hidden failures in the Babel snapshot, including the nested ambient-module fixtures.
2026-08-12 10:30:24 +00:00
oxc-guard 7ebbdddce7 chore(submodules): update submodule SHAs to latest commits (#25505)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `b363f29` → `be13516`
- babel: `06b6eae` → `1eac448`
- estree-conformance: `f7a4e0c` → `8d4e1fa`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-08-11 16:17:31 +00:00
camc314 4d723caaff fix(parser): report TS1035 for quoted module names (#25305)
Quoted module names are only valid in ambient contexts in TypeScript, but we were accepting them in regular TypeScript files.

This reports TS1035 when a quoted module name appears outside a declaration file or ambient declaration. The conformance snapshots now cover both TypeScript cases, and the old invalid codegen fixture has been replaced with a valid internal module declaration.
2026-08-05 10:21:52 +00:00
oxc-guard[bot] 4e7007118d chore(submodules): update submodule SHAs to latest commits (#25261)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `d1d583d` → `b363f29`
- babel: `c86e9e4` → `06b6eae`
- TypeScript: `637d574` → `b465fdb`
- estree-conformance: `e8fd120` → `f7a4e0c`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
2026-08-03 22:09:18 +01:00
camc314 76ec104498 fix(semantic): resolve import-equals namespaces (#22696)
Fixes `import =` semantic reference resolution so internal module references are resolved as namespace lookups instead of ordinary value reads.

TypeScript treats the RHS of an internal `import =` specially. In the checker, `getTargetOfImportEqualsDeclaration` delegates internal module references to `getSymbolOfPartOfRightHandSideOfImportEquals`, which resolves bare RHS names and intermediate qualified names with `SymbolFlags.Namespace` rather than value meaning:

- `getTargetOfImportEqualsDeclaration`: https://github.com/microsoft/TypeScript/blob/f350b52331494b68c90ab02e2b6d0828d2a22a74/src/compiler/checker.ts#L3708-L3733
- `getSymbolOfPartOfRightHandSideOfImportEquals`: https://github.com/microsoft/TypeScript/blob/f350b52331494b68c90ab02e2b6d0828d2a22a74/src/compiler/checker.ts#L4480-L4499
- `getSymbolOfNameOrPropertyAccessExpression` also routes names on the RHS of import/export assignments through that same helper: https://github.com/microsoft/TypeScript/blob/f350b52331494b68c90ab02e2b6d0828d2a22a74/src/compiler/checker.ts#L50014-L50019

Before this change, Oxc could count plain values as references from `import =`:

```ts
const x = 1;
import foo = x;
```

Before:

```text
x references: 1
```

After:

```text
x references: 0
```

That matches TypeScript’s behavior because `x` is only a value symbol, not a namespace-capable symbol.

The same applies to qualified names:

```ts
const x = { y: 1 };
import foo = x.y;
```

Before:

```text
x references: 1
```

After:

```text
x references: 0
```

But namespace-capable declarations still resolve:

```ts
namespace x {}
import foo = x;
```

After:

```text
x references: 1
```

and:

```ts
namespace x {
  export namespace y {}
}

import foo = x.y;
```

After:

```text
x references: 1
```

This updates the semantic snapshots to reflect the corrected reference/declaration matching.
2026-07-20 13:10:54 +00:00
oxc-guard[bot] 17cb5c13c5 chore(submodules): update submodule SHAs to latest commits (#24463)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `de8e621` → `d1d583d`
- babel: `1fb0b77` → `c86e9e4`
- TypeScript: `7964e22` → `637d574`
- estree-conformance: `6514ad7` → `e8fd120`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
2026-07-13 14:24:36 +01:00
camc314 af4922be6d fix(transformer): clear lowered namespace redeclarations (#24300) 2026-07-08 13:56:43 +00:00
camc314 6371fed556 fix(transformer): remove stale enum member bindings (#24272)
## Summary

Remove TypeScript enum-member bindings after transformation.

Enum members are represented as bindings during semantic analysis so the transformer can resolve member values, fold references, and handle merged enums. Once TypeScript transformation finishes, those bindings no longer correspond to emitted JavaScript declarations.

Include `EnumMember` in the existing final TypeScript binding cleanup instead of removing bindings during enum lowering, where later references may still need them.

This fixes `discriminatedUnionTypes4.ts` and removes the same stale binding mismatch from other enum cases.
2026-07-07 18:29:57 +00:00
Dunqing f05dfabe5c fix(transformer): correct symbol flags for lowered namespaces (#24271)
Closes #24224 — the first commit is @camc314's fix from there.

Lowered namespaces kept their `ValueModule`/`NameSpaceModule` symbol flags, so the flags no longer matched the emitted JavaScript:

- Namespaces lowered to a declaration become `let` → `BlockScopedVariable`.
- Namespaces lowered to an assignment only lose their module bits.

This removes over 2,000 stale symbol-flag mismatches from the snapshots.

Unlike #24224 there is no pending state: the type-only check for merged namespaces now reads per-declaration flags from the redeclaration list instead of the symbol's live flags, so each declaration can update the flags right when it is lowered.
2026-07-07 16:48:19 +00:00
Dunqing 84eeb5570b fix(transformer): correct symbol flags for lowered enums (#24269)
Closes #24226 — the first commit is @camc314's fix from there.

Lowered enums kept their `RegularEnum`/`ConstEnum` symbol flags, so the flags no longer matched the emitted JavaScript:

- Top-level enums become `var` → `FunctionScopedVariable`.
- Exported and nested enums become `let` → `BlockScopedVariable`.
- Merged enums lowered to an assignment only lose their enum bits.

This removes over 1,000 stale symbol-flag mismatches from the snapshots.

Unlike #24226 there is no pending state: enum member inlining now identifies enums through `EnumData` (#24268) instead of `SymbolFlags`, so the flags can be updated right when the enum is lowered.
2026-07-07 16:48:19 +00:00
camc314 8260096253 fix(transformer): correct span for lowered namespace symbol (#24222)
## Summary

- preserve source spans when TypeScript namespace declarations are lowered to variable bindings
- update semantic coverage snapshots, removing stale `Span { start: 0, end: 0 }` mismatches
2026-07-07 02:27:08 +00:00
camc314 d8ead846c8 fix(transformer): correct scoping flags for lowered enums (#24225)
## Summary

TypeScript enum lowering reuses the enum body’s scope for the generated function expression. Update that scope with `ScopeFlags::Function` so transformed semantic data matches a freshly rebuilt AST.
2026-07-06 13:34:00 +00:00
camc314 e8b50ee716 fix(transformer): clean up semantics for stripped TypeScript syntax (#24180)
## Summary

Keep transformer semantic data in sync when TypeScript-only syntax is removed.

This change:

- removes resolved and unresolved references belonging only to stripped TypeScript syntax
- removes bindings for erased type-only and unused imports
- preserves runtime bindings when a type import is merged with a value declaration
- promotes the surviving declaration’s symbol flags, span, and redeclaration metadata
- adds coverage for type imports merged with runtime declarations
- refreshes semantic and transformer conformance snapshots

## Motivation

We are preparing to change the AST shape, including adding and rearranging scopes.

Currently, transformer semantic snapshots contain thousands of lines of mismatches caused by stale bindings and references from TypeScript syntax that has already been removed from the AST. That creates a large amount of unrelated snapshot noise.

With that noise present, snapshot changes caused by the upcoming AST work would be difficult to review: a real scope or semantic regression could easily be hidden among mechanical churn.

This PR fixes the underlying semantic inconsistencies first, giving us a much cleaner baseline for reviewing future AST and scope changes. It is not intended to change emitted JavaScript.
2026-07-06 08:11:46 +00:00
leaysgur 47008d88b6 fix(ci): regenerate transform_conformance snapshots (#24103)
In #24078, the snapshot generation was missed, which caused the CI to fail on all subsequent PRs.

Also fixes typo in CI trigger, which should prevent this. 🙈
2026-07-03 06:38:43 +00:00
oxc-guard 9e72aa0312 chore(submodules): update submodule SHAs to latest commits (#23451)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `05bb032` → `de8e621`
- babel: `2688fbd` → `1fb0b77`
- TypeScript: `7539c04` → `7964e22`
- estree-conformance: `ca42c3d` → `6514ad7`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-06-15 14:31:01 +00:00
camc314 d74964cda6 perf(parser): store class definite assertion offset (#23170)
- Store class property definite assignment assertion positions as `u32` offsets instead of carrying a full `Span`.
- Reconstruct the one-character diagnostic span only when emitting class definite-assignment diagnostics.
- aligns the behaviour for definite assertion errors with variables by reporting on the definite assertion rather than on the whole class member
2026-06-09 15:33:10 +00:00
camc314 d169fcd3af feat(parser): report invalid class definite assertions (#23164)
- Match TypeScript’s diagnostic precedence for class property definite assignment assertions.
 - Report TS1264 when a class property uses ! without a type annotation.
 - Report TS1255 when a definite assignment assertion is used in disallowed class property contexts, including static.
2026-06-09 14:42:42 +00:00
oxc-guard b4f9cb9d8c chore(submodules): update submodule SHAs to latest commits (#23118)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `7e115f4` → `05bb032`
- babel: `d9fe348` → `2688fbd`
- TypeScript: `e5509e2` → `7539c04`
- estree-conformance: `faf089d` → `ca42c3d`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-06-08 14:49:36 +00:00
oxc-guard[bot] 50baca037c chore(submodules): update submodule SHAs to latest commits (#22721)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `78fc3f8` → `7e115f4`
- babel: `3d34928` → `d9fe348`
- TypeScript: `f350b52` → `e5509e2`
- estree-conformance: `576e7d8` → `faf089d`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
2026-05-25 22:16:39 +08:00
camc314 7baed9c4b7 fix(transformer/private-method): clear inherited strict flags (#22508)
Fixes private method transforms so scopes inherited from a transformed private method are converted back to sloppy mode when the surrounding scope is sloppy.

Previously we only cleared `StrictMode` on the private method function scope itself. That left child scopes, such as async/generator wrapper scopes, marked as strict even though the transformed output is no longer inside a class method. This caused semantic rebuild mismatches across Babel and Test262 coverage.

Nested classes are still left strict, since class bodies are always strict mode.
2026-05-25 09:39:48 +00:00
oxc-guard[bot] ec7de07b08 chore(submodules): update submodule SHAs to latest commits (#22550)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `ccaac10` → `78fc3f8`
- babel: `4079bcd` → `3d34928`
- estree-conformance: `9c67f5e` → `576e7d8`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
2026-05-19 10:46:02 +08:00
Dunqing e6090e7ccc fix(transformer): keep enum IIFE when a non-inlinable value reference remains (#22501)
Refs vitejs/vite#22452 (comment).

The optimize pass dropped the enum declaration whenever the members were all evaluable — regardless of whether some non-inlinable value reference still named the enum at runtime. The result referenced a binding that no longer existed:

```ts
const enum Phase { one = 'one' }
export default Phase;
// -> export default Phase;  // ReferenceError at runtime

enum Direction { Up }
Direction.Up.toString();
// -> Direction.Up.toString();  // ReferenceError at runtime
```

## Fix

Decide based on the remaining resolved references: drop only when none of them is a value reference (`Read`/`Write`). Type references (`as E`, `: E`) are kept here and stripped later by `annotations.rs`, so they don't block removal. `typeof E` in JS expression position is `Read` and correctly keeps the IIFE; `typeof E` in TS type position is `ValueAsType` (not in `Value`) and doesn't.

Unifies the rule for regular and const enums — the previous asymmetry (const always dropped, regular dropped only when no refs at all) had no principled basis.

## Compatibility

Diverges from Babel on two `optimize-const-enums/*` fixtures where the input has a bare value reference to the enum that we can't inline. Three engines disagree on what to do:

| Engine | Inline `E.X` member accesses | Preserve `E` binding (IIFE) | Result for `E.unknown` / bare `E` |
|---|---|---|---|
| Babel `transform-typescript` (optimize-const-enums) | yes | **no** | runtime ReferenceError / TypeError |
| tsc `--isolatedModules` | no | yes | `undefined` / resolves |
| oxc after this PR | yes | yes | `undefined` / resolves |

We now hybridize: inline what's inlinable (Babel) **and** keep the binding (tsc). Local overrides under `tasks/transform_conformance/overrides/` record the new expected output for the two affected Babel fixtures.

### `optimize-const-enums/local`

Input:

```ts
const enum A {
  x, y
}

A.x;
A["y"];
A.z;
A;
```

Babel (and oxc before this PR):

```js
0;
1;
A.z;
A;
```

`A.z` is `TypeError: cannot read properties of undefined`; `A;` is `ReferenceError`.

tsc (`--isolatedModules`):

```js
var A;
(function (A) {
    A[A["x"] = 0] = "x";
    A[A["y"] = 1] = "y";
})(A || (A = {}));
A.x;
A["y"];
A.z;
A;
```

Keeps the IIFE binding, no member-access inlining. `A.z` evaluates to `undefined`; `A;` is a no-op.

oxc after this PR (`overrides/.../optimize-const-enums/local/output.mjs`):

```js
var A = /* @__PURE__ */ function(A) {
  A[A["x"] = 0] = "x";
  A[A["y"] = 1] = "y";
  return A;
}(A || {});
0;
1;
A.z;
A;
```

Hybrid: inlines `A.x` / `A["y"]` like Babel, **and** keeps the IIFE binding like tsc — so `A.z` evaluates to `undefined` (not crash) and `A;` resolves.

### `optimize-const-enums/merged`

Input:

```ts
const enum A {
  x, y
}

const enum A {
  z
}

A.x;
A["y"];
A.z;
A.w;
A;
```

Babel (and oxc before this PR):

```js
0;
1;
0;
A.w;
A;
```

`A.w` is `TypeError: cannot read properties of undefined`; `A;` is `ReferenceError`.

tsc (`--isolatedModules`):

```js
var A;
(function (A) {
    A[A["x"] = 0] = "x";
    A[A["y"] = 1] = "y";
})(A || (A = {}));
(function (A) {
    A[A["z"] = 0] = "z";
})(A || (A = {}));
A.x;
A["y"];
A.z;
A.w;
A;
```

Both IIFEs emitted, no inlining. `A.w` is `undefined`; `A;` resolves.

oxc after this PR (`overrides/.../optimize-const-enums/merged/output.mjs`):

```js
var A = /* @__PURE__ */ function(A) {
  A[A["x"] = 0] = "x";
  A[A["y"] = 1] = "y";
  return A;
}(A || {});
A = /* @__PURE__ */ function(A) {
  A[A["z"] = 0] = "z";
  return A;
}(A || {});
0;
1;
0;
A.w;
A;
```

Hybrid: both enum bodies lower (the second reuses the first's binding via `A = (function(A) { … })(A || {})` — assignment, not `var`) **and** members are inlined like Babel. `A.w` evaluates to `undefined`; `A;` resolves.

## Verification

New fixtures cover the bug shapes:
- `babel-plugin-transform-typescript/const-enum-value-ref-kept/` — `export default Phase`
- `babel-plugin-transform-typescript/const-enum-mixed-refs/` — member access + bare ref combined

Existing `optimize-enums/type-cast` updated to drop the IIFE for the all-type-refs case (the regular-enum side of the unified rule).
2026-05-18 02:19:11 +00:00
camc314 3ce3431717 fix(transformer/explicit-resource-managment): preserve shadowed for-head block (#22451)
Given:
```
for (using x of y) { const x = z; }
```
Previously we would produce

```
var _usingCtx2 = require("@oxc-project/runtime/helpers/usingCtx");
for (const _x of y) try {
	var _usingCtx = _usingCtx2();
	const x = _usingCtx.u(_x);
	const x = z;
} catch (_) {
	_usingCtx.e = _;
} finally {
	_usingCtx.d();
}
```

Now we produce

```
var _usingCtx2 = require("@oxc-project/runtime/helpers/usingCtx");
for (const _x of y) try {
	var _usingCtx = _usingCtx2();
	const x = _usingCtx.u(_x);
	{
		const x = z;
	}
} catch (_) {
	_usingCtx.e = _;
} finally {
	_usingCtx.d();
}
```

Which avoids a syntax error - cannot create a duplicate var named `x`.
2026-05-16 11:10:11 +00:00
oxc-guard e68f4fa1c3 chore(submodules): update submodule SHAs to latest commits (#22417)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `d0c1b45` → `ccaac10`
- babel: `6402dbb` → `4079bcd`
- estree-conformance: `d968f2c` → `9c67f5e`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-05-14 10:36:57 +00:00
camc314 dda33deea8 fix(transformer/explicit-resource-management): align lexical binding scopes (#22320)
Part of #9699
2026-05-14 09:18:42 +00:00
camc314 0cba210ba6 fix(transformer/class): replace new.target in static blocks (#22360) 2026-05-12 18:20:40 +00:00
camc314 4e880de872 fix(transformer/object-rest-spread): declare temp vars for computed keys (#22284)
Given some code like
```js
const {
  [({ ...rest }) => {
    let { ...b } = {};
  }]: a,
  [({ ...d } = {})]: c,
} = {};

export {}; // necessary so we are in strict mode
```
It would previously be transformed to:
```js
const { [(_ref) => {
	let rest = _extends({}, (_objectDestructuringEmpty(_ref), _ref));
	let _ref2 = {}, b = _extends({}, (_objectDestructuringEmpty(_ref2), _ref2));
}]: a, [(_ref3 = {}, {} = _ref3, d = _extends({}, (_objectDestructuringEmpty(_ref3), _ref3)), _ref3)]: c } = {};
export {};
```

This is a problem because there was no declaration to `_ref3`

This causes runtime errors.

After this PR, we now emit:

This new code includes `var _ref3`, fixing the unresolved reference issue.

```js
var _ref3;
const {
  [_ref => {
    let rest = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref), _ref));
    let _ref2 = {},
      b = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref2), _ref2));
  }]: a,
  [(_ref3 = {}, {} = _ref3, d = babelHelpers.extends({}, (babelHelpers.objectDestructuringEmpty(_ref3), _ref3)), _ref3)]: c
} = {};

```

This aligns with Babel.

----

This has been fixed by walking up to find the containing statement, and inserting the var declaration before it.

Previously, the `var` declaration would only be inserted if we were inside `ExpressionStatementExpression` which was not guaranteed.
2026-05-11 09:14:25 +00:00
Dunqing 5da9fda0d8 fix(transformer/explicit-resource-management): preserve class names (#22306)
Stacked on #22305.

## Why

`class C { static getSelf() { return C } }` lowered by the explicit resource management transform was emitting `var C = class {}` (anonymous), so when the outer `C` is reassigned (`C = 123`), `getSelf()` returns the reassigned value instead of the original class — the exact behaviour the named class expression's inner binding is supposed to protect against. Babel emits `var C = class C {}` for the same input.

## Fix

1. **Emit `var C = class C {}`** for both `class C {}` and `export default class C {}`. Adds a `preserve_class_expression_name` helper that mirrors the swap in `decorator::legacy::transform_class_declaration_with_class_decorators` — generate a fresh `Class`-flagged symbol in the class scope for the inner class id, swap `class_decl.id.symbol_id` (via `Cell::replace`) to the new symbol, and repurpose the original symbol as the outer `var` (flags → `FunctionScopedVariable`). Returns the outer `BoundIdentifier` and the original span so the caller can emit the outer declarator with the correct span.

2. **Carry the original span through both sides of the swap.** The inner symbol is created with the original `id.span` (via `Scoping::create_symbol(span, ...)` + `add_binding`); the outer var's `BindingIdentifier` is emitted with the same span (via `BoundIdentifier::create_spanned_binding_pattern`, added in #22305). This eliminates the `Symbol span mismatch` diffs in:
   - `transform-top-level/hoisting/input.mjs`
   - `transform-top-level/hoisting-default-class/input.mjs`
   - `export-class-name/input.js`

## Comparison with Babel

Babel reuses the *original `id` node* for the outer `var` and clones it for the inner class. This PR does the inverse — reuses the original *symbol id* for the outer `var` and generates a new symbol for the inner class. Given oxc's symbol-aware model, the inversion avoids rewiring every outer-scope reference (`const K = C`, `C = 123`, …): they already point at the original symbol.

## Remaining follow-up

`export-class-name/input.js` still has `Symbol reference IDs mismatch` for `C` — references inside the class body (`return C`) still resolve to the outer symbol in the transformer's bookkeeping. A fresh semantic rebuild over the printed AST correctly resolves them to the inner class symbol, so tools that re-run semantic (rolldown / oxc_minifier on a fresh build) are fine. Tools that trust the transformer's symbol table directly (in-place minification / mangler) will see the stale binding. Rewiring those references is a separate follow-up (`Reference.symbol_id` update + `delete_resolved_reference` / `add_resolved_reference`).

## Conformance impact

- Babel suite: **692 → 694 passing** (+2)
- `transform-top-level/hoisting/input.mjs` ✓
- `transform-top-level/hoisting-default-class/input.mjs` ✓
- `export-class-name/input.js`: 4 span mismatches eliminated; reference-rewiring follow-up remains.

## Test plan

- [x] `cargo run -p oxc_transform_conformance`
- [x] `cargo run -p oxc_transform_conformance -- --exec`
- [x] `cargo test -p oxc_transformer`
2026-05-11 08:34:24 +00:00
camc314 b5d970fe5d fix(transformer/explicit-resource-management): preserve class names (#22290)
related to https://github.com/oxc-project/oxc/issues/9699
2026-05-11 07:55:58 +00:00
oxc-guard[bot] 550052a096 chore(submodules): update submodule SHAs to latest commits (#22170)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `2b2ecea` → `d0c1b45`
- babel: `c543b03` → `6402dbb`
- TypeScript: `c7a0ae1` → `f350b52`
- estree-conformance: `e4104a1` → `d968f2c`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: oxc-guard[bot] <276638029+oxc-guard[bot]@users.noreply.github.com>
2026-05-06 09:19:12 +01:00
Boshen 3fca6febc6 chore(submodules): update submodule SHAs to latest commits (#21455)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `ff0d161` → `2b2ecea`
- babel: `91b4ce3` → `c543b03`
- TypeScript: `7b8cb3b` → `c7a0ae1`
- estree-conformance: `d5e48e7` → `e4104a1`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-04-15 09:08:25 +00:00
Dunqing 679f57fab2 feat(transformer/typescript): implement const enum inlining and declaration removal (#20508)
## Summary

Depends on #20602.

Closes: https://github.com/oxc-project/oxc/issues/6073
Closes: #11844

- Inline const enum member accesses (`Foo.Bar` / `Foo["Bar"]`) to literal values when `optimize_const_enums` is enabled
- Remove non-exported const enum declarations when all members are evaluable
- Use `exit_statements` for enum removal so inlining happens before removal
- Delete references when inlining enum member accesses for correct semantic data
- Handle `IdentifierReferenceRename` for sibling enum member references in merged declarations

## Test plan

- [x] Transform conformance tests pass (`cargo run -p oxc_transform_conformance`)
- [x] `cargo test -p oxc_transformer` passes
- [x] Babel conformance snapshot updated
2026-04-13 03:29:40 +00:00
Boshen 5f6ce21874 chore(submodules): update submodule SHAs to latest commits (#21105)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `5c82069` → `ff0d161`
- babel: `0124e7c` → `91b4ce3`
- TypeScript: `4f7b417` → `7b8cb3b`
- estree-conformance: `dc0f79b` → `d5e48e7`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-04-07 06:54:12 +00:00
Boshen 75f4a3e593 chore(submodules): update submodule SHAs to latest commits (#20651) 2026-03-23 18:23:15 +08:00
Boshen f42be37c91 chore(submodules): update submodule SHAs to latest commits (#20518)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `63829c6` → `3a9ecbe`
- babel: `87a048d` → `31b3d95`
- TypeScript: `c9e7428` → `9059e5b`
- estree-conformance: `4daa9d7` → `9a4ddfb`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2026-03-20 13:13:40 +08:00
Boshen 5474d0a091 perf(semantic): V8-style walk-up reference resolution (#20292)
## Summary

- Replace bubble-up reference resolution with V8-style walk-up algorithm
- References are collected in a flat `Vec<(Ident, ReferenceId)>` during traversal instead of per-scope hashmaps
- After full AST visit, all references are resolved in a single pass by walking up the scope chain from each reference's scope
- `leave_scope()` no longer does any reference resolution work — only `direct_eval` flag propagation remains
- Early resolution via checkpoint mechanism preserved for function parameters and catch parameters (prevents binding to body variables that share the same scope)
- Deduplicated walk-up logic into a single `#[inline(always)]` helper shared by both normal and early resolution paths
- Uses `to_vec+truncate` instead of `split_off` to preserve `Vec` capacity and avoid reallocation
- Removes `smallvec` and `oxc_data_structures` dependencies from `oxc_semantic`

### Why this is faster

| Operation | Bubble-up (old) | Walk-up (new) |
|-----------|-----------------|---------------|
| Per reference creation | Hashmap insert | Vec push (O(1) amortized) |
| Per scope exit | Drain + merge hashmap | Nothing |
| Per reference resolution | Implicit via merging | Walk scope chain, O(depth) lookups |
| Total hashmap mutations | O(refs × depth) inserts+drains | 0 during traversal |

Hashmap lookups (read-only) are cheaper than hashmap drain+insert (mutating, allocating). The flat Vec also eliminates creating/recycling per-depth hashmaps entirely.

### Snapshot changes

3 jest linter rule snapshots have diagnostic reordering (same diagnostics, different emission order) due to references being processed in insertion order rather than scope-by-scope.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-13 06:20:40 +00:00
Boshen 7e83da9f2f chore(submodules): update submodule SHAs to latest commits (#20268) 2026-03-12 19:07:19 +08:00
Boshen f467298373 chore(submodules): update submodule SHAs to latest commits (#19951) 2026-03-06 14:45:41 +08:00
Boshen 529fbac105 chore(submodules): update submodule SHAs to latest commits (#19662) 2026-02-24 15:34:23 +08:00
camc314 08b0218dd6 chore(submodules): update submodule SHAs to latest commits (#19518) 2026-02-18 14:56:36 +00:00
Boshen deed3d851b fix(transformer): remove unnecessary trailing expression in object rest spread assignment (#19259)
## Summary

- Skip the trailing reference (e.g. `_c`) in the generated sequence expression when the destructuring assignment is directly inside an `ExpressionStatement`, since the expression result is not consumed
- Before: `_c = c2, {a2} = _c, b2 = objectWithoutProperties(_c, ["a2"]), _c;`
- After: `_c = c2, {a2} = _c, b2 = objectWithoutProperties(_c, ["a2"]);`
- The trailing reference is still kept when the result is consumed, e.g. `console.log((..., _c))`

Closes #7389 (issue 1)

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-11 11:43:24 +00:00
Boshen 0eff6be0a0 feat(parser): error JSX-like type assertions and generics in .mts/.cts (#18910)
## Summary

Implements TS7059 and TS7060 errors for JSX-like syntax in `.mts`/`.cts` files:

- **TS7059**: JSX-like type assertions (`<T>value`) - "Use an `as` expression instead"
- **TS7060**: JSX-like type parameters in arrow functions (`<T>() => {}`) - "Add a trailing comma or explicit constraint"

### Valid workarounds for TS7060:
- `<T,>() => {}` (trailing comma)
- `<T extends unknown>() => {}` (explicit constraint)
- `<T, U>() => {}` (multiple type parameters)

Closes #15184

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-04 05:21:42 +00:00
Boshen e7e72e27df fix(transform_conformance): skip tests that expect parser errors (#18914)
## Summary

- Skip tests in transform conformance that expect parser errors
- Parser errors are already tested by parser conformance tests
- Transform conformance should only test transformation logic

When a test has a `throws` option, we now try parsing the input first. If parsing fails, the test is skipped since it's a parser error test (not a transformer error test).

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-02-04 03:41:29 +00:00
Boshen 333d4fb167 chore(submodules): update submodule SHAs to latest commits (#18841)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `fff41f0` → `dd6138f`
- babel: `6ef16ca` → `92c052d`
- TypeScript: `7f6a846` → `95e3aaa`
- estree-conformance: `389cb2a` → `6611520`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-02-03 04:30:00 +00:00
sapphi-red 3d01fa1219 docs(transformer): update links to use Oxc docs (#18722)
Updated the links to Oxc docs instead of babel and esbuild.
2026-02-01 15:21:18 +00:00
Boshen b225b29cc1 chore(submodules): update submodule SHAs to latest commits (#18334)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `6f55d0c` → `fff41f0`
- babel: `fc58af4` → `6ef16ca`
- TypeScript: `f5ccf43` → `7f6a846`
- estree-conformance: `4980d9b` → `389cb2a`

This PR is automatically generated by the [update_submodules workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).
2026-01-22 16:13:31 +00:00
Dunqing 30a4899dd8 feat(oxc)!: remove CompilerInterface::semantic_child_scope_ids (#18361)
No usage in the Oxc and Rolldown (see https://github.com/rolldown/rolldown/pull/7995), and it will be removed in #18362, so remove this first.
2026-01-22 07:46:26 +00:00
Boshen 8687b0959f chore(submodules): update submodule SHAs to latest commits (#17978)
Updates submodule dependencies to their latest commits.

## Changes

- test262: `9079aee` → `6f55d0c`
- babel: `761c250` → `fc58af4`
- TypeScript: `f3770c9` → `f5ccf43`
- estree-conformance: `87a8e99` → `4980d9b`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2026-01-14 15:13:29 +08:00
Boshen 0c4e9cf50d chore(submodules): update submodule SHAs to latest commits (#17456)
Updates submodule dependencies to their latest commits.

## Changes

- babel: `cbdc42f` → `761c250`
- TypeScript: `2dfdbba` → `f3770c9`
- estree-conformance: `2e7394c` → `87a8e99`


This PR is automatically generated by the [update_submodules
workflow](https://github.com/oxc-project/oxc/blob/main/.github/workflows/update_submodules.yml).

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-12-29 19:57:32 +08:00