Commit Graph

28 Commits

Author SHA1 Message Date
Andrew Powell af2d26c073 fix(linter/astro): handle js --- after frontmatter in .astro files (#22091)
Resolves https://github.com/oxc-project/oxc/issues/22090

## Summary
Fixes Astro frontmatter parsing so it stops at the first valid closing
`---` fence, instead of the last `---` anywhere in the file. This
prevents `---` inside template/script content from being treated as a
frontmatter delimiter.

## Changes included
- Updated `AstroPartialLoader` frontmatter parsing to recognize only
standalone fence lines, require the opening fence at file start
(ignoring whitespace), and pair it with the next valid closing fence.
- Returned the frontmatter end offset from parsing so subsequent script
extraction starts after frontmatter.
- Added a regression test covering `.astro` content where later
JS/template strings include `---`.

LLM Disclosure: This was developed by an agent on this PR
https://github.com/shellscape/oxc/pull/1, but supervised by a human
(me).

---------

Co-authored-by: charliecreates[bot] <198680274+charliecreates[bot]@users.noreply.github.com>
Co-authored-by: CharlieHelps <charlie@charlielabs.ai>
Co-authored-by: Cameron <cameron.clark@hey.com>
2026-05-03 20:16:06 +01:00
camc314 b6bc421488 fix(linter): skip linting astro scripts with non JS script types (#21954)
fixes #21942

Astro script tags with non-JavaScript type values are now skipped by the partial loader, so import maps and JSON scripts are not parsed as TypeScript. The shared script attribute parser is reused with Svelte to avoid duplicating tag parsing logic.
2026-05-01 09:21:55 +00:00
mustafa0x aace797941 fix(linter): detect Svelte TS and module scripts correctly (#20819)
## Summary
- parse Svelte <script> attributes instead of broad substring checks
- detect both module and context="module" scripts when creating partial
JS sources
- add unit and CLI coverage for module/instance scripts in both JS and
TS

## Validation
- mise x -- cargo test -p oxlint lint_svelte_
- mise x -- cargo test -p oxc_linter partial_loader::svelte

## AI usage disclosure
This PR was prepared with AI assistance (Codex). I reviewed and take
responsibility for the final changes.

---------

Co-authored-by: Cameron <cameron.clark@hey.com>
2026-04-27 10:39:04 +01:00
bab 3d1e83a75b fix(linter): parse <script> tag attributes with curly braces in Svelte files (#21089)
fixes https://github.com/oxc-project/oxc/issues/20349

---------

Co-authored-by: Cameron Clark <cameron.clark@hey.com>
2026-04-23 18:27:52 +01:00
Connor Shea d8c039822a test(linter): Add HTML comment tests for astro and svelte as well. (#18315)
This was fixed a while ago, in #15202, but it wasn't being tested before
except for Vue files. So I've ported the test over to the other two as
well.
2026-01-21 10:21:57 +08:00
Boshen 66b8c022ab feat(parser): implement unambiguous module parsing for JS/TS files (#18124)
## Summary

- Implements speculative/unambiguous parsing for `.js`, `.jsx`, `.ts`, and `.tsx` files
- Instead of assuming module or script upfront, parses with `ModuleKind::Unambiguous` and upgrades to module mode when ESM syntax is detected
- ESM indicators: `import`, `export`, `import.meta` (NOT top-level await alone)
- Defers top-level await errors until module type is resolved
- Vue loader upgrades unambiguous scripts to module mode
- Updates linter tests to use explicit ESM extensions (`.mjs`/`.mts`) where needed

## Test plan

- [x] All parser tests pass
- [x] All linter tests pass
- [x] All semantic tests pass
- [x] Coverage conformance tests updated

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-01-17 13:40:28 +00:00
Boshen ba9c750f68 feat(span)!: use ModuleKind::CommonJS for .cjs and .cts file extensions (#18117)
## Summary

- Updates `SourceType::from_path()` to return `ModuleKind::CommonJS` for `.cjs`/`.cts` files (previously returned `ModuleKind::Script`)
- Fixes `eslint/no-eval` to check `!is_module()` instead of `is_script()` to handle both scripts and CommonJS (matching ESLint's `sourceType: "commonjs"` behavior)
- Fixes `eslint/no-redeclare` to run for both scripts and CommonJS files
- Updates tests to use proper CommonJS assertions

This follows up on #18089 which added `ModuleKind::CommonJS` support but didn't update the file extension mapping.

## Test plan

- [x] `cargo test -p oxc_span`
- [x] `cargo test -p oxc_linter`

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-01-17 09:10:49 +00:00
Liang Mi 377e90450f fix(linter): ignore script tag in code comment (#15202)
Partial loader tries parsing the `<script>` tag in the code comment
incorrectly

For example, we have a `.vue` file

```vue
<!-- <script setup lang="tsx"> -->
<script setup lang="ts">
const count = ref(0)
</script>
```

And the loader will regard these as script part

```
 -->
<script setup lang="ts">
const count = ref(0)
```

So this PR added some `Finder`s for code comment to ignore the
`<script>` in code comment, also works on `.svelte` and `.astro` files
2025-11-01 12:46:40 +00:00
Boshen 34d3cde705 fix(rust): fix clippy issues (#13540) 2025-09-04 07:00:33 +00:00
Sysix 077abdf261 refactor(linter): introduce ContextSubHost for cross script block analyse (#12724)
Another approach to https://github.com/oxc-project/oxc/pull/12541 stack.
Because `vue/valid-define-emit` and other rules required the semantics of the other script block.

## The Goal:
`Linter.run` should run with the complete file context. In `vue` files and others, there can be multiple Semantics / Module Records.
Because `vue` requires some magic compiler rules, the linter should have access to the complete file.
This will also fix the offset bug in #12758. ~~**Don't** merge both stacks without rebasing.~~

I do not like the loop part. Maybe you guys have some better ideas.

---

<img width="1160" height="422" alt="benchmark results" src="https://github.com/user-attachments/assets/88702a01-eeb2-4a4f-8d80-c5236d3fa8cc" />
2025-08-27 02:02:30 +00:00
Sysix 209d006c9f fix(linter): parse vue lang attribute without quotes (#12517) 2025-07-25 13:17:03 +00:00
Sysix 4621872e5a fix(linter): parse second script block for svelte files (#12390)
https://svelte.dev/tutorial/svelte/module-exports

I could not find a better doc.
Now the Vue parser and svelte parser are almost similar. Maybe refactor it to share the `script` logic.
2025-07-18 14:04:31 +00:00
Sysix eadc359ea0 fix(linter): correct source text for vue files having script attributes containig ">" char inside (#12375) 2025-07-18 09:41:08 +00:00
overlookmotel 625870f445 style(linter): re-order imports (#12334)
Pure refactor. Re-order imports in `oxc_linter` crate to be in standard order.
2025-07-16 19:44:06 +00:00
Boshen 5d9344fbfa refactor(rust)!: clippy avoid-breaking-exported-api = false (#11088) 2025-05-17 02:21:26 +00:00
Boshen 48c542d4d4 fix(linter): skip linting vue <script> where lang is not js / ts (#10740) 2025-05-01 08:18:44 +00:00
overlookmotel be048d20e4 perf(linter): remove write! macro where unnecessary (#10232)
Same as #10230, but for linter.

Replace usages of `write!` macro with either `fmt.write_str(...)` for static strings or `Display::fmt` / `Debug::fmt` for other values, where it's not being used to concatenate multiple values.

`Formatter::write_str` is more performant, as it avoids various checks. `Display::fmt` / `Debug::fmt` may also perform a little better in some cases, and will be equivalent in others. But in all cases it should be better for compile times, due to avoiding macro expansion and trait resolution.
2025-04-04 15:07:39 +00:00
renovate a788a64649 chore(deps): update dependency rust to v1.86.0 (#10196)
This PR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [rust](https://redirect.github.com/rust-lang/rust) | minor | `1.85.1` -> `1.86.0` |

---

### Release Notes

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

### [`v1.86.0`](https://redirect.github.com/rust-lang/rust/blob/HEAD/RELEASES.md#Version-1860-2025-04-03)

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

\==========================

<a id="1.86.0-Language"></a>

## Language

-   [Stabilize upcasting trait objects to supertraits.](https://redirect.github.com/rust-lang/rust/pull/134367)
-   [Allow safe functions to be marked with the `#[target_feature]` attribute.](https://redirect.github.com/rust-lang/rust/pull/134090)
-   [The `missing_abi` lint now warns-by-default.](https://redirect.github.com/rust-lang/rust/pull/132397)
-   Rust now lints about double negations, to catch cases that might have intended to be a prefix decrement operator (`--x`) as written in other languages. This was previously a clippy lint, `clippy::double_neg`, and is [now available directly in Rust as `double_negations`.](https://redirect.github.com/rust-lang/rust/pull/126604)
-   [More pointers are now detected as definitely not-null based on their alignment in const eval.](https://redirect.github.com/rust-lang/rust/pull/133700)
-   [Empty `repr()` attribute applied to invalid items are now correctly rejected.](https://redirect.github.com/rust-lang/rust/pull/133925)
-   [Inner attributes `#![test]` and `#![rustfmt::skip]` are no longer accepted in more places than intended.](https://redirect.github.com/rust-lang/rust/pull/134276)

<a id="1.86.0-Compiler"></a>

## Compiler

-   [Debug-assert that raw pointers are non-null on access.](https://redirect.github.com/rust-lang/rust/pull/134424)
-   [Change `-O` to mean `-C opt-level=3` instead of `-C opt-level=2` to match Cargo's defaults.](https://redirect.github.com/rust-lang/rust/pull/135439)
-   [Fix emission of `overflowing_literals` under certain macro environments.](https://redirect.github.com/rust-lang/rust/pull/136393)

<a id="1.86.0-Platform-Support"></a>

## Platform Support

-   [Replace `i686-unknown-redox` target with `i586-unknown-redox`.](https://redirect.github.com/rust-lang/rust/pull/136698)
-   [Increase baseline CPU of `i686-unknown-hurd-gnu` to Pentium 4.](https://redirect.github.com/rust-lang/rust/pull/136700)
-   New tier 3 targets:
    -   [`{aarch64-unknown,x86_64-pc}-nto-qnx710_iosock`](https://redirect.github.com/rust-lang/rust/pull/133631).
        For supporting Neutrino QNX 7.1 with `io-socket` network stack.
    -   [`{aarch64-unknown,x86_64-pc}-nto-qnx800`](https://redirect.github.com/rust-lang/rust/pull/133631).
        For supporting Neutrino QNX 8.0 (`no_std`-only).
    -   [`{x86_64,i686}-win7-windows-gnu`](https://redirect.github.com/rust-lang/rust/pull/134609).
        Intended for backwards compatibility with Windows 7. `{x86_64,i686}-win7-windows-msvc` are the Windows MSVC counterparts that already exist as Tier 3 targets.
    -   [`amdgcn-amd-amdhsa`](https://redirect.github.com/rust-lang/rust/pull/134740).
    -   [`x86_64-pc-cygwin`](https://redirect.github.com/rust-lang/rust/pull/134999).
    -   [`{mips,mipsel}-mti-none-elf`](https://redirect.github.com/rust-lang/rust/pull/135074).
        Initial bare-metal support.
    -   [`m68k-unknown-none-elf`](https://redirect.github.com/rust-lang/rust/pull/135085).
    -   [`armv7a-nuttx-{eabi,eabihf}`, `aarch64-unknown-nuttx`, and `thumbv7a-nuttx-{eabi,eabihf}`](https://redirect.github.com/rust-lang/rust/pull/135757).

Refer to Rust's \[platform support page]\[platform-support-doc]
for more information on Rust's tiered platform support.

<a id="1.86.0-Libraries"></a>

## Libraries

-   The type of `FromBytesWithNulError` in `CStr::from_bytes_with_nul(bytes: &[u8]) -> Result<&Self, FromBytesWithNulError>` was [changed from an opaque struct to an enum](https://redirect.github.com/rust-lang/rust/pull/134143), allowing users to examine why the conversion failed.
-   [Remove `RustcDecodable` and `RustcEncodable`.](https://redirect.github.com/rust-lang/rust/pull/134272)
-   [Deprecate libtest's `--logfile` option.](https://redirect.github.com/rust-lang/rust/pull/134283)
-   [On recent versions of Windows, `std::fs::remove_file` will now remove read-only files.](https://redirect.github.com/rust-lang/rust/pull/134679)

<a id="1.86.0-Stabilized-APIs"></a>

## Stabilized APIs

-   [`{float}::next_down`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_down)
-   [`{float}::next_up`](https://doc.rust-lang.org/stable/std/primitive.f64.html#method.next_up)
-   [`<[_]>::get_disjoint_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_mut)
-   [`<[_]>::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.get_disjoint_unchecked_mut)
-   [`slice::GetDisjointMutError`](https://doc.rust-lang.org/stable/std/slice/enum.GetDisjointMutError.html)
-   [`HashMap::get_disjoint_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_mut)
-   [`HashMap::get_disjoint_unchecked_mut`](https://doc.rust-lang.org/std/collections/hash_map/struct.HashMap.html#method.get_disjoint_unchecked_mut)
-   [`NonZero::count_ones`](https://doc.rust-lang.org/stable/std/num/struct.NonZero.html#method.count_ones)
-   [`Vec::pop_if`](https://doc.rust-lang.org/std/vec/struct.Vec.html#method.pop_if)
-   [`sync::Once::wait`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait)
-   [`sync::Once::wait_force`](https://doc.rust-lang.org/stable/std/sync/struct.Once.html#method.wait_force)
-   [`sync::OnceLock::wait`](https://doc.rust-lang.org/stable/std/sync/struct.OnceLock.html#method.wait)

These APIs are now stable in const contexts:

-   [`hint::black_box`](https://doc.rust-lang.org/stable/std/hint/fn.black_box.html)
-   [`io::Cursor::get_mut`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.get_mut)
-   [`io::Cursor::set_position`](https://doc.rust-lang.org/stable/std/io/struct.Cursor.html#method.set_position)
-   [`str::is_char_boundary`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.is_char_boundary)
-   [`str::split_at`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at)
-   [`str::split_at_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_checked)
-   [`str::split_at_mut`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut)
-   [`str::split_at_mut_checked`](https://doc.rust-lang.org/stable/std/primitive.str.html#method.split_at_mut_checked)

<a id="1.86.0-Cargo"></a>

## Cargo

-   [When merging, replace rather than combine configuration keys that refer to a program path and its arguments.](https://redirect.github.com/rust-lang/cargo/pull/15066/)
-   [Error if both `--package` and `--workspace` are passed but the requested package is missing.](https://redirect.github.com/rust-lang/cargo/pull/15071/) This was previously silently ignored, which was considered a bug since missing packages should be reported.
-   [Deprecate the token argument in `cargo login` to avoid shell history leaks.](https://redirect.github.com/rust-lang/cargo/pull/15057/)
-   [Simplify the implementation of `SourceID` comparisons.](https://redirect.github.com/rust-lang/cargo/pull/14980/) This may potentially change behavior if the canonicalized URL compares differently in alternative registries.

<a id="1.86.0-Rustdoc"></a>

## Rustdoc

-   [Add a sans-serif font setting.](https://redirect.github.com/rust-lang/rust/pull/133636)

<a id="1.86.0-Compatibility-Notes"></a>

## Compatibility Notes

-   [The `wasm_c_abi` future compatibility warning is now a hard error.](https://redirect.github.com/rust-lang/rust/pull/133951)
    Users of `wasm-bindgen` should upgrade to at least version 0.2.89, otherwise compilation will fail.
-   [Remove long-deprecated no-op attributes `#![no_start]` and `#![crate_id]`.](https://redirect.github.com/rust-lang/rust/pull/134300)
-   [The future incompatibility lint `cenum_impl_drop_cast` has been made into a hard error.](https://redirect.github.com/rust-lang/rust/pull/135964) This means it is now an error to cast a field-less enum to an integer if the enum implements `Drop`.
-   [SSE2 is now required for "i686" 32-bit x86 hard-float targets; disabling it causes a warning that will become a hard error eventually.](https://redirect.github.com/rust-lang/rust/pull/137037)
    To compile for pre-SSE2 32-bit x86, use a "i586" target instead.

<a id="1.86.0-Internal-Changes"></a>

## Internal Changes

These changes do not affect any public interfaces of Rust, but they represent
significant improvements to the performance or internals of rustc and related
tools.

-   [Build the rustc on AArch64 Linux with ThinLTO + PGO.](https://redirect.github.com/rust-lang/rust/pull/133807)
    The ARM 64-bit compiler (AArch64) on Linux is now optimized with ThinLTO and PGO, similar to the optimizations we have already performed for the x86-64 compiler on Linux. This should make it up to 30% faster.

</details>

---

### Configuration

📅 **Schedule**: 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:eyJjcmVhdGVkSW5WZXIiOiIzOS4yMjcuMyIsInVwZGF0ZWRJblZlciI6IjM5LjIyNy4zIiwidGFyZ2V0QnJhbmNoIjoibWFpbiIsImxhYmVscyI6W119-->
2025-04-04 07:43:00 +00:00
camc314 fba11d2704 style(linter): remove unnecessary semi-colons (#10207) 2025-04-03 19:30:55 +00:00
camchenry d8e49a15d9 refactor(linter): compute lintable extensions at compile time (#10090)
Previously, we were wasting some time creating a `Vec` at runtime with the lintable extensions, which is all of the JS/TS extensions plus other frameworks extensions like `.vue`. Now, we precompute this as a static string slice at compile time. This also ensures that we are using the same extensions list between `oxlint` and the language server too. Theoretically this is a very minor perf win possibly?
2025-03-29 12:38:23 +00:00
Boshen e9565c98a1 fix(linter): parse vue custom tag that starts with script (#9887)
fixes #9837
2025-03-19 06:36:18 +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
Boshen 9f361819b9 refactor(rust): apply cllippy::nursery rules (#9232) 2025-02-20 01:51:04 +00: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
overlookmotel 3858221f45 refactor(global): sort imports (#7883)
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.
2024-12-14 15:07:21 +00:00
Boshen 7fb9d47460 style(rust): cargo +nightly fmt (#7877) 2024-12-14 06:03:31 +00:00
camchenry f6a3450710 fix(linter): get correct source offsets for astro files (#6196)
Previously, we reported the `source_text` of an Astro file correctly, but the `start` offset was incorrectly set to before the `---` of the frontmatter. The start value now correctly points to the end of the split.
2024-10-01 03:35:58 +00:00
DonIsaac ea908f742d refactor(linter): consolidate file loading logic (#6130)
# Human Description
Low on time, so this one is short.
- consolidate source file and partial loader logic into `loader` module. I have more plans for this.
- ~LSP no longer uses `VALID_EXTENSIONS`, so now `.d.ts` files (and the like) will be linted as well~ LSP does not respect `.gitignore` files, so this change was reverted.

# AI Description
## Refactor Loader and Partial Loader

This PR refactors the loader and partial loader functionality in the oxc_linter crate:

* Introduce a new `Loader` struct with methods for checking if a file can be loaded and loading file contents
* Move `partial_loader` module to `loader/partial_loader`
* Rename `JavaScriptSource` to `source.rs` and move it to the `loader` module
* Update `JavaScriptSource` to use `u32` for `start` offset instead of `usize`
* Refactor `IsolatedLintHandler` to use the new `Loader`
* Update imports and module references throughout the codebase

This change improves the organization of the loader-related code and provides a more unified interface for loading different file types.
2024-09-29 02:48:01 +00:00