Commit Graph

62 Commits

Author SHA1 Message Date
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
Boshen 030857b509 refactor(diagnostics): update oxc-miette to v4 (#25395)
Remove the miette `Report` wrapper and update oxc-miette to v4's narrowed diagnostic and source protocol.

AI-assisted by OpenAI Codex.
2026-08-10 07:48:02 +00:00
Boshen cef9143aed refactor(transformer,minifier,react_compiler): switch JS-only visitors from Visit to VisitJs (#24532)
Migrate the transform-pipeline `Visit` implementors to `VisitJs` (#24499): `oxc_transformer` (3), `oxc_minifier` (4), `oxc_react_compiler` (1), plus the parser regex example and the coverage driver. Part of #24317; linter half in #24530. Behavior is unchanged.

Together with #24530: `oxlint` −129.4 KiB (−0.94%) stripped, `oxc_transform` napi −16.2 KiB (−0.46%).

## Why each visitor can switch

A visitor is safe on `VisitJs` when its hooks cannot observe anything inside the pruned type grammar — either the hooked node kinds are value-space-only, or the AST it walks cannot contain type nodes at that pipeline stage.

| Visitor | File | Why equivalent |
|---|---|---|
| `PrivateInExpressionDetector` | `crates/oxc_transformer/src/decorator/legacy/mod.rs` | Hooks `visit_private_in_expression` (+`visit_decorators`); `#x in y` is runtime-only and cannot occur in type grammar, even inside decorator expressions carrying casts. |
| `BindingMover` | `crates/oxc_transformer/src/es2017/async_to_generator.rs` | Its formal-parameter overrides visit only pattern + initializer (`BindingPattern` carries no type field — annotations are sibling fields it never touches); runs in the exit phase after TS strip. |
| `UsedInJSXBindingsCollector` | `crates/oxc_transformer/src/jsx/refresh.rs` | Runs on un-stripped TSX, but its hooks (JSX-shaped calls, `visit_jsx_opening_element`, declarations/imports) cannot fire inside type grammar; its hand-written `visit_ts_type_annotation` skip-stub is deleted — `VisitJs` prunes that natively. |
| `Finder` | `crates/oxc_react_compiler/src/react_compiler/entrypoint/program.rs` | Matches functions by `scope_id`; real JS function scopes never live in pure type grammar, and `VisitJs` still walks the places one could hide (enum initializers, namespace bodies, cast inner expressions). |
| `KeepVar` | `crates/oxc_minifier/src/keep_var.rs` | Hooks `visit_statement`/`visit_variable_declaration`; statements and `var` declarations don't exist in type space, and namespace/enum bodies (which can contain them) are still walked by `VisitJs`. |
| `DirectEvalFlagCheck` | `crates/oxc_minifier/src/peephole/mod.rs` | Debug-only; hooks `visit_call_expression` only — call expressions cannot occur in valid type grammar. |
| `LiveDirectEvalCollector` | `crates/oxc_minifier/src/peephole/mod.rs` | Same single call-expression hook; type-space-immune regardless of input. |
| `TestVisitor` | `crates/oxc_minifier/tests/ecmascript/prop_name.rs` | Test helper parsing `SourceType::default()` (plain JS); single non-recursing `visit_object_expression` hook. |
| `RegularExpressionVisitor` | `crates/oxc_parser/examples/regular_expression.rs` | Finds `RegExpLiteral` / `new RegExp(...)`; neither node kind can occur in type grammar. |
| `CheckASTNodes` | `tasks/coverage/src/driver.rs` | Its only active override is `visit_reg_exp_literal` (regex print idempotency); `RegExpLiteral` cannot occur in type space. (The commented-out `visit_span` full-AST check would need `Visit` if ever revived.) |

Left on `Visit`: the minifier's incremental-scoping bookkeeping (`DropDiff`, `OverPruneCheck`, `LiveRefCollector`) — dropping `let x: Foo = …` must unmark the type-space `Foo` reference, which the `peephole::remove_unused_declaration` tests verify (they fail under `VisitJs`; confirmed and reverted during this work). `ChildScopeCollector` also stays: TS type nodes (mapped/conditional/function types) carry real `scope_id`s it must collect.

---

🤖 This PR was written with the assistance of Claude Code (Claude Fable 5).
2026-07-15 08:08:18 +00:00
overlookmotel 7a76cd3dc3 feat(estree)!: make whether to include TS fields a runtime option (#23574)
Previously, whether to serialize AST to ESTree JSON with/without TS fields was a compile-time option - via 2 different configs `CompactTSSerializer` and `CompactJSSerializer` (and their pretty-printing and with-fixes counterparts).

Turn this into a runtime option instead -

This make serialization a little slower (more branches in either mode, and dead code in JS-only mode) but reduces the size of `oxc-parser` binary as only one `ESTreeSerializer` is generated, instead of 2 (JS-only, and with-TS).
2026-06-17 23:22:37 +00:00
Boshen 777f02ae10 refactor(diagnostics)!: return a Diagnostics type instead of Vec<OxcDiagnostic> (#23217)
## 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)
2026-06-10 14:46:52 +00:00
renovate 611b3b69ef chore(deps): update dependency rust to v1.95.0 (#21509)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.94.1` → `1.95.0` |

---

### Release Notes

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

### [`v1.95.0`](https://redirect.github.com/rust-lang/rust/compare/1.94.1...1.95.0)

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

</details>

---

### Configuration

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

- Branch creation
  - At any time (no schedule defined)
- Automerge
  - At any time (no schedule defined)

🚦 **Automerge**: Enabled.

♻ **Rebasing**: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR was generated by [Mend Renovate](https://mend.io/renovate/). View the [repository job log](https://developer.mend.io/github/oxc-project/oxc).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMjMuOCIsInVwZGF0ZWRJblZlciI6IjQzLjEyMy44IiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
2026-04-17 14:43:16 +00:00
Copilot 2bf9347a60 chore(rust): Fix needless_doctest_main lint by updating parser_tsx example (#12996) 2025-08-12 00:49:59 +08:00
Copilot 514322c4c3 docs(rust): Add minimal documentation to example files in crates directory (#12731) 2025-08-02 22:02:20 +08:00
Bacary Bruno Bodian 9a2548ae9d feat(napi/parser)!: add range option (#11728)
Part of #10307. Add `range` option to `oxc-parser`, to add `range` property to nodes in ESTree AST.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
2025-06-24 02:23:27 +01:00
Boshen be3bd8ce22 fix(parser): fix panic while parsing async await => {} in module (#11493)
fixes #11487
2025-06-05 05:01:20 +00:00
Boshen 635aa96219 fix(napi): computed final source type from lang then sourceType (#11060)
closes #10980

Previously final source type was only computed when `lang` is not set.

It is changed to:

* compute source type from `lang`, use filename extension if `lang` is
not set
* reset the computed source type with 'script` or `module` if provided
2025-05-15 21:41:42 +08:00
Boshen e228840a41 feat(parser): fast forward lexer to EOF if errors are encountered (#10579)
This PR prepares for the next optimization: removal of `Result<T>`.
2025-04-24 14:28:31 +00:00
overlookmotel ac23773615 docs(parser): update parser example (#10468)
Our Rust AST, ESTree AST, and TS-ESTree ASTs are increasingly diverging from each other. It's useful to be able to view any of them.

Alter `oxc_parser` example so that:

* `--ast` prints the Rust AST.
* `--estree` prints ESTree AST or TS-ESTree AST, depending on source type.
2025-04-17 11:44:48 +00:00
Boshen a5cde10ecc feat(visit_ast)!: add oxc_visit_ast crate (#9428)
closes #9384
2025-02-28 08:03:54 +00:00
overlookmotel 61939ca501 perf(ast/estree): faster UTF-8 to UTF-16 span conversion (#9349)
Speed up UTF-8 to UTF-16 `Span` conversion by processing span offsets in ascending order.

This involves, for each node, processing `span.start`, then visiting all children and processing their `Span`s, and then finally processing `span.end`.

When the AST has come direct from the parser, this means all offsets are processed 100% in ascending order (and the visitor used here has manually-written visitation methods for the few types where that's not always the case otherwise e.g. `export {x}`).

If the AST *has* been modified, code may have moved around, so ascending order won't necessarily be preserved, but still it *mostly* will.

Optimize for this visitation order. Instead of doing a binary search through the whole UTF8-UTF16 translation table on every single span offset, assume the current offset is in same region as the last. Only resort to binary search as a de-opt when that's not the case. Most JS/TS files don't contain many non-ASCII characters, so these cases will be rare.
2025-02-26 02:11:13 +00:00
Boshen 1d81adac48 Rust Edition 2024 (#9289)
closes #9271

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-22 11:56:25 +08:00
overlookmotel b09249c3bc refactor(ast/estree): rename serializers and serialization methods (#9284)
Pure refactor. Rename:

* `Program::to_json` to `to_estree_ts_json`.
* `Program::to_pretty_json` to `to_pretty_estree_ts_json`.

This is preparatory work for #9285, which adds `*_js_*` variants of these 2 methods, which omit TypeScript fields.

Also rename the serializers, to include `TS` in their names, for the same reason.
2025-02-22 02:22:15 +00:00
overlookmotel 216b33fd2a feat(ast/estree)!: replace serde with custom ESTree serializer (#9256)
Replace `serde` with a custom serializer specialized for writing JSON.

`impl Serialize` -> `impl ESTree`. I've called it `ESTree` in case we
want to add e.g. `impl Babel` later on.

The main motivation is that with control of the serializer, we can make
it stateful, so we can extend it to, for example, omit TS fields based
on a flag. This is pretty much impossible with `serde`'s interface.

But a side-effect of the simpler implementation is that it's also more
performant.

The usage of `ESTree` trait is very similar to `serde::Serialize`. Main
differences:

* `serialize` method is infallible. Does not return a `Result`.
* `state = serializer.serialize_struct();` instead of `map =
serializer.serialize_map();`.
* `state.serialize_field(...)` instead of `map.serialize_entry(...)`.
* Struct keys must be strings, and JSON-safe (not including `"` or other
characters that require escaping in JSON).

This is a breaking change, as it's possible downstream consumers are
using `serde` to serialize our AST to other formats. I'd guess unlikely,
but possible. We can always implement `serde::Serialize` as well as
`ESTree` further down the line if there's a demand.
2025-02-21 12:20:26 +08:00
overlookmotel a4a8e7deda style(all): replace #[allow] with #[expect] (#8930)
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)]`.
2025-02-07 14:50:02 +00:00
Boshen b7f13e636e feat(ast): implement utf8 to utf16 span converter (#8687)
closes #8629
2025-01-24 16:57:44 +00:00
overlookmotel 2857ae15cd refactor(parser): refactor visitor in regexp example (#8524)
Refactor visitor in example to use `visit_*` methods instead of `enter_node`. This is our recommended style as it's more performant.
2025-01-16 02:40:29 +00:00
Boshen 666b6c104c fix(parser): add missing ChainExpression in optional TSInstantiationExpression (#7371) 2024-11-20 11:51:55 +00:00
Boshen d1d187417b feat(ast)!: change comment.span to real position that contain // and /* (#7154)
closes #7150
2024-11-06 05:10:33 +00:00
leaysgur 8032813bf8 fix(regular_expression)!: Migrate to new regexp parser API (#6741)
Follow up #6635

- [x] Remove old APIs
- [x] Update linter usage
- [x] Update parser usage
- [x] Update transformer usage
2024-10-22 05:34:18 +00:00
Boshen 520096030a refactor(oxc)!: remove passing Trivias around (#6446)
part of #6426
2024-10-11 06:09:25 +00:00
leaysgur 5a73a663dc refactor(regular_expression)!: Simplify public APIs (#6262)
This PR makes 2 changes to improve the existing API that are not very useful.

- Remove `(Literal)Parser` and `FlagsParser` and their ASTs
- Add `with_flags(flags_text)` helper to `ParserOptions`

Here are the details.

> Remove `(Literal)Parser` and `FlagsParser` and their ASTs

Previously, the `oxc_regular_expression` crate exposed 3 parsers.

- `(Literal)Parser`: assumes `/pattern/flags` format
- `PatternParser`: assumes `pattern` part only
- `FlagsParser`: assumes `flags` part only

However, it turns out that in actual usecases, only the `PatternParser` is actually sufficient, as the pattern and flags are validated and sliced in advance on the `oxc_parser` side.

The current usecase for `(Literal)Parser` is mostly for internal testing.

There were also some misuses of `(Literal)Parser` that restore `format!("/{pattern}/{flags}")` back and use `(Literal)Parser`.

Therefore, only `PatternParser` is now published, and unnecessary ASTs have been removed.
(This also obsoletes #5592 .)

> Added `with_flags(flags_text)` helper to `ParserOptions`

Strictly speaking, there was a subtle difference between the "flag" strings that users were aware of and the "mode" recognised by the parser.

Therefore, it was a common mistake to forget to enable `unicode_mode` when using the `v` flag.

With this helper, crate users no longer need to distinguish between flags and modes.
2024-10-03 02:47:08 +00:00
DonIsaac 3120c6c5ba docs(parser): add module and struct level documentation (#5831) 2024-09-18 06:27:24 +00:00
Boshen 4abfa7682a refactor(parser): add --ast and --comments to example 2024-09-14 09:02:23 +08:00
Boshen e8bf30a125 feat(ast): add Comment::real_span (#5764) 2024-09-13 15:28:34 +00:00
rzvxa 59abf27d95 feat(ast, parser): add oxc_regular_expression types to the parser and AST. (#5256)
closes #5060
2024-09-03 02:36:37 +00:00
Boshen 5e27798dc3 chore(parser): parse regular expression in example 2024-08-28 19:32:44 +08:00
Boshen dd3ad4d68e chore(regular_expression): remove circular dependency
Error: Circular dependency detected: oxc_parser -> oxc_regular_expression
2024-08-23 16:16:10 +08:00
Boshen 4c989d0fda chore(parser): remove multi-thread example
because `ouroboros` has a few heavy dependencies, including an older
version of itertools.
2024-08-16 22:57:10 +08:00
overlookmotel 2c7bb9f6c8 refactor(ast): pass final ScopeFlags into visit_function (#4283)
We have a strange workaround for `visit_function` where we pass in `ScopeFlags`, to support creating the scope inside `Function`, but setting different flags for `MethodDefinition`s.

Previously `visit_function` took `Option<ScopeFlags>` and then did `flags.unwrap_or(ScopeFlags::empty()) | ScopeFlags::Function` to it. Personally, I found this confusing. When I was looking at `MethodDefinition`, I was wondering "It's a function, why doesn't it set Function flag too?"

This changes makes it more explicit and clear what `ScopeFlags` everything has.
2024-07-16 07:22:07 +00:00
Boshen a71787572e chore: remove unsafe_code = "warn" rust lint
Feels too verbose as we already have unsafe comment turned on
2024-07-15 10:39:08 +08:00
Luca Bruno 5731e3957f refactor(ast)!: store span details inside comment struct (#4132)
This tweaks `Comment` definition in order to internally store the start
and end position of its span.

Closes: https://github.com/oxc-project/oxc/issues/4069
2024-07-09 23:23:43 +08:00
Boshen 051ceb6539 chore: improve some format by running cargo +nightly fmt 2024-06-19 00:48:30 +08:00
Boshen 982e6f08df chore: make println and eprintln opt-in (#3712)
I noticed accidental `println` can be merged, which isn't really nice.
2024-06-17 10:40:34 +00:00
Boshen e818fba21c refactor(parser): improve parse_simple_arrow_function_expression (#3349) 2024-05-19 06:05:39 +00:00
Boshen 9ced605487 refactor(parser): start porting arrow function parsing from tsc (#3340)
relates #3320
2024-05-18 22:35:29 +08:00
branchseer f159f60084 Make ast types covariant over the allocator lifetime. (#2943)
## Why

Due to the usage of `&'alloc mut T` in `oxc_allocator::Box`, and
`bumpalo::collections::Vec` in `oxc_allocator::Vec`, ast types are
currently invariant over their allocator lifetime `'a`. This prevents
`ouroboros` from generating `borrow_*` on ast type fields, leading to
the unfriendly `with_*` api:
https://github.com/oxc-project/oxc/blob/c250b288ef0b9a3ca72ac01ff96e3e240b78a30d/crates/oxc_parser/examples/multi-thread.rs#L82-L84

## How

- For `oxc_allocator::Vec`, switch to `allocator_api2::vec::Vec`, which
has a covariant relationship with the allocator lifetime.
- For `oxc_allocator::Box`, use `std::ptr::NonNull` which is
specifically designed to be covariant. I don't use
`allocator_api2::boxed::Box` because it holds the allocator for
dropping, so the size is bigger.

## Downside

Now that `oxc_allocator::Box` uses the unsafe `NonNull`. It has to be a
private field to be safe. This make it impossible to do `Box(....)`
pattern matching.
2024-04-12 18:12:18 +08:00
Boshen 59748199da refactor(ast): clean up the ts type visit methods 2024-04-11 15:26:24 +08:00
Boshen fb2ebf462e chore: fix clippy on unsafe comment 2024-04-03 19:57:21 +08:00
Boshen feb3c90098 chore(parser): allow unsafe in examples 2024-04-03 19:40:02 +08:00
Ali Rezvani fc3878350f refactor(ast): add walk_mut functions (#2776)
* move `visit` and `visit_mut` modules to a super module called `visit`
* add `walk_mut` module containing walk functions
* update `enter_node` and `leave_node` events to not pass a reference in the `VisitMut` trait
* add `AstType`, a non-referencing version of `AstKind` to use with `VisitMut` trait
* update the `VisitMut` trait's usages.
2024-03-25 20:40:13 +03:30
Ali Rezvani 198eea0bce refactor(ast): add walk functions to Visit trait. (#2791)
closes #2442
2024-03-25 10:44:29 +08:00
Boshen ef1108a749 chore: Rust v1.77.0 (#2781) 2024-03-21 17:21:57 +00:00
Boshen 0f86333437 refactor(ast): refactor Trivias API - have less noise around it (#2692) 2024-03-12 20:16:36 +08:00
Boshen cda9c93436 fix(parser): improve lexing of jsx identifier to fix duplicated comments after jsx name (#2687) 2024-03-12 15:51:51 +08:00
Boshen 351a0572be chore(parser): print both AST and errors in examples/parser 2024-02-26 23:20:46 +08:00