Commit Graph

811 Commits

Author SHA1 Message Date
overlookmotel 8cab72fb79 test(napi/parser): env var to run lazy deserialization tests (#11636)
Enable lazy deserialization tests in `napi/parser` with `RUN_LAZY_TESTS=true pnpm test`. This is easier to use than a hard-coded value.
2025-06-12 12:43:03 +00:00
overlookmotel 0bdf718230 chore(napi)!: drop support for NodeJS before v20 in oxc-parser (#11586)
Drop support for NodeJS before v20 in `oxc-parser` NPM package.

All versions of NodeJS earlier than v20 are now EOL. I don't think we need to support them.

https://nodejs.org/en/about/previous-releases

I would like to use `FinalizationRegistry`, which is not available in Node v14 (our current lowest supported version).
2025-06-12 09:53:06 +00:00
overlookmotel 8ad30611b2 test(napi/parser): run raw transfer tests on multiple threads (#11611)
Fix #10519.

Run raw transfer tests across multiple threads. Vitest can run multiple test *files* in parallel on separate threads, but it doesn't have ability to run test *cases* in the same file in parallel.

So create a worker pool and send details of each test case to the workers, which then run them in parallel.

On my machine, this cuts down the time to run `napi/parser` tests by a factor of 3 - from 19s to 6s.

Also: Fix `parseAsync` tests: `Promise`s weren't being `await`-ed, and cut down number of iterations on `parseAsync` test from 100,000 to 10,000 so it completes in a reasonable amount of time.
2025-06-12 03:44:00 +00:00
overlookmotel ff7111ce52 refactor(napi/parser): use "construct" instead of "deserialize" in lazy deserializer (#11616)
Use the term "construct" for creating an AST node object in lazy deserializer. "Deserialize" was the wrong word to use, because the whole point is that it *doesn't* deserialize until you ask it to.
2025-06-11 22:52:12 +00:00
overlookmotel 5271951d48 perf(napi/parser): remove function calls from lazy deserialization (#11615)
Remove unnecessary intermediate functions from lazy deserializer. To create a node object, you can construct the node class directly.
2025-06-11 19:03:27 +00:00
overlookmotel 5a55a5856e feat(napi/parser): add lazy deserialization (#11595)
First iteration of lazy deserialization. It works (does not throw an error on any of Test262 or TS test cases), but has some major shortcomings at present:

* Does not match ESTree - shape of AST is more like our Rust types.
* Some missing fields.
* `Vec`s are not lazily deserialized.
* No caching of nodes, so you get a different object each time you get a node e.g. `assert(binaryExpression.left == binaryExpression.left)` fails!

Note: This is a lazy deserializer, which is first step towards a lazy visitor. But there's no visitor implemented yet.

I will build on this starting point in future PRs.
2025-06-11 15:04:19 +00:00
overlookmotel 120b00f98a feat(napi/parser): support old versions of NodeJS (#11596)
Add a fallback for `os.availableParallelism` in versions of NodeJS prior to v18.14.0, which don't support it.

As requested by Prettier, who support NodeJS v14. https://github.com/oxc-project/oxc/pull/11583#pullrequestreview-2913819661
2025-06-11 15:04:19 +00:00
overlookmotel 7c66637878 perf(napi/parser): re-use TypedArray objects in raw transfer (#11585)
Small optimization to raw transfer. Reuse the same `Uint32Array` and `Float64Array`, rather than re-creating them for each file.
2025-06-11 15:04:19 +00:00
overlookmotel c0027e0358 test(ast/estree): benchmark raw transfer deserialization in isolation (#11584)
Add a benchmark for just the deserialization part (JS side) of raw transfer.
2025-06-11 15:04:18 +00:00
overlookmotel 95ee174347 refactor(napi/parser): move raw transfer code into separate directory (#11583)
Pure refactor. Move code for raw transfer into separate directory. This will enable exposing some internals to benchmarks without exposing them publicly from the package. Also lazy deserialization is going to add a lot more code - don't want `index.js` to get too bloated.

Also make main entry point `index.js` run in strict mode (doesn't much matter, but it's good practice).
2025-06-11 15:04:18 +00:00
overlookmotel 8e74e05a60 refactor(ast/estree): remove dead code from generated raw transfer deserializer (#11579)
Remove dead code for deserializing `Option`s, `Box`es and `Vec`s of types which are not included in ESTree AST (e.g. `oxc_regular_expression` types).
2025-06-09 18:44:38 +00:00
renovate[bot] 888b9c8d43 chore(deps): lock file maintenance npm packages (#11557) 2025-06-09 14:34:46 +08:00
overlookmotel f3eaefbf1b feat(ast)!: add value field to BigIntLiteral (#11564)
Add `value` field to `BigIntLiteral`, same as the other literal types.

Once upon a time, we stored the value as a `BigInt` which normalized the representation (removing `_`s, and converting e.g. `0xFF` to `255`). But we had to remove it because `BigInt` owns a heap allocation, and this caused a memory leak.

https://github.com/oxc-project/oxc/commit/50fe0fef73027f10740e68a65a78216933b5d8a0

This PR brings back the `value` field, but avoids memory leak by storing the normalized value as a string (`Atom`).

This has effects in various places in the codebase:

* Brings our JS-side AST into line with ESTree (fixing the test cases broken by #11563).
* Fixes edge cases in a couple of lint rules.
* Codegen now prints bigints in normalized form e.g. `0xFFn` is printed as `255n`.
* Changes behavior of 1 function in `oxc_ecmascript`.

I've made comments below on the parts I'm not so sure about. Review would be very welcome!
2025-06-09 02:28:46 +00:00
oxc-bot 958849ca05 release(crates): v0.72.3 (#11504) 2025-06-06 15:40:07 +08:00
overlookmotel 8451beea5d fix(ast/estree): remove repeat fields from BindingPattern in TS-ESTree AST (#11500)
Related to #11489.

Remove the duplicate properties from TS-ESTree JSON for `BindingPattern` by using custom serializers.

This isn't the ideal solution, but it does solve the immediate problem.
2025-06-05 15:54:56 +00:00
LongYinan ab0dd29a2b fix(napi): napi build cache problem (#11479) 2025-06-05 12:16:08 +08:00
overlookmotel 5c32b7cb1e fix(ast/estree): make error objects via raw transfer match standard transfer (#11481)
Add `codeframe` property to errors returned by `parseSync` / `parseAsync` when using raw transfer. This matches the shape of error objects without raw transfer.
2025-06-04 13:24:02 +00:00
overlookmotel 97aa9ccfc1 test(ast/estree): remove test skip list for TS raw transfer tests (#11478)
There were some test cases we needed to skip because they'd cause parser to panic. That bug is now fixed (#11473), so no need to skip these tests any more.
2025-06-04 12:27:55 +00:00
overlookmotel 75e241c353 test(ast/estree): test raw transfer on TS-ESTree (#11476)
Add NAPI parser tests to check that TS-ESTree AST via raw transfer matches snapshots.

Previous PRs have fixed all remaining issues, so all the tests pass!
2025-06-04 08:52:33 +00:00
Boshen 0c2d1c1e80 Revert "chore(napi): upgrade to napi@3.0.0-beta.4" (#11474)
Reverts oxc-project/oxc#11466
2025-06-04 16:03:12 +08:00
LongYinan 81af6b3988 chore(napi): upgrade to napi@3.0.0-beta.4 (#11466)
Regenerate the binding files
2025-06-04 11:49:19 +08:00
overlookmotel 953e61b839 fix(ast/estree): fix field order of PropertyKey constructor in raw transfer TS-ESTree AST (#11463)
Fix field order of `PropertyKey` where it is a constructor in raw transfer TS-ESTree AST.
2025-06-03 19:43:11 +00:00
overlookmotel 1919e5d1f1 ci(napi): add parseAsync to benchmarks (#11460)
Add `parseAsync` to NAPI parser benchmarks. Group benchmarks by file, so it's easier to read the results.
2025-06-03 16:02:48 +00:00
Yuji Sugiura ec4fc832b7 fix(estree): Use consistent field order in serialization (#11385)
Part of #9705 , follow up #11362 

This change will generate the same AST shapes in all locations, regardless of `visitor-keys`.
2025-06-02 18:28:09 +01:00
oxc-bot 972c76572b release(crates): v0.72.2 (#11411) 2025-05-31 13:45:07 +08:00
overlookmotel 1df6732b46 feat(ast/estree): add decorators to ESTree AST (#11393)
Close #10921.

Add decorators to ESTree AST. `decorators` field is added to `ClassDeclaration`, `ClassExpression`, `PropertyDefinition`, and `MethodDefinition` - as per [ESTree spec](https://github.com/estree/estree/blob/52399d923111fe2a4dcfe1ede795e08356f35ddc/stage3/decorators.md).

Bump `acorn-test262` dependency to include https://github.com/oxc-project/acorn-test262/pull/42 and https://github.com/oxc-project/acorn-test262/pull/43, which add test fixtures for decorators.
2025-05-31 01:20:06 +00:00
overlookmotel 12690a10bf refactor(ast/estree): re-order fields in visitation order (#11362)
Re-order fields in ESTree and TS-ESTree ASTs to be in visitation order (which is the order in which they're defined in Rust types).

This does not align with either Acorn or TS-ESLint, but for the reasons discussed in https://github.com/oxc-project/oxc/issues/9705#issuecomment-2859250834, I feel this isn't a concern. The field order doesn't matter much per se, only that it's consistent, and this change has other benefits - it will make it simpler to build a visitor which visits fields in the correct order, and allows adding other parsers to `acorn-test262` in order to produce test cases for decorators.

Visitation order aligns with TS-ESLint except for the following types:

* `ExportSpecifier`
* `TSImportType`
* `TSIndexedAccessType`
* `TSMethodSignature`
* `TSPropertySignature`
* `TSTypePredicate`

In these 6 cases, TS-ESLint's `visitorKeys` has the wrong visitation order, because it does not visit fields in source order. I will open an issue and hopefully they can fix.

This PR also bumps `acorn-test262` to include https://github.com/oxc-project/acorn-test262/pull/37 which re-orders the fields in fixture snapshots to match the new field order here.
2025-05-29 02:20:54 +00:00
overlookmotel 1d1ebd6287 refactor(ast_tools/estree): order type and span fields first by default (#11361)
Order `type` field 1st, and `span` field 2nd in ESTree and TS-ESTree ASTs.
2025-05-29 02:20:54 +00:00
overlookmotel 75ee3a5c47 refactor(ast/estree): do not put TS struct fields last (#11360)
Previously we automatically re-ordered fields to put TS-only fields last. Don't do that - use definition order, unless a field order is specified with `#[estree(field_order(...))]`.
2025-05-29 02:20:54 +00:00
oxc-bot 01a4647a18 release(crates): v0.72.1 (#11345) 2025-05-28 16:54:01 +08:00
overlookmotel b8aa4e34db feat(napi/parser): parseAsync support raw transfer (#11335)
Previously, only `parseSync` supported raw transfer. Extend support to `parseAsync` too.

This requires:

1. A queue to limit the number of files being parsed simultaneously, to avoid the possibility of memory exhaustion.

2. A more complicated mechanism for recycling buffers, since now multiple buffers can be in use at the same time.
2025-05-28 02:01:55 +00:00
renovate[bot] 9e2686a62b chore(deps): lock file maintenance npm packages (#11289) 2025-05-26 11:55:59 +08:00
oxc-bot 3efc25fdeb release(crates): v0.72.0 (#11267) 2025-05-24 14:53:50 +08:00
overlookmotel 23182b811a feat(ast/estree): add phase field to ImportExpression in TS-ESTree AST (#11193)
Related to #10978. Add `phase` property to `ImportExpression` in TS-ESTree AST.

This aligns with ESTree spec, but does *not* align with TS-ESLint - TS-ESLint outputs a `CallExpression` with a `MetaProperty` as its `callee` instead.

We don't have the necessary information in our AST to match TS-ESLint, because we don't have the spans of `import`, `defer`, or `import.defer`, to use for the `MetaProperty`, or the `IdentifierName`s it contains.

This is not completely ideal, but I figure it's preferable to represent this syntax *somehow* in the AST, rather than completely ignoring it, in which case there's no way to distinguish between `import("x")`, `import.defer("x")`, and `import.source("x")`.

Presumably TS-ESLint will change their AST shape to conform to ESTree spec once these reach stage 4, so I don't think we should expend effort changing our AST to align with them in the meantime. TypeScript doesn't even have test cases for these (we'd know if they did, as we'd be failing them) - so I doubt these are popular constructs in TS.

`acorn-test262` submodule is bumped to include https://github.com/oxc-project/acorn-test262/pull/36 which adds the `phase` field to `ImportExpression`s in test snapshots.
2025-05-21 01:39:07 +00:00
overlookmotel c331eceb37 chore(deps): bump acorn-test262 (#11192)
Bump `acorn-test262` dependency to include the following tidy-up PRs:

* https://github.com/oxc-project/acorn-test262/pull/33
* https://github.com/oxc-project/acorn-test262/pull/34
* https://github.com/oxc-project/acorn-test262/pull/35
2025-05-20 18:13:56 +00:00
Boshen 9a2a6c6c37 chore(napi): remove --no-dts-cache 2025-05-20 15:20:12 +08:00
oxc-bot 4086e24083 release(crates): v0.71.0 (#11182) 2025-05-20 13:11:01 +08:00
overlookmotel d47b3057e8 feat(ast/estree): add phase field to ImportExpression in ESTree AST (#11165)
Related to #10978. Add `phase` property to `ImportExpression` in ESTree AST.

This property is *not* added in TS-ESTree, because TS-ESLint supports `import.defer(...)` and `import.source(...)`, but does not align with ESTree - it outputs a `CallExpression` with a `MetaProperty` as its `callee` instead.

We don't have the necessary information in our AST to match TS-ESLint, because we don't have the spans of `import`, `defer`, or `import.defer`, to use for the `MetaProperty`, or the `IdentifierName`s it contains.

Presumably TS-ESLint will change their AST shape to conform to ESTree spec once these reach stage 4, so I don't think we should expend and changing our AST to align with them in the meantime. TypeScript doesn't even have test cases for these (we'd know if they did, as we'd be failing them) - so I doubt these are popular constructs in TS.

`acorn-test262` submodule is bumped to include https://github.com/oxc-project/acorn-test262/pull/31.
2025-05-20 02:55:03 +00:00
overlookmotel 9e90e00f67 feat(ast_tools): introduce #[js_only] attr for struct fields and converters (#11160)
Codegen for `ESTree` impls supports a `#[ts]` attribute on struct fields which only appear in TS-ESTree AST. Add a `#[js_only]` attribute which does the same thing in reverse - indicates a field only appears in the JS ESTree AST, and not in TS-ESTree.

This allows removing a custom serializer and hacky workaround for `JSXOpeningFragment`.
2025-05-19 15:13:31 +00:00
overlookmotel 1bc8d29209 feat(ast/estree): add phase field to ImportDeclaration in ESTree AST (#11157)
Fixes #10978. Add `phase` property to `ImportDeclaration` in ESTree and TS-ESTree ASTs.

`ImportExpression` is not covered by this PR. That's more tricky as TS-ESLint already supports `import.defer(...)` and `import.source(...)`, but does not align with ESTree - it outputs a `MetaProperty` instead.

`acorn-test262` submodule is bumped to include https://github.com/oxc-project/acorn-test262/pull/30.
2025-05-19 15:13:31 +00:00
Boshen d67c9e583b feat(napi): bump napi to beta (#11159) 2025-05-19 15:05:34 +00:00
overlookmotel e92bf1f96b docs(napi): update docs for oxc-parser (#11156)
Update docs for `oxc-parser` NPM package to clarify:

1. TS AST now aligns with TS-ESLint.
2. We align with Acorn for plain JS ESTree.
3. We add a non-standard `hashbang` property to `Program`.
2025-05-19 14:15:40 +00:00
Yuji Sugiura 9775585021 refactor(regular_expression): Refactor regexp-modifiers support (#11142)
When I first implemented this proposal, it was Stage 3 and the specs
were not even fixed.
But for now, this spec is in Stage 4 and has been cleared up, so I've
updated it.

In the process, I have done some refactoring.

- Shorten code by `bitflags` like `RegExpFlags`
  - This requires some lines to make `ast_tools` works
- Update readme

NOTE: The basic behavior remains unchanged.
2025-05-19 17:54:38 +09:00
Boshen 3795eb6d98 fix(ci): use jsdelivr for all benchmark files (#11108)
https://github.blog/changelog/2025-05-08-updated-rate-limits-for-unauthenticated-requests/
2025-05-18 04:33:35 +00:00
overlookmotel 2b0a69fb6b perf(ast): re-order struct fields to reduce padding (#11056)
All our AST structs are `#[repr(C)]`, which gives us guaranteed stable memory layouts. This is essential for raw transfer, and helpful for other purposes too.

However, the downside is that we lose out on the automatic field-reordering that default `#[repr(Rust)]` provides, where structs are packed to minimize padding bytes.

This PR implements a similar field-reordering scheme, to get the same effect.

* `oxc_ast_tools` determines optimal field order for compact memory layout.
* `oxc_ast_tools` generates a file (`structs.rs`) which details the desired field order for each type.
* `#[ast]` proc macro follows the instructions in `structs.rs` and re-orders the fields.

This reduces the size of various AST types by 8 bytes. No type now has more than 7 padding bytes (previously e.g. `Function` had 15 bytes of padding).

Possible future improvements:

1. Get Rust Analyser to display original field order.
2. Remove `syn` dependency from `oxc_ast_macros` crate, to improve compile times. It should be possible to do all the AST manipulation using just `proc_macro` crate, by generating more code in `oxc_ast_tools`, so the macro's logic can be simpler.

Note: This PR doesn't add `syn` dependency, it was already there. But it makes it easier to remove it.
2025-05-16 03:43:22 +00:00
Dunqing 5dcd0f1213 perf(allocator/vec2): reorder RawVec fields (#11050)
According to `len` is more commonly used than `cap` and `a` is used less than any other field,  reorder `RawVec` fields to get the best performance.

<img width="721" alt="image" src="https://github.com/user-attachments/assets/c044e134-2d28-45a4-8d8d-91ec5166612f" />

I've tried putting `cap` before `len`, the performance is not as good as the current order, see https://github.com/oxc-project/oxc/pull/11050#issuecomment-2883194443
2025-05-15 22:33:43 +00:00
Dunqing c60382d181 feat(allocator/vec2): change len and cap fields from usize to u32 (#10884)
Related:
* #6488
* #9706

Finished first step(32 -> 24) of #9706.

Change `len` and `cap` fields from `usize` to `u32`, so that the `Vec` size can reduced size to `24`. Also, to avoid some unnecessary unit conversion. I changed many `RawVec` methods to take `u32` rather than `usize`.

The performance looks great now! And we reduced 1%-3% memory usage in the parser.
2025-05-15 22:14:01 +00:00
camchenry b9e51e24c4 perf(ast): reduce size of Comment to 16 bytes (#11062)
I noticed that most of `Comment` consisted of enums which were only 1 byte in size, but only used a few bits in each byte. There are few enough fields that we can actually store all of them in a single `u16` bit flag, which reduces the size of `Comment` from 24 bytes to 16 bytes.
2025-05-15 19:31:05 +00:00
Boshen 963167dc76 fix(napi): fix cfg feature on global_allocator 2025-05-15 22:20:42 +08:00
oxc-bot 58d2e6effe release(crates): v0.70.0 (#11061) 2025-05-15 21:55:38 +08:00