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.
Summary:
- Upgrade oxc_sourcemap to 8.0.1.
- Return borrowed SourceMap from CodegenReturn.
- Support no-sourcemap feature builds used by benchmarks.
AI-assisted: yes
## Summary
Introduces `oxc_diagnostics::Diagnostics` — a `Vec<OxcDiagnostic>` newtype that knows the difference between errors and warnings — and makes it the standard diagnostics return value across oxc.
- **New type**: `Diagnostics` with `has_errors()`, `has_warnings()`, `errors()`, `warnings()`, plus `Vec`-like ergonomics (Deref, `IntoIterator`, `Extend`, `From`/`Into<Vec>`) so most call sites are unchanged.
- **Return types**: `ParserReturn`, `SemanticBuilderReturn`, `IsolatedDeclarationsReturn`, the React Compiler `TransformResult`/`LintResult`, and `TransformerReturn` now expose `diagnostics: Diagnostics` instead of `errors: Vec<OxcDiagnostic>` (the React Compiler's separate `errors`/`warnings` are merged into one severity-tagged list).
- **Behaviour**: a React Compiler **error** now stops the transform (no output), while **warnings** flow through and the transform continues. `compile()` aborts codegen only when `diagnostics.has_errors()` — warnings alone no longer abort (previously any diagnostic did).
## Breaking change
Consumers reading `*.errors` on these return values must read `*.diagnostics`. React Compiler consumers that read `.errors`/`.warnings` separately should use `diagnostics.has_errors()` / `diagnostics.errors()` / `diagnostics.warnings()`.
Parser/semantic/isolated-declarations fatality is otherwise unchanged. Builds on the React Compiler transform feature (#23201).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Fixes#20654
The JSX source and self plugins were erroneously reporting "Duplicate `__source` prop found" / "Duplicate `__self` prop found" warnings when a user wrote `<div __source={{}} />` or `<div __self={this} />`. This prevented valid code from being transformed.
In Babel, the duplicate error only exists to warn users who have both the automatic runtime AND the deprecated standalone plugins enabled simultaneously ([source](https://github.com/babel/babel/blob/9137617716e200cb440948562789ae3744559fcb/packages/babel-plugin-transform-react-jsx/src/create-plugin.ts#L847-L853)). It's not relevant for oxc as a standalone transformer.
Now the plugins silently skip adding `__source`/`__self` when the user has already provided one, matching the behavior of Babel's standalone plugins.
## 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)
## Summary
Improves the `print_diff_in_terminal` function with better readability and a simpler API:
**API Changes:**
- `print_diff_in_terminal(expected, result)` - Simple API that takes two strings
- `print_text_diff(diff)` - For when you already have a `TextDiff` (e.g., to use `diff.ratio()`)
**Features:**
- Show 3 lines of context above and below each change
- Add line numbers with gutter separator (`│`)
- Add blank line between adjacent hunks for visual separation
- Add `...` separator when lines are skipped between hunks
- Use single-pass streaming algorithm with small fixed-size buffer
- Colors: red (`-`) for deletions, green (`+`) for insertions, dim for context
**Formatter Example:**
- Added `--diff` flag to show diff between original and formatted code
Example output:
```
1 │class A {
2 │ #x;
3 │}
- 4 │var _x = /* @__PURE__ */ new WeakMap();
- 5 │var _B_brand = /* @__PURE__ */ new WeakSet();
4 │class B {
- 7 │ constructor() {
- 8 │ babelHelpers.classPrivateMethodInitSpec(this, _B_brand);
- 9 │ babelHelpers.classPrivateFieldInitSpec(this, _x, void 0);
+ 5 │ #x;
+ 6 │ #y() {
+ 7 │ this.#x;
8 │ }
- 11 │}
- 12 │function _y() {
- 13 │ babelHelpers.classPrivateFieldGet2(_x, this);
9 │}
```
## Test plan
- [x] `cargo check -p oxc_tasks_common` passes
- [x] Clippy passes
- [x] Verified output with `just test-transform --filter "plugins-integration/class-features-node-12/input.js"`
🤖 Generated with [Claude Code](https://claude.ai/code)
Implement a transformation plugin for tagged template expressions containing </script> tags to prevent script tag issues in browser environments.
This plugin transforms tagged template literals containing `</script` (case-insensitive) to use a helper function call with template caching, matching esbuild's behavior.
### Example
Transforms tagged templates to use cached template objects with a helper function:
Input:
```js
foo`</script>`
bar`<script>${content}</script>`
```
Output:
```js
var _templateObject, _templateObject2;
foo(_templateObject || (_templateObject = babelHelpers.taggedTemplateLiteral(["<\/script>"])));
bar(_templateObject2 || (_templateObject2 = babelHelpers.taggedTemplateLiteral(["<script>", "<\/script>"])), content);
```
Closes#15306
✅ **Implementation Complete: ES2020 Export Namespace From
Transformation**
Successfully implemented the transformation for `export * as ns from
"mod"` to convert it to:
```js
import * as _ns from "mod";
export { _ns as ns };
```
## Changes Made:
- [x] Core transformation in `es2020/export_namespace_from.rs`
- [x] ES2020 module integration and options
- [x] Browser compatibility mapping in `oxc_compat` (auto-generated from
custom compat data)
- [x] Babel plugin support (`transform-export-namespace-from`)
- [x] Target-based transformation (works with old browsers, skips modern
ones)
- [x] Code optimizations (removed clones, reserved capacity, used vec1)
- [x] Custom compat data infrastructure for features not in compat-table
- [x] Early return optimization to avoid unnecessary allocations
- [x] Implemented `GatherNodeParts` for `ModuleExportName` to avoid
string allocations
- [x] All tests passing ✅
## Code Review Addressed:
- Reserved capacity for statements vector
- Removed unnecessary clones via destructuring
- Used `ctx.ast.vec1()` for single-element vectors
- Created custom compat data system to avoid manual edits
- Imported `TransformCtx` directly
- Added early return when no export namespace declarations exist
- Implemented `GatherNodeParts` for `ModuleExportName` and use
`generate_uid_based_on_node`
## Example:
**Input:**
```js
export * as ns from "mod";
```
**Output:**
```js
import * as _ns from 'mod';
export { _ns as ns };
```
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>transformer: transform `export * as ns from "mod";` to
`import * as ns from "mod"; export { ns }`</issue_title>
> <issue_description>This transformation is supported by babel:
https://babeljs.io/docs/babel-plugin-transform-export-namespace-from
> ```js
> export * as ns from "mod";
>
> // to
>
> import * as _ns from "mod";
> export { _ns as ns };
> ```</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
Fixesoxc-project/oxc#14257
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/oxc-project/oxc/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Signed-off-by: Dunqing <dengqing0821@gmail.com>
Co-authored-by: sapphi-red <49056869+sapphi-red@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Dunqing <29533304+Dunqing@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Dunqing <dengqing0821@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Summary
- Closesoxc-project/backlog#150
- Replaces manual tab-to-space replacement hack with native indentation configuration
## Changes
- Configure `Driver::codegen_options()` to use spaces with width 2
- Configure `TestCase` Codegen instance to use spaces with width 2
- Remove three instances of `cow_replace("\t", " ")` hack
- Add `IndentChar` imports where needed
## Context
The `CodegenOptions` struct already had `indent_char` and `indent_width` fields available. This change leverages existing infrastructure to provide cleaner, more maintainable code instead of post-processing the output with string replacement.
This addresses the issue mentioned in oxc-project/backlog#150 where transformer conformance output was replacing tabs with spaces as a workaround.
🤖 Generated with [Claude Code](https://claude.ai/code)
We can now use `if let` chains. Previously we had to use an early return pattern in some places because one branch had multiple nested `if` statements. Now that they're combined into a single `if`, we don't need to use this pattern any more, and can convert to `if` / `else`. Usually this is shorter, but even when it's not, in my opinion it's a bit clearer.
close: #11876
This plugin adds comprehensive support for styled-components with server-side rendering, style minification, and enhanced debugging capabilities. The implementation is ported from the [official Babel plugin](https://github.com/styled-components/babel-plugin-styled-components) to ensure compatibility and feature parity.
## Current Limitations
⚠️ **Import Support**: This plugin currently only supports styled-components imported via ES modules (`import` statements). CommonJS imports using `require("styled-components")` are not yet supported.
## Feature Support
### Options:
**✅ Fully Supported:**
- `displayName`: Adds display names for debugging
- `fileName`: Controls filename prefixing in display names
- `ssr`: Adds unique component IDs for server-side rendering
- `transpileTemplateLiterals`: Converts template literals to function calls
- `minify`: Minifies CSS content in template literals
- `namespace`: Adds namespace prefixes to component IDs
- `meaninglessFileNames`: Controls which filenames are considered meaningless
**⚠️ Partially Supported:**
- `pure`: Only supports call expressions, not tagged template expressions (bundler limitation)
**❌ Not Yet Implemented:**
- `cssProp`: JSX css prop transformation
- `topLevelImportPaths`: Custom import path handling
## Testing
The test suite is adapted from the [official Babel plugin tests](https://github.com/styled-components/babel-plugin-styled-components) with modifications to integrate with our testing infrastructure.
**Note**: Some test outputs differ from the original due to our different hashing algorithm for component IDs. This is intentional and follows the same approach used by SWC's implementation.
Control printing of comments more precisely via more options:
The logic change here is that jsdoc is no longer part of annotation
comments.
```rust
pub struct CommentOptions {
/// Print normal comments that do not have special meanings.
///
/// At present only statement level comments are printed.
///
/// Default is `true`.
pub normal: bool,
/// Print jsdoc comments.
///
/// * jsdoc: `/** jsdoc */`
///
/// Default is `true`.
pub jsdoc: bool,
/// Print annotation comments.
///
/// * pure: `/* #__PURE__ */` and `/* #__NO_SIDE_EFFECTS__ */`
/// * webpack: `/* webpackChunkName */`
/// * vite: `/* @vite-ignore */`
/// * coverage: `v8 ignore`, `c8 ignore`, `node:coverage`, `istanbul ignore`
///
/// Default is `true`.
pub annotation: bool,
/// Print legal comments.
///
/// * starts with `//!` or `/*!`.
/// * contains `/* @license */` or `/* @preserve */`
///
/// Default is [LegalComment::Inline].
pub legal: LegalComment,
}
```
closes#12030
related https://github.com/rolldown/tsdown/issues/357
closes#11020
Previously `SourceType::from_path(".js")` treats a `.js` file as `.jsx`
to maximize parse rate for the linter.
Force the `.jsx` change in the linter instead of a generic solution for
`SourceType::from_path`.
fixes#10948
This PR changes how comment options are interpreted.
`CodegenOptions::comments`, `CodegenOptions::annotation_comments` and
`CodegenOptions::legal_comments` are now independent of each other.
### `CodegenOptions::comments`
Controls printing of normal comments. At present, only some leading
comments are preserved. It does not control legal and annotation
comments.
### `CodegenOptions::annotation_comments`
Controls printing of annotation comments
* jsdoc: `/** jsdoc */`
* pure: `/* #__PURE__ */` and `/* #__NO_SIDE_EFFECTS__ */`
* webpack: `/* webpackChunkName */`
* vite: `/* @vite-ignore */`
* coverage: `v8 ignore`, `c8 ignore`, `node:coverage`, `istanbul ignore`
### `CodegenOptions::legal_comments`
Controls printing of legal comments
* starts with `//!` or `/*!`.
* contains `/* @license */` or `/* @preserve */`
---
Comment generation is also changed:
codegen first builds a comments map by keeping only the needed comments.
Printing functions will then print out comments in their respective
positions.
---
This PR reveals some incorrect comment interpretation:
* https://github.com/oxc-project/oxc/issues/10998
Before, we could only override the failed tests, now we support `--override` for the passed tests. This is useful for fixing the Babel itself bugs/misalignments. See #10538 and #10491
#10196 replaced the anti-pattern of `str.push_str(&format!("..."));` with `let _ = write!(str, "...");`.
However, this ignores the `Result` returned by `write!` macro. It's unspecified what happens when the `String` reaches capacity - it may return `Result::Err`, or may panic. Ensure we get a panic, rather than silently generating incorrect output by calling `unwrap()` on the `Result`.
This problem could never arise in practice on 64-bit systems because max capacity of `String` is enormous, but it's not impossible on 32-bit systems (e.g. WASM).
~~wanted to have a shot at implementing this, this is rough draft.~~
~~Dunqing or overlookmotel feel free to take over or close out this PR. not sure how much time i'll have to finish it off~~
@Dunqing @overlookmotel this should be ready when you guys have time 🙏closes#9168
Replace `#[allow]` with `#[expect]` through the whole codebase.
This also surfaced many places where the `#[allow]` attributes were outdated/pointless and could be removed entirely.
Only places `#[allow]` remains are:
1. In generated code and macros, where lint errors may or may not be triggered depending on the generated code.
2. A few places where clippy malfunctions. These use e.g. `#[allow(unused, clippy::allow_attributes)]`.
Previously, #8634 visualized each spec result, but this was not enough.
If the implementation has been updated but the spec still fails, there
is no way to know if there is an improvement or not.
This time, finally, all progress is visualized! 🤩

e.g. here `arrow_function_expression` is mostly passing, except for
comment handling.
Pure refactor. Re-order imports for clarity:
1. `std`
2. External crates
3. `oxc_*` crates
4. Current crate `use crate::...`
5. Super `use super::...`
6. Local modules
This order is from "furthest away" to "closest". This makes it clearer to see what is coming from where.
`cargo +nightly fmt` (#7877) did a lot of the work, but unfortunately `rustfmt` does not have an option to (a) put workspace crates in a separate block from external crates and (b) move `mod` statements to after `use` statements.
When running `just test-transform --override`, generate override files with indentation as double spaces, instead of tabs. This matches our convention for formatting JS files.
We should move the handling of `<CWD>` to the test runner because this is just only used in testing, and it causes us always get a path by `self.ctx.source_path` like `<CWD>/xxx/xxx.js`, we should get a real path for this.
The `--override` flag used to write the output which is generated by the transformer to the `overrides` folder according to the test path. The acting is similar to the previous `takeover` mode
This PR does the following things.
1. Move the override output of the `snapshots` folder to the `overrides` folder.
2. Support `override` mode to replace `takeover` mode
3. The `update_fixtures.js` no longer uses `overrides`'s `output.js` to replace Babel's `output.js`.
### How does `override` mode work?
When running each test, it checks whether an output file for that test exists in the `overrides` directory. If it does, the output file will be used to compare with the transformed code.
In "takeover" mode, transformer conformance test runner was using `HelperLoaderMode::Runtime`. Switch this to `HelperLoaderMode::External` to match standard test runner mode.