Commit Graph

811 Commits

Author SHA1 Message Date
hi-ogawa ce6808a7d9 fix(parser)!: rename type_parameters to type_arguments where needed (#9815)
Aligning with https://github.com/typescript-eslint/typescript-eslint/pull/5384
2025-03-18 01:09:48 +00:00
overlookmotel db946e6dc9 feat(ast/estree): order TS fields last by default (#9820)
`ESTree` generator order fields marked `#[ts]` last by default. This behavior can be overridden if required with `#[estree(field_order)]`.
2025-03-17 08:26:26 +00:00
oxc-bot 7856a0b091 release(crates): v0.58.1 (#9754)
## [0.58.1] - 2025-03-13

### Features

- a8331f7 transformer: Turn off explicit resource management by default
(#9749) (Boshen)

### Bug Fixes

- cd3f2fb ast/estree: Fix `JSXOpeningFragment` (#9747) (Hiroshi Ogawa)
- fecec56 ast/estree: Fix `JSXOpeningElement` field order (#9746)
(hi-ogawa)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-03-13 20:34:27 +08:00
Hiroshi Ogawa cd3f2fbc52 fix(ast/estree): fix JSXOpeningFragment (#9747) 2025-03-13 20:03:59 +08:00
hi-ogawa fecec56434 fix(ast/estree): fix JSXOpeningElement field order (#9746)
Remaining failure looks like this:

```diff
== tasks/coverage/acorn-test262-diff/acorn-jsx/010.diff ==
@@ -71,7 +71,7 @@
                 "type": "Literal",
                 "start": 19,
                 "end": 26,
-                "value": "&",
+                "value": "&amp;",
                 "raw": "\"&amp;\""
               }
             },
== tasks/coverage/acorn-test262-diff/acorn-jsx/013.diff ==
@@ -30,7 +30,7 @@
                 "type": "Literal",
                 "start": 16,
                 "end": 31,
-                "value": "&&",
+                "value": "&#x0026;&#38;",
                 "raw": "\"&#x0026;&#38;\""
               }
             }
== tasks/coverage/acorn-test262-diff/acorn-jsx/020.diff ==
@@ -90,7 +90,7 @@
                     "type": "JSXText",
                     "start": 31,
                     "end": 53,
-                    "value": "monkeys /> gorillas",
+                    "value": "monkeys /&gt; gorillas",
                     "raw": "monkeys /&gt; gorillas"
                   }
                 ]
== tasks/coverage/acorn-test262-diff/acorn-jsx/028.diff ==
@@ -14,9 +14,7 @@
         "openingFragment": {
           "type": "JSXOpeningFragment",
           "start": 0,
-          "end": 2,
-          "attributes": [],
-          "selfClosing": false
+          "end": 2
         },
         "closingFragment": {
           "type": "JSXClosingFragment",
== tasks/coverage/acorn-test262-diff/acorn-jsx/046.diff ==
@@ -40,7 +40,7 @@
             "type": "JSXText",
             "start": 3,
             "end": 10,
-            "value": "foo>",
+            "value": "foo&gt;",
             "raw": "foo&gt;"
           }
         ]
```
2025-03-13 11:41:38 +00:00
oxc-bot 38d1302267 release(crates): v0.58.0 (#9740) 2025-03-13 16:58:56 +08:00
Boshen a6c9b0949c docs(napi/minifier): improve documentation (#9736) 2025-03-13 06:28:23 +00:00
Yuji Sugiura 842edd87ea feat(ast)!: Add raw property to JSXText node (#9641)
I happened to find this while trying out
https://github.com/leaysgur/prettier-plugin-oxc .

|Acorn|OXC|
|:---:|:-:|

|![image](https://github.com/user-attachments/assets/f8485bc8-baa7-4892-9c53-fe947318c909)|![image](https://github.com/user-attachments/assets/2c075bbe-ff6b-4b27-87f6-a14c13f5460f)|


Does it make sense to add?

---------

Co-authored-by: overlookmotel <theoverlookmotel@gmail.com>
2025-03-13 14:05:10 +08:00
Boshen 475b48f966 fix(ast): change ImportExpression::attributes to options (#9665)
To align with ts-eslint

https://github.com/typescript-eslint/typescript-eslint/blob/9aa0b6b49807599b1c2b704b778df74c91084a7c/packages/ast-spec/src/expression/ImportExpression/spec.ts#L23
2025-03-12 00:09:56 +00:00
hi-ogawa 446d11ed32 feat(ast/estree): export Node union type (#9574)
- Closes https://github.com/oxc-project/oxc/issues/9573
2025-03-11 12:43:43 +00:00
oxc-bot 8d18dc4207 release(crates): v0.57.0 (#9668)
## [0.57.0] - 2025-03-11

- 510446a parser: [**BREAKING**] Align JSXNamespacedName with ESTree
(#9648) (Arnaud Barré)

- b0d979d semantic: [**BREAKING**] Make `Scoping::references` private
(#9629) (Boshen)

- 3c6f140 semantic: [**BREAKING**] Make `Scoping` methods consistent
(#9628) (Boshen)

- ef6e0cc semantic: [**BREAKING**] Combine `SymbolTable` and `ScopeTree`
into `Scoping` (#9615) (Boshen)

- 7331656 semantic: [**BREAKING**] Rename `SymbolTable` and `ScopeTree`
methods (#9613) (Boshen)

- 23738bf semantic: [**BREAKING**] Introduce `Scoping` (#9611) (Boshen)

### Features

- b6deff8 ecmascript: Support integer index access for array and string
in `may_have_side_effects` (#9603) (sapphi-red)
- 047fb01 minifier: Place `void 0` on right hand side if possible
(#9606) (sapphi-red)
- 36f8703 minifier: Compress `[] + string` to `string` (#9602)
(sapphi-red)
- 554c4ce minifier: Compress constant integer index access (#9604)
(sapphi-red)
- e3c2015 minifier: Allow compressing computed __proto__ more precisely
(#9595) (sapphi-red)
- 6a57198 minifier: Allow compressing computed constructor/prototype
keys precisely (#9594) (sapphi-red)
- 638007b parser: Apply `preserveParens` to `TSParenthesizedType`
(#9653) (Boshen)

### Bug Fixes

- eae1a41 ast: Align `TSImportType` field names with ts-eslint (#9664)
(Boshen)
- 96eef8b ecmascript: `(foo() + "").length` may have a side effect
(#9605) (sapphi-red)
- 24d9261 minifier: Remove names from functions / classes in normal pass
to make the minifier idempotent (#9608) (sapphi-red)
- 6ac3635 napi/parser: Disable raw transfer on unsupported platforms
(#9651) (overlookmotel)
- cfdcfdb parser: Fix end span for optional binding pattern without type
annotation (#9652) (Boshen)
- 26da65d parser: Parse asi after class accessor property (#9623)
(Boshen)
- 87462fd parser: Fix end span for `using` declaration (#9622) (Boshen)
- 29edb51 transformer: Fix module runner transform of export default
expression (#9661) (hi-ogawa)

### Documentation

- 31a2618 allocator: Add safety constraint for
`String::from_raw_parts_in` (#9640) (overlookmotel)

### Refactor

- 44101bd allocator: Refactor and improve safty comments of
`String::from_strs_array_in` (#9639) (overlookmotel)
- c6edafe napi: Remove `npm/oxc-*/` npm packages (#9631) (Boshen)
- a43c341 semantic: Add `Scoping` to `Semantic` (#9614) (Boshen)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-03-11 12:05:56 +08:00
Boshen eae1a411a7 fix(ast): align TSImportType field names with ts-eslint (#9664) 2025-03-11 03:37:03 +00:00
Boshen 638007b181 feat(parser): apply preserveParens to TSParenthesizedType (#9653)
closes #9616
2025-03-10 15:39:24 +00:00
Arnaud Barré 510446a95f fix(parser)!: align JSXNamespacedName with ESTree (#9648)
See in
https://ast-explorer.dev/#eNolyUEOgyAQheGrkLc26Z40PUV3nS4A0WiQISBGY7y7Q9z973snAjRms5ni8pRWdEgC1lgfpJ30e2DW1mT1+oiwyElRKULhmp3/HskTtOyF+xqku+dOoY5TLO37NWk2l53Qxp/ihesGhcgmng==
and
https://ast-explorer.dev/#eNpFy8EKAjEMBNBfKTmveC/i0U/w1EssEbrUtiRZUZb+u4kePM6bmR0qRFjxiZK5DIUFhoG+B/3gQFJLc8/mp3vv8YYcjmeTbrKnFkICyg+8EkvpLUE0qKgkmmD59xdC3ZjEB9+bF6u8PCtv5DRTmzA/PxwwOA==

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-03-10 22:05:04 +08:00
overlookmotel 6ac3635000 fix(napi/parser): disable raw transfer on unsupported platforms (#9651)
Disable `experimentalRawTransfer` in `oxc-parser` NAPI package on
unsupported platforms.

Tested working on:

* NodeJS v22.0.0
* NodeJS v22.14.0
* NodeJS v23.0.0
* NodeJS v23.9.0
* Deno v2.0.0
* Deno v2.2.3

Not working on:

* NodeJS v20.0.0
* NodeJS v20.18.1
* Bun v1.2.4

The reason NodeJS v20 and Bun are unsupported is because they cannot
create an `ArrayBuffer` larger than 4 GiB. We may be able to relax that
requirement in future in order to support those platforms.
2025-03-10 21:39:35 +08:00
Boshen c6edafe08d refactor(napi): remove npm/oxc-*/ npm packages (#9631)
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-03-09 22:43:06 +08:00
oxc-bot 0ab76bf129 release(crates): v0.56.5 (#9593)
## [0.56.5] - 2025-03-07

### Refactor

- 5103322 semantic: Move `IsGlobalReference` to its own file (#9592)
(Boshen)
- b7484b8 semantic: Remove `CompactStr` usage from `ClassTable` (#9591)
(Boshen)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-03-07 23:34:02 +08:00
oxc-bot 5352483965 release(crates): v0.56.4 (#9589)
## [0.56.4] - 2025-03-07

### Bug Fixes

- c08b7fc napi: Commit wasi files (Boshen)
- 35626a4 npm: Change to `wasm32-wasip1-threads` target (Boshen)

### Refactor

- 62bffed rust: Allow a few annoying clippy rules (#9588) (Boshen)
- adf7987 transformer: Combine strings by `ctx.ast.atom_from_array`
(#9401) (Dunqing)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-03-07 20:30:37 +08:00
Boshen c08b7fc0ce fix(napi): commit wasi files 2025-03-07 19:53:33 +08:00
oxc-bot 48fa01cba5 release(crates): v0.56.3 (#9587) 2025-03-07 17:35:32 +08:00
Boshen 6b95d25a23 feat(parser): disallow TSInstantiationExpression in SimpleAssignmentTarget (#9586)
relates #9493
2025-03-07 09:21:06 +00:00
oxc-bot f82cbeea74 release(crates): v0.56.2 (#9584) 2025-03-07 15:31:20 +08:00
oxc-bot 109d06626d release(crates): v0.56.1 (#9582) 2025-03-07 12:02:05 +08:00
Boshen 0bbb197c87 ci(npm): rework release pipeline (#9581) 2025-03-07 11:49:50 +08:00
oxc-bot 64080ee745 release(crates): v0.56.0 (#9572) 2025-03-06 09:47:22 +08:00
overlookmotel 2985bf3d37 ci(wasm): check wasm32-wasip1-threads build (#9569)
Duplicate of #9555, but just stacked on top of #9566.

`napi-rs` for some reason omits the `export * from '@oxc-project/types';` line from `index.d.ts` when building for WASM.

I don't know how to fix that, so added a hacky script to fix up `index.d.ts` manually. This is not at all ideal, but at least it now compiles and CI passes.
2025-03-06 01:34:21 +00:00
overlookmotel 91c993290f fix(napi): do not support raw transfer on WASM32 (#9566)
Prevent compilation errors on 32-bit platforms by avoiding calculating `usize: 1 << 32` unless on a 64-bit platform.

`parseSync` will throw an error if called with `experimentalRawTransfer` on an unsupported system.

Add a function `rawTransferSupported` to check if raw transfer is supported on current system or not, so user can avoid these errors.
2025-03-06 01:34:20 +00:00
oxc-bot 4d973040c8 release(crates): v0.55.0 (#9554) 2025-03-05 14:19:54 +08:00
overlookmotel c1a8cea474 refactor(ast/estree): simplify serializing RegExpLiterals (#9551)
Similar to #9546. Acorn outputs `RegExpLiteral`'s flags in same order as in source text. There is nothing wrong with this, but it makes our serialization/deserialization code more complex than it needs to be, just to match Acorn. I don't think we need to follow Acorn here - there's no particular "good" order for the flags.

Bump `acorn-test262` to include commit https://github.com/oxc-project/acorn-test262/commit/3d7013e145499268dc8f985d087208aa013e0ba2, which reorders the flags in alphabetical order in Acorn's AST.

This allows simplifying serialization/deserialization code on our side.
2025-03-05 02:21:02 +00:00
overlookmotel af02a87853 feat(ast/estree): Property have consistent field order (#9547)
Similar to #9546. Acorn has inconsistent field order for `Property` nodes - https://github.com/acornjs/acorn/pull/1347.

Bump `acorn-test262` to include commit https://github.com/oxc-project/acorn-test262/commit/7b7fa95e055352d76ddccc98cabc37ca1448cf92, which orders the fields consistently in Acorn's AST.

This allows simplifying serialization/deserialization code, as we now don't need to deal with shuffling field order to match Acorn.
2025-03-05 02:21:02 +00:00
overlookmotel 3e4f909861 feat(ast/estree): ESTree AST ExportNamedDeclaration always have attributes field (#9546)
Acorn does not include an `attributes` field on `ExportNamedDeclaration` when `source == null`. I think that's an oversight - https://github.com/acornjs/acorn/pull/1346.

Bump `acorn-test262` to include commit https://github.com/oxc-project/acorn-test262/commit/96faefa7644f16bb163484ee50fa13d6ecff7e72 which adds the missing `attributes` field to Acorn's AST.

This allows simplifying serialization/deserialization code, as we now don't need to deal with this special case.
2025-03-05 02:21:01 +00:00
overlookmotel a9889f5c9a ci(benchmarks): benchmark NAPI parser (#9519)
Add benchmarks for NAPI parser. Benchmarks cover both "standard" mode and "raw transfer" mode.

Codspeed say they've sorted out the problems with wide variance in NodeJS benchmarks, so hopefully they won't wave all over the place, the way they did last year when we first tried to add these benchmarks.

What we also found last year is that Codspeed's measures didn't reflect real-world wallclock measurements at all when comparing code running on Rust side vs JS side. Raw transfer moves a lot of work from Rust side to JS side, and so likely the bench results will be misleading if comparing "standard" vs "raw".

I've added benchmarks for both, not to compare the 2, but because I think there's room to improve the performance of both "standard" and "raw" independently.
2025-03-05 02:21:01 +00:00
overlookmotel a0f6f37b64 fix(ast/estree): raw transfer support showSemanticErrors option (#9522)
Add support for `showSemanticErrors` option in `parseSync` when `experimentalRawTransfer` option is enabled.
2025-03-04 14:40:36 +00:00
overlookmotel 4378a66a40 test(ast/estree): speed up raw transfer tests (#9521)
Speed up the tests for raw transfer by serializing output to JSON, and comparing as string to the `acorn-test262` JSON snapshots. This is faster than running `parseSync` twice with "raw" and "standard" settings, and comparing the 2 - time to run the NAPI parser tests is reduced by half.

There are still 5 tests which compare 5 sample JS/TS files (same ones as used in benchmarks) with a full raw-vs-standard comparison. These tests cover the other parts of `parseSync`'s return value - `comments`, `module` and `errors`. They also give some limited test coverage for AST of TS files.
2025-03-04 14:40:36 +00:00
overlookmotel 40565600a5 feat(ast/estree)!: option to return JS-only AST (#9520)
Add an `astType` option to `parseSync` and `parseAsync`.

When set to `'js'`, the returned AST does not include TypeScript-related properties. When set to `'ts'`, it does.

If not specified, the option defaults to same as source type. So when parsing JS / JSX files, the AST returned does not include TS properties by default.

The motivation for allowing the user to override that behavior, is in case someone is parsing a mix of JS and TS files, and want all the ASTs in the same format. In that case they'd set `astType: 'ts'` for all files.

This is a breaking change as it alters what properties appear in the AST on JS side.
2025-03-04 14:40:36 +00:00
overlookmotel d55dbe2d78 feat(ast/estree): raw transfer (experimental) (#9516)
First version of raw transfer (#2409).

Provides a solid speed-up transferring data from Rust to JS. Further iterations will speed it up further.

Tests check that output via raw transfer matches output via JSON transfer exactly for all of Test262 which Acorn is able to parse. It should also match for TypeScript and JSX, but that's not covered by tests as yet.

However, I think we should consider this experimental for now because there are a few rough edges (discussed below).

Therefore I've put it behind an "experimental" flag:

```js
const ret = parseSync(filename, code, { experimentalRawTransfer: true });
console.log(ret.program);
```

### How it works

* JS creates an `ArrayBuffer` and passes it to Rust.
* Rust creates an `Allocator` using that buffer as its backing memory.
* Rust parses the AST into that allocator (including comments).
* Rust also converts module record and errors into arena types, and writes them into the allocator.
* Rust writes into the end of the buffer the offset at which data begins in the buffer.
* Control passes back to JS.
* JS code decodes data in the buffer, and creates JS objects fitting the ESTree shape.

There is *no* serialization step on Rust side. There is no JSON encoding or decoding involved. These are the main sources of the speed gain.

### Preconditions

The reason all this works is that all AST types (and other transferred types) are `#[repr(C)]`. So the memory layouts of those types are specified, and can be statically calculated.

`oxc_ast_tools` does those layout calculations, and generates the JS-side deserializer code based on its knowledge of what offsets struct fields are at, what the discriminants of enums are etc.

### Rough edges

There are a few rough edges.

#### `Allocator::from_raw_parts`

This PR adds a method `Allocator::from_raw_parts`. It creates a `bumpalo::Bump` that uses an existing block of memory as the allocator's backing memory. This ability is required, but it's not an API that `bumpalo` offers (and the maintainer was not willing to add it).

The implementation of `Allocator::from_raw_parts` is extremely hacky. It depends on internal implementation details of `bumpalo` which are not specified. And the method used to determine the memory layout of `Bump` depends on unspecified details of Rust's memory model. So, while it does seem to work in practice, it is, strictly speaking, UB.

It could break in a future Rust version, or with esoteric compiler flags e.g. [`-Zrandomize-layout`](https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/randomize-layout.html). And it could break if we update `bumpalo` from the version we're currently using. For this reason, this PR pins the version of `bumpalo` in `Cargo.toml`.

I think this OK for now, but it's unpleasantly fragile.

We can resolve all these problems by replacing `bumpalo` with our own arena allocator (which I think we should do anyway, for other reasons).

In the meantime, `Allocator::from_raw_parts` is behind a cargo feature `from_raw_parts`, to avoid it being used anywhere else in our codebase.

#### Unspecified type layouts

As noted above, all AST types are `#[repr(C)]`, so their layout is specified and stable. There are a few types which are outside of our control, though:

1. `Vec<T>`. We use `allocator_api2::vec::Vec`, which is not `#[repr(C)]`.
2. `&str`. I don't believe the layout of this type is specified.
3. `Option<T>`.

For production-grade stability, we need to try to work around these.

`Vec` - we should replace `allocator_api2::vec::Vec` with our own `Vec` type. This will also allow us to reduce its size (https://github.com/oxc-project/backlog/issues/18).

`&str` - again, we need our own string slice type, to work around the problem of lone surrogates (#3526) and to make it more efficient (https://github.com/oxc-project/backlog/issues/46). We can make its memory layout stable at the same time.

`Option<T>` is tricky. We don't want to replace Rust's `Option` because of the niche optimization benefits it gives. I'm not sure this one is 100% soluable, but Rust gives at least *some* guarantees about the layout of `Option`. Maybe we can avoid using `Option` in the AST in ways which go outside that specification.

#### Large buffers

For speed, raw transfer requires the entire AST to be in a single contiguous memory region, and for the start of that region to be aligned on 4 GiB.

JS does not support 64-bit integers, so offset calculations are much cheaper when the buffer is aligned on 4 GiB and no larger than 4 GiB - because then all pointers have the same value in their top 32 bits. So the pointer can be treated as a 32-bit value (bottom 32 bits only). JS can handle 32 bit integers no problem.

When creating a large buffer on JS side, it *mostly* ends up aligned on a 4 GiB boundary anyway, but occasionally it doesn't. So in order to ensure the buffer has at least 1 region within it which is aligned on 4 GiB, and 2 GiB in size, we have to create a 6 GiB buffer.

I *think* this is OK. On systems with virtual memory, allocating 6 GiB only reserves 6 GiB of *virtual* memory. Physical memory is only consumed when the pages of that allocation are actually written to.

But I may be missing something here, and memory exhaustion might be a danger. I think we need some real-world usage to find out.

*Possibly* we could reduce the need for so much memory if JS deserializer called into a small WASM module to do offset calculations. WASM can work with `i64` values. Or there may be other solutions.

#### Endianness

Currently only little-endian systems are supported. Probably in practice this doesn't matter much, but it'd be ideal to cover big-endian too.
2025-03-04 14:40:35 +00:00
oxc-bot 7bfb6076b5 release(crates): v0.54.0 (#9524)
## [0.54.0] - 2025-03-04

- 098f652 codegen: [**BREAKING**] Add `CommentAnnotation` to avoid
parsing comments again (#9506) (Boshen)

- a8d1d48 parser,codegen: [**BREAKING**] Parse and
print`#__NO_SIDE_EFFECTS__` (#9496) (Boshen)

- 355a4db napi/parser: [**BREAKING**] Remove `parse_without_return` API
(#9455) (Boshen)

- a5cde10 visit_ast: [**BREAKING**] Add `oxc_visit_ast` crate (#9428)
(Boshen)

- abb15e0 ast: [**BREAKING**] Add `pure` field to `Function`,
`CallExpression`, and `NewExpression` (#9207) (overlookmotel)

### Features

- a9f0d2b ast_tools: Generate field offset assertions for more types
(#9449) (overlookmotel)
- 64f4a82 ecmascript: Handle pure call expression in chain expressions
(#9480) (sapphi-red)
- 32139d2 ecmascript: Support `/* @__PURE__ */` in may_have_side_effects
(#9409) (sapphi-red)
- f5453f6 minifier: Flatten spread args in new expressions (#9512)
(sapphi-red)
- f8073f3 minifier: Support if with side effects in dead code
elimination (#9502) (sapphi-red)
- 10eb8f7 minifier: Use `remove_unused_expression` in
`try_fold_sequence_expression` in `remove_dead_code` (#9467)
(sapphi-red)
- 70916db minifier: Remove unused expression in for init and update
(#9466) (sapphi-red)
- 26fde56 minifier: Inline simple IIFEs in `remove_unused_expression`
(#9465) (sapphi-red)
- ec2193e minifier: Support extracting arguments in pure calls in
`remove_unused_expression` (#9463) (sapphi-red)
- 007051c minifier: Compress `a != null && a.b()` to `a?.b()` in
`remove_unused_expression` (#9459) (sapphi-red)
- 50fce20 minifier: Support binary expression in
`remove_unused_expression` (#9456) (sapphi-red)
- ed9ede3 minifier: Support conditional expression in
`remove_unused_expression` (#9432) (sapphi-red)
- 3520538 minifier: Support object expression in
`remove_unused_expression` (#9430) (sapphi-red)
- fb8a93d minifier: Improve array expression handling in
`remove_unused_expression` (#9427) (sapphi-red)
- ff477cd minifier: Support template literals in
`remove_unused_expression` (#9426) (sapphi-red)
- 0d26113 minifier: Compress `/* @__PURE__ */ a() ? b : b` to `b`
(#9410) (sapphi-red)
- 68c77c8 napi/parser: Return semantic errors (#9460) (Boshen)
- 7d7f16c parser: Apply pure to rhs of binary expression (#9492)
(Boshen)
- 2a08b14 parser: Support V8 intrinsics (#9379) (injuly)
- 9b7017c parser,codegen: Pure annotations (#9351) (Boshen)
- aa06932 transformer: Support `ModuleRunnerTransform` (#9371) (Dunqing)

### Bug Fixes

- 75f06ad codegen: Do not print comments when only `annotation_comments`
is enabled (#9518) (Dunqing)
- f5bbd5d ecmascript: Fix toString for negative numbers (#9508)
(sapphi-red)
- d2cd975 ecmascript: Fix may_have_side_effects for `${a() === b}`
(#9478) (sapphi-red)
- 584d847 ecmascript: Objects passed to template literals may have side
effects (#9425) (sapphi-red)
- b371fdc estree/ast: Camel-case `typeAnnotation` field (#9420)
(overlookmotel)
- 1fff993 minifier: Correctly remove dead code in `try` with `finally`
(#9503) (sapphi-red)
- 0b96ebe minifier: Don't inline IIFE with parameters (#9477)
(sapphi-red)
- 071c84c minifier: Skip `try_fold_stmt_in_boolean_context` on
`ExpressionStatement` (#9458) (sapphi-red)
- 306284d minifier: Call mark_current_function_as_changed in
remove_unused_expression (#9457) (sapphi-red)
- 9c6ae9f parser: `@__NO_SIDE_EFFECTS` only affects const variable decl
(#9517) (Boshen)
- b7d5513 parser: Parse `@__NO_SIDE_EFFECTS__` between `export default`
and `async function` (#9514) (Boshen)
- 01de74c parser: Correctly fail parsing when parsing `foo.bar?.`
(#9499) (camc314)
- 58defe3 parser: Mark expression as pure in chain expression (#9479)
(sapphi-red)
- 2a03689 parser: Mark expressions on the left side of logical and
conditional expressions as pure (#9414) (sapphi-red)
- 7fde233 transformer/legacy-decorator: Incorrect check for potentially
non-existent ident (#9491) (Dunqing)
- b4f050c transformer/legacy-decorator: Metadata incorrectly wrapped by
decorateParam (#9490) (Dunqing)
- 5f67fa9 transformer/optional-chaning: Keep `this` when transforming
`this.f?.()` (#9505) (camc314)

### Performance

- 10e4431 ast/estree: Skip escaping identifiers (#9398) (overlookmotel)
- b0a0a82 ast/estree: Reduce overhead serializing static strings (#9396)
(overlookmotel)
- 27a8e50 isolated_declarations: Reserve sufficient capacity in
statements `Vec` (#9394) (overlookmotel)

### Refactor

- 8916335 ast/estree: Convert enums with converters on variants (#9438)
(overlookmotel)
- dcff40c ast_tools: Generate layout assertions in multiple crates
(#9448) (overlookmotel)
- 19c4835 codegen: Simplify printing comments between arguments in
call-like expressions (#9501) (Dunqing)
- c880481 isolated_declarations: Rename var (#9390) (overlookmotel)
- 37e41f0 isolated_declarations: Use aliases `ArenaBox` / `ArenaVec`
(#9389) (overlookmotel)
- bbb450c minifier: Move `a != null && b` -> `a ?? b` compression to
`remove_unused_expression` (#9468) (sapphi-red)
- b93774c minifier: Move `try_fold_iife` to `remove_unused_expression`
(#9464) (sapphi-red)
- 96a9719 minifier: Use `may_have_side_effects` in
`remove_unused_expression` (#9413) (sapphi-red)

### Testing

- c187b11 ecmascript: Add comments and tests for cases where
`ToPropertyKey` throws an error (#9429) (sapphi-red)
- d129055 napi: Add tests for worker threads (#9408) (Boshen)
- 48d51e3 napi: Add tests for `hashbang` field (#9386) (overlookmotel)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-03-04 08:42:28 +08:00
Boshen 68c77c8996 feat(napi/parser): return semantic errors (#9460)
closes #9395
2025-03-01 09:50:23 +00:00
Boshen 355a4dbadd feat(napi/parser)!: remove parse_without_return API (#9455) 2025-03-01 07:51:26 +00:00
Boshen a5cde10ecc feat(visit_ast)!: add oxc_visit_ast crate (#9428)
closes #9384
2025-02-28 08:03:54 +00:00
Boshen d129055dc6 test(napi): add tests for worker threads (#9408)
There are user code which may crash under some random circumstances
that we don't understand. Prevent these crashes with a test.
2025-02-27 07:19:11 +00:00
overlookmotel 48d51e31bc test(napi): add tests for hashbang field (#9386)
ESTree conformance tester does not test `hashbang` field, so add tests to `napi/parser` instead.
2025-02-26 13:07:35 +00:00
oxc-bot 41b3d2b9b7 release(crates): v0.53.0 (#9381)
## [0.53.0] - 2025-02-26

- https://github.com/oxc-project/oxc/pull/9289
- 4a5a7cf napi/parser: [**BREAKING**] Remove magic string; enable utf16
span converter by default (#9291) (Boshen)

### Features

- 5c775ea ast/estree: Enable serialization without TS fields (#9285)
(overlookmotel)
- f21740e data_structures: Add `CodeBuffer::print_bytes_iter_unchecked`
method (#9337) (overlookmotel)
- e10fb97 ecmascript: Improve may_have_side_effects for `.length`
(#9366) (sapphi-red)
- 35e5ca9 ecmascript: Improve may_have_side_effects for `instanceof`
(#9365) (sapphi-red)
- 11012c6 ecmascript: Improve ValueType for coalesce operator (#9354)
(sapphi-red)
- b7998fd ecmascript: To_number for object without toString (#9353)
(sapphi-red)
- e51d563 minifier: Concatenate strings with template literals on right
side (#9356) (sapphi-red)
- 9d7db54 minifier: Concatenate strings with template literals (#9355)
(sapphi-red)
- 835ee95 wasm: Return estree with utf16 span offsets (#9376) (Boshen)

### Bug Fixes

- 6a8f53f ast/estree: Visit `JSXOpeningFragment` and
`JSXClosingFragment` (#9342) (overlookmotel)
- e303767 ast/estree: Fix ESTree AST for imports and exports (#9282)
(overlookmotel)
- 54d59f1 data_structures: Stack types correctly report allocation size
if allocation failure during grow (#9317) (overlookmotel)
- f5c8698 ecmascript: Correct may_have_side_effects for classes (#9367)
(sapphi-red)
- d3ed128 minifier: Do not remove `=== 0` if the lhs can be NaN (#9352)
(sapphi-red)

### Performance

- 82adab9 ast/estree: Speed up building UTF8-UTF16 translation table
with SIMD (#9359) (overlookmotel)
- 61939ca ast/estree: Faster UTF-8 to UTF-16 span conversion (#9349)
(overlookmotel)
- 1bfc459 ast/estree: Pre-allocate `CodeBuffer` for JSON output (#9340)
(overlookmotel)
- 018c523 ast/estree: `ESTree` serializer use `CodeBuffer` (#9331)
(overlookmotel)
- 35ee399 codegen: Use `iter::repeat_n` in `CodeBuffer` (#9325)
(overlookmotel)

### Documentation

- 8bd3e39 data_structures: Uppercase SAFETY comments (#9330)
(overlookmotel)

### Refactor

- d94fc15 allocator: Reduce scope of `unsafe` blocks (#9319)
(overlookmotel)
- 7427900 ast: Re-order `ExportDefaultDeclaration` fields (#9348)
(overlookmotel)
- b09249c ast/estree: Rename serializers and serialization methods
(#9284) (overlookmotel)
- 55ed1df ast/estree: Shorten `ESTree` impls for enums (#9275)
(overlookmotel)
- 9d98444 codegen, data_structures: Move `CodeBuffer` into
`oxc_data_structures` crate (#9326) (overlookmotel)
- 6a4e892 data_structures: Add debug assertion to
`CodeBuffer::peek_nth_char_back` and improve safety docs (#9336)
(overlookmotel)
- fc46218 data_structures: `CodeBuffer::print_str` use
`Vec::extend_from_slice` (#9332) (overlookmotel)
- 690bae5 data_structures: Stack types const assert `T` is not zero-size
type (#9318) (overlookmotel)
- 10ba2ea data_structures: Reduce scope of `unsafe` blocks (#9316)
(overlookmotel)
- beb8382 data_structures: `CodeBuffer::print_bytes_unchecked` take a
byte slice (#9327) (overlookmotel)
- faf966f ecmascript: Don't check side effects in constant_evaluation
(#9122) (sapphi-red)
- 2faabe1 estree: Make `itoa` dependency optional (#9338)
(overlookmotel)
- 4e9e8cf lexer: Reduce scope of `unsafe` blocks (#9320) (overlookmotel)
- c31b53f mangler: Reduce scope of `unsafe` blocks (#9321)
(overlookmotel)
- f10a6da mangler: Move base54 into seperate mod (#9278) (Cameron)
- 12e89e0 syntax: Reduce scope of `unsafe` blocks (#9322)
(overlookmotel)
- f39be5f traverse: Reduce scope of `unsafe` blocks (#9323)
(overlookmotel)

Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com>
2025-02-26 20:00:21 +08: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 4a5a7cf921 feat(napi/parser)!: remove magic string; enable utf16 span converter by default (#9291)
Benchmark reveals utf16 span converter is not that slow:

```
 ✓ bench.bench.mjs 1491ms
     name                                                  hz      min      max     mean      p75      p99     p995     p999     rme  samples
   · parser_napi[checker.ts] convertSpanUtf16: true   31.3194  30.8477  34.4288  31.9291  32.3740  34.4288  34.4288  34.4288  ±1.61%       16
   · parser_napi[checker.ts] convertSpanUtf16: false  34.1307  28.6449  29.9385  29.2991  29.6852  29.9385  29.9385  29.9385  ±0.70%       18   fastest

 BENCH  Summary

  parser_napi[checker.ts] convertSpanUtf16: false - bench.bench.mjs
    1.09x faster than parser_napi[checker.ts] convertSpanUtf16: true
```

```
 ✓ bench.bench.mjs 2127ms
     name                                               hz      min      max     mean      p75      p99     p995     p999     rme  samples
   · parser_napi[antd.js] convertSpanUtf16: true   15.1191  65.1335  67.4651  66.1414  66.6032  67.4651  67.4651  67.4651  ±0.70%       10
   · parser_napi[antd.js] convertSpanUtf16: false  17.3037  57.0110  58.6842  57.7911  58.1348  58.6842  58.6842  58.6842  ±0.69%       10   fastest

 BENCH  Summary

  parser_napi[antd.js] convertSpanUtf16: false - bench.bench.mjs
    1.14x faster than parser_napi[antd.js] convertSpanUtf16: true
```

Remove the option and enable the conversion by default.

Magic string API becomes useless at this point. 

This is a trade off between dx, maintenance and performance. dx and
maintainance wins this time.

---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
2025-02-22 14:27:35 +08: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
oxc-bot ba8dcfd6aa release(crates): v0.52.0 (#9276) 2025-02-21 23:51:58 +08:00
Boshen c2ee8060dc chore: include build.rs in napi crates 2025-02-21 23:37:03 +08:00
Boshen c933c6d67a chore(deps): bump napi (#9274) 2025-02-21 23:33:21 +08:00