Standardize React Compiler diagnostics with concise titles, primary labels, actionable help, notes, structured categories, and official guidance links.
Preserve React guidance when diagnostics are surfaced through Oxlint, and refresh affected snapshots.
AI-assisted; reviewed and validated by the contributor.
Centralizes React compiler diagnostics in explicit `#[cold]` functions and removes the `[ReactCompiler]` prefix, keeping diagnostic formatting off hot paths. Updates related NAPI expectations.
AI assistance was used.
Align ref validation with Babel React Compiler 1.0 by limiting call-site alias-effect checks to values actually passed to the call. This keeps refs captured by returned event handlers valid while preserving diagnostics for refs passed to invoked functions.
Validated with `cargo test -p oxc_react_compiler`, the rebuilt `oxc-transform-react` binding against Outline’s `ContentEditable.tsx`, and `just ready`.
AI-assisted; the contributor remains responsible for review and submission.
Disable exhaustive memo dependency validation by default and align
suppression handling.
AI-assisted.
<sub>Stack created with <a
href="https://github.com/github/gh-stack">GitHub Stacks CLI</a> • <a
href="https://gh.io/stacks-feedback">Give Feedback 💬</a></sub>
Preserve warning-level React Compiler diagnostics instead of wrapping pipeline bailouts in a synthetic fatal error. This keeps expected incompatible-library and Todo bailouts non-fatal so sibling functions can still compile.
Adds regression coverage and refreshes the affected snapshots. Validated with `just ready`.
AI-assisted: Codex was used to investigate, implement, and validate this change.
Splits `oxc_react_compiler`'s public API into two phases so the transform rewrites the caller's program in place instead of returning a whole-program clone:
- `compile(&Program, &Semantic, &Allocator, PluginOptions) -> (Option<CompileOutput>, Diagnostics)` — read-only; `None` means no changes (or error / lint output mode).
- `CompileOutput::transform(self, &mut Program, &Allocator)` — substitutes the compiled functions into the program in place. `CompileOutput` owns only arena data (replacements + `ProgramContext`), so the caller drops its `Semantic` between the two calls, releasing the shared borrow that previously forced `ox_splice_program` to `clone_in_with_semantic_ids` the entire program.
- `lint` is unchanged and structurally never runs the transform phase; the oxlint rule needed no changes.
The old `transform` free function and `TransformResult` are removed; `oxc_transformer` no longer does the `*program = result.program.take()` swap and just applies the output to its `&mut Program`.
The 1806-fixture snapshot corpus is byte-identical, and the transform path drops one whole-program clone per compiled file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
## What
Simplify the post-compile comment cleanup in `oxc_react_compiler`.
The output program is built by cloning the source (`ox_splice_program` → `program.clone_in()`), and `CloneIn` for `Program` copies both `comments` and `source_text`. So the compiled program already carries every original comment and the correct `source_text` before the cleanup step runs.
The old `preserve_comments` re-derived that from scratch:
- allocated a second `ArenaVec` and re-filtered `source.comments` into it, then
- re-assigned an already-correct `source_text`,
which forced it to take `source: &Program` and `allocator` params it didn't need.
## Change
Filter the already-cloned `compiled.comments` in place with `retain`, dropping the extra allocation, the redundant `source_text` write, and both params. Renamed to `prune_inner_comments`, and corrected the doc comments — the old ones claimed the roundtrip *drops* comments, when it actually clones them and this step prunes only the ones anchored inside rewritten functions (whose spans no longer resolve).
## Verification
Output is unchanged: the fixture snapshot suite passes byte-identical (no `.snap` updates) and all 15 unit tests pass. `cargo clippy -p oxc_react_compiler --all-targets` is clean.
Removes unused upstream JS option fields from Oxc's React Compiler options and deletes the dead filename plumbing they carried through the compile environment.
Stacked on #24063.
AI-assisted.
Borrow existing semantic data and caller allocator in React Compiler transform/lint paths to avoid hidden rebuild/allocation work.
Transform now returns the compiled program so callers can install it after the semantic borrow ends.
AI-assisted.
Slims down `oxc_react_compiler`'s `PluginOptions` and removes the now-dead timing infrastructure. Four related cleanups:
### Remove `source_code` from `PluginOptions`
It was redundant — `compile` in `lib.rs` always overwrote it with `program.source_text`, and no caller set it. The one consumer (`ProgramContext::new` in `program.rs`) now reads `program.source_text` directly (the oxc `Program` is already in scope there), and the threading block in `lib.rs` is gone.
### `default_plugin_options()` → `impl Default for PluginOptions`
Converted the free function into a manual `Default` impl (the defaults are non-trivial: `should_compile: true`, `target: "19"`, `flow_suppressions: true`, …). All callers now use `PluginOptions::default()`.
### Remove `profiling`
The field was always `false` in practice (no caller set it). Its sole consumer now passes `TimingData::new(false)` — which leads into…
### Remove the timing instrumentation entirely
With `profiling` gone, timing was pure, always-disabled instrumentation: every `context.timing.start/stop` was a no-op and the collected `Vec<TimingEntry>` was always empty and never read (`lib.rs` destructures `CompileResult` with `..`). Removed:
- `timing.rs` (the `TimingData`/`TimingEntry` module) and its `mod` declaration
- ~218 `context.timing.start/stop(...)` calls across `pipeline.rs`
- the `timing` field on `ProgramContext` and on both `CompileResult` variants, plus all initializers
### Verification
- `oxc_react_compiler`: builds, 15/15 tests pass.
- `oxc_linter`: `react_compiler` rule snapshot test passes — **snapshot unchanged** (diagnostics identical).
- `oxc_transformer` react_compiler integration: 2/2 pass; `oxc_benchmark` bench compiles.
- rustc warnings, clippy (`dev-no-debug-assertions`), and `cargo shear` all clean.
Remove the `transform_source` and `lint_source` convenience wrappers from `oxc_react_compiler`'s public API.
- `lint_source` had no callers anywhere in the workspace.
- `transform_source` (parse-then-`transform`) was only used by the crate's own integration tests, so it moves into `tests/transform.rs` as a private helper — the 17 call sites are unchanged.
- Dropped the now-unused `oxc_parser::Parser` import in `lib.rs` and narrowed `oxc_span::{GetSpan, SourceType}` to `GetSpan`.
`transform`, `lint`, and `LintResult` are kept — they remain in use by the benchmark/example (`transform`) and the `react/react_compiler` linter rule (`lint`).
## Summary
Follow-up to #24009 (de-Babel). Now that `oxc_react_compiler` speaks the
oxc AST natively, this tidies its test + dependency layout:
- **Move the 15 end-to-end tests to `tests/transform.rs` as integration
tests** — they exercise the crate through its public `transform_source`
API instead of `#[cfg(test)]` modules inside `lib.rs`.
- **Remove the internal unit tests** (function discovery, `JsString`,
HIR `Environment`, codegen hashing, prefilter) — the crate is covered
through its public API.
- **Move `oxc_codegen` to `[dev-dependencies]`** — the library builds
the oxc AST but never codegens it; only the example and integration
tests print the program.
Net −397 lines.
## Verification
- `cargo test -p oxc_react_compiler`: 15 integration tests pass, 0 unit.
- Differential over the 1,805 upstream React Compiler fixtures:
byte-identical (`same=1805 diff=0`).
- clippy `-D warnings`, `cargo fmt --check`, `typos`, `cargo shear`:
clean. Example builds.
---
Produced with AI assistance (Claude Code); verified byte-identical
against the 1,805-fixture differential and the crate's tests.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>