It is a compilation error to load `generated::raw_transfer_constants` on 32-bit platforms, and JS plugins are only supported on little-endian 64-bit platforms.
Feature gate all JS plugin-related code so it does not get loaded on unsupported platforms. This should allow `napi/oxlint` to be built as WASM32.
Pure refactor. Move `wrap_*` functions into separate `external_linter.rs` module, and add a `create_external_linter` function which wraps both JS callbacks.
This is necessary so we can feature gate loading the module (next PR #13711).
Amend error messages related to JS plugins. "external" is the term we use in the codebase, but it probably wouldn't make much sense to end users. Use the term "JS plugin" instead.
Surprisingly, TSDown inlines the constants from `constants.mjs` into the bundled code, regardless of whether the file is listed as `external` in TSDown config. So remove it from `external` list and don't copy the file into `dist`.
Rename `napi/oxlint2` to `napi/oxlint`. This is in preparation for migrating code from `napi/oxlint` into `apps/oxlint`. This PR is incidental, but renaming everything in this PR will reduce diff when moving code over to `apps/oxlint`.
part of #13646
## Summary
This PR converts the Control Flow Graph (CFG) functionality in `oxc_semantic` from runtime checks to a compile-time cargo feature, eliminating runtime overhead when CFG is not needed.
## Changes
- Added `cfg` cargo feature to `oxc_semantic/Cargo.toml` with `oxc_cfg` as optional dependency
- Feature-gated all CFG-related code using `#[cfg(feature = "cfg")]`
- Updated `oxc_linter` to enable the `cfg` feature (since it requires CFG)
- Made the `control_flow!` macro work correctly with and without the feature
## Benefits
- **Performance**: Eliminates runtime `Option<CFG>` checks when feature is disabled
- **Binary size**: Smaller binaries for crates that don't need CFG
- **Cleaner API**: CFG methods only available when feature is enabled
## Test Plan
- [x] All existing tests pass with `cargo test -p oxc_semantic --features cfg`
- [x] `oxc_linter` builds and works correctly (it enables the feature)
- [x] Feature is backward compatible - existing code continues to work
🤖 Generated with [Claude Code](https://claude.ai/code)
Remove `oxlint2` Cargo feature from `oxlint` and `oxc_linter` crates.
Now that enabling `fixed_size` Cargo feature of `oxc_allocator` doesn't change behavior, we don't need the feature gate. The incompatibility of `tokio` with WASM has been resolved by #13647.
`tokio` is required to run `load_plugin` JS callback, to load a JS plugin.
Move this code into `napi/oxlint2`, so can remove the `tokio` dependency from `oxc_linter` crate.
Add `--experimental-js-plugins` CLI option to `oxlint`.
At present this option is hidden in the CLI's `--help` output.
If this option is not present, `ExternalLinter` is dropped, which disables JS plugins.
Therefore, JS plugins are only enabled, and code related to them (e.g. fixed size allocators) runs only if both:
1. `oxlint` is run via `napi/oxlint2`.
2. `--experimental-js-plugins` CLI option is present.
This prepares the way for switching `oxlint` over to `napi/oxlint2`.
`napi/oxlint2` will soon become the default version of `oxlint`. It will support JS plugins, but only behind an `--experimental-js-plugins` option. Most users will not be using JS plugins.
Therefore, don't load the code for loading/running JS plugins upfront. Instead, lazy-load the code when Rust first calls into JS asking it to load a JS plugin. This means the addition of JS plugin support should not affect perf for users who aren't using JS plugins.
Pure refactor. In `napi/oxlint2`, split up code into more files, and move all code related to JS plugins (almost all of it) into `plugins` directory.
None of the code is altered, it's just moved around. Only code change is adding a few more comments and 1 type annotation.
This prepares the way for:
1. Lazy-loading the JS plugin code (next PR).
2. Adding a 2nd version of visitor which doesn't use lazy deserialization.
Alter TSDown settings for `napi/oxlint2`.
We intended the code to be minified, but not to have symbols mangled, or whitespace removed, so it remains somewhat readable. It seems that TSDown may have changed how it handles these options, as `minify: { compress: true }` now turns on mangling and whitespace removal.
Alter the TSDown options to get the intended output.
Pure refactor. All these generated modules have no exports, so importing them with `pub mod` is misleading - there is nothing to make public. Import them with plain `mod` instead.
```diff
mod generated {
- pub mod assert_layouts;
+ mod assert_layouts;
}
```
Implement support for disable directives (like `// oxlint-disable-next-line`) for custom plugin rules.
The full name of the rule (including plugin name) is required in the disable comment e.g.:
```js
// oxlint-disable-next-line my-plugin/my-rule
```
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: camc314 <18101008+camc314@users.noreply.github.com>
Co-authored-by: Cameron Clark <cameron.clark@hey.com>
The AST on JS side in linter JS plugins previously had `start` and `end` as UTF-8 offsets.
Convert the AST to UTF-16 offsets prior to transferring it to JS, and convert offsets in any errors/warnings returned from JS side back to UTF-8 before creating `OxcDiagnostic`s from them.
The tricky part is that it's not possible to mutate the AST (convert offsets to UTF-16) while `Semantic` is alive, because you can't obtain a `&mut Program` due to aliasing rules. Work around this with some pointer juggling and by dropping `Semantic` before creating a `&mut Program`.
This is a bit sketchy, but is not (I believe) UB. Hopefully we can remove the need for this workaround later on by performing offset conversion during serialization / raw transfer deserialization, and so avoid the need to mutate the AST.
`ContextSubHost` does not share `Semantic` with any other structure, so `Rc<Semantic>` is unnecessary overhead. Make it contain owned `Semantic` instead.
Here we are not aligning every diagnostic to the source text offset. Later we could cross-reference with an extra method `push_diagnostic_without_adjustment` or something similar.
#13173 enabled Oxlint for all the repo, but we currently skip `napi` directory.
Fix all errors that Oxlint flags in `napi/oxlint2`.
We currently can't turn on Oxlint for the directory, because `oxlint-disable` comments don't work for type-aware rules, but we should be able to once that's fixed.
Same as #13184.
#13173 enabled Oxlint for all the repo, but we currently skip `napi` directory.
Fix all errors that Oxlint flags in `napi/parser`.
We currently can't turn on Oxlint for the directory, because `oxlint-disable` comments don't work for type-aware rules, but we should be able to once that's fixed.
closes#13174
This should reduce sourcemap memory usage by a huge amount.
These tokens were added in esbuild for code coverage: https://github.com/evanw/esbuild/commit/c4d45e6b5766b1a1b56bf24b7dadb240de91332b
But esbuild has an optimization to not generate these tokens when `}` is not on the same line
```
if class.CloseBraceLoc.Start > class.BodyLoc.Start {
p.addSourceMapping(class.CloseBraceLoc)
}
```
We should revisit these tokens later in the future.
Tiny perf optimization.
Reduce complexity of maths by doing as much calculation as possible using consts.
Shaves off 1 operation! https://godbolt.org/z/5h4hzznxs
This change does not alter the result. `data_offset + RAW_METADATA_SIZE` couldn't overflow because `data_offset` was derived from a `u32`, and this code (raw transfer) is only run on 64-bit systems, so there's plenty of headroom in `usize`. But it does make it easier to support 32-bit in future.
Pure refactor. When this code was written, `usize::is_multiple_of` was not available in our MSRV. Now it is, so use it instead of writing the same function ourselves.
Refactor only. Move block of code for creating a JS buffer out into its own function. This code is going to get more complicated to accommodate JS plugins on multiple threads.
Now every `ignorePatterns` configuration in nested configuration are respected.
Before, only `ignorePatterns`, which are located in the base-configuration of the project, would be respected.
Closes#11067Closes#12857Closes#11969