fix(linter): detect Svelte TS and module scripts correctly#20819
fix(linter): detect Svelte TS and module scripts correctly#20819camc314 merged 10 commits intooxc-project:mainfrom
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9900f83b6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
camc314
left a comment
There was a problem hiding this comment.
Do you mind explaining a little bit more about this change - was something not working previously that this now fixes?
|
This PR fixes real Svelte parsing correctness issues in oxlint’s partial-loader path. Previously, TypeScript detection used a broad This change makes parsing attribute-aware ( |
|
@mustafa0x do you mind sharing a real-world example of when it didn't work before? |
|
Thanks for the follow-up. Yes, this fixes a real behavior gap, and I validated it with a negative regression check. Before this PR, if !self.source_text[*pointer..].starts_with([' ', '>']) {
return self.parse_script(pointer);
}That means valid Svelte tags like these could be skipped: <script
lang="ts">
debugger;
</script><script context="module">
debugger;
</script>So we could silently miss diagnostics for legitimate What this PR changesThe boundary check now accepts any whitespace (space/tab/newline) or let is_script_tag_boundary = self.source_text[*pointer..]
.chars()
.next()
.is_some_and(|ch| ch.is_whitespace() || ch == '>');It also keeps the existing Regression proof (negative test)I validated this by doing a throwaway revert in a temporary worktree:
mise x -- cargo test -p oxc_linter partial_loader::svelteResult: tests fail exactly where expected:
Both failed with So this is not just refactoring; it closes a real parsing correctness hole and the new regressions are effective at catching it. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: e30a331e93
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0b716135f1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
Pull request overview
Improves Svelte <script> parsing in the partial loader so TypeScript and module/context-module scripts are detected reliably, and adds regression coverage to ensure both module + instance blocks are linted with correct locations.
Changes:
- Parse Svelte
<script>attributes to detectlang,module, andcontext="module"instead of substring checks. - Ensure extracted partial JS sources use the correct
SourceType(TS vs JS and module semantics). - Add unit + CLI tests (and fixtures) covering module/instance scripts in JS and TS.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/oxc_linter/src/loader/partial_loader/svelte.rs | Adds attribute parsing for <script> blocks and expands unit tests for module/context-module + TS handling. |
| apps/oxlint/src/tester.rs | Adds a helper to capture non-silent CLI output for assertion-based tests. |
| apps/oxlint/src/lint.rs | Adds CLI regression tests asserting module + instance scripts both produce diagnostics with correct positions. |
| apps/oxlint/fixtures/cli/svelte/module-script.svelte | New fixture for <script module> + instance script. |
| apps/oxlint/fixtures/cli/svelte/context-module-script.svelte | New fixture for <script context="module"> + instance script. |
| apps/oxlint/fixtures/cli/svelte/context-module-script-ts.svelte | New fixture for context-module + instance scripts using lang="ts". |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 934ebf107f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
Svelte support in |
|
@janosh you can also test my up-to-date fork for svelte |
Merging this PR will not alter performance
Comparing Footnotes
|
# Oxlint ### 💥 BREAKING CHANGES - 502e804 ast: [**BREAKING**] Reduce size of `TSTypePredicateName` (#21711) (overlookmotel) - 5651539 ast: [**BREAKING**] Reduce size of `JSXExpression` (#21710) (overlookmotel) - c44e280 ast: [**BREAKING**] Reduce size of `ArrayExpressionElement` (#21709) (overlookmotel) ### 🚀 Features - b4acdbd linter/vue: Implement no-deprecated-delete-set rule (#21766) (bab) - 613bfef linter: Split jest/prefer-to-contain into a jest and a vitest rule. (#21821) (connorshea) - c629719 linter/vue: Implement no-deprecated-events-api rule (#21793) (Alex Peshkov) - f2a8528 linter: Split jest/require-top-level-describe rule into a Jest and a Vitest rule. (#21822) (connorshea) - ea4b358 linter: Split jest/prefer-todo into a shared rule and a vitest-specific rule. (#21820) (connorshea) - 3a66819 linter: Split jest/no-mocks-import into vitest/no-mocks-import (#21818) (camchenry) - 0b3ffce linter: Split jest/no-large-snapshots into vitest/no-large-snapshots (#21814) (camchenry) - d1cf22e linter: Split jest/no-interpolation-in-snapshots into vitest/no-interpolation-in-snapshots (#21812) (camchenry) - bb0c359 linter: Split jest/no-identical-title into vitest/no-identical-title (#21810) (camchenry) - c26ea41 linter: Split jest/no-hooks into vitest/no-hooks (#21809) (camchenry) - 46b32f2 linter: Split jest/no-focused-tests into vitest/no-focused-tests (#21804) (camchenry) - acf41a8 linter: Split jest/no-duplicate-hooks into vitest/no-duplicate-hooks (#21803) (camchenry) - 54d787f linter: Split jest/no-disabled-tests into vitest/no-disabled-tests (#21802) (camchenry) - 9c9a676 linter/vue: Implement no-deprecated-data-object-declaration rule (#21764) (bab) - 4445855 linter: Split `jest/no-conditional-in-test` into `vitest/no-conditional-in-test` (#21763) (camchenry) - b8604de linter: Split `jest/no-conditional-expect` into `vitest/no-conditional-expect` (#21762) (camchenry) - 0dbd650 linter: Split `jest/no-commented-out-tests` into `vitest/no-commented-out-tests` (#21761) (camchenry) - 7f1a97c linter: Split `jest/no-alias-methods` into `vitest/no-alias-methods` (#21760) (camchenry) - eb97c49 linter: Split `jest/max-nested-describe` into `vitest/max-nested-describe` (#21759) (camchenry) - d870cad linter: Split `jest/max-expects` into `vitest/max-expects` (#21758) (camchenry) - 1b97124 linter/vue: Implement no-deprecated-vue-config-keycodes rule (#21699) (bab) - 5f81883 linter/eslint: Implement `func-name-matching` rule (#21708) (Mikhail Baev) - 348f46c linter: Add `respectEslintDisableDirectives` option (#21384) (Christian Vuerings) - 63ec351 linter: Support nested vite+ config discovery (#21638) (camc314) - 560feb4 linter: Introduce `Vite` variant to `DiscoveredConfigFile` (#21637) (camc314) - 07dc41e linter/eslint: Implement `no-underscore-dangle` rule (#21630) (Paul-Arthur THIERY) - e270d54 linter/react: Impl react/no-did-update-set-state (#17322) (Kenzo Wada) - ca81199 linter/react: Implement `forbid-component-props` rule (#20005) (Mikhail Baev) - 6776403 linter/branches-sharing-code: Move rule from nursery to pedantic (#21621) (camc314) - ce7a4dc linter/no-unreachable: Move rule from nursery to correctness (#21618) (camc314) - e3b5e78 linter/getter-return: Move rule from nursery to correctness (#21617) (camc314) - d3a7e9a linter/unicorn: Implement suggestion for `no-useless-iterator-to-array` rule (#21610) (Mikhail Baev) - a0c883c oxlint/lsp: Add vite plus version to server info (#21587) (Sysix) - 67ff860 linter/no-unknown-property: Support React 19 `precedence` prop (#21590) (João Pedro Schmitz) ### 🐛 Bug Fixes - aace797 linter: Detect Svelte TS and module scripts correctly (#20819) (mustafa0x) - 3612db1 linter/prefer-default-parameters: Skip reporting on object/class setters (#21836) (camc314) - 28c3521 oxlint/lsp: Remove overlapping edits for `source.fixAllDangerous.oxc` code action (#21785) (Sysix) - 705a82c linter/no-non-null-asserted-nullish-coalescing: Add fixer (#21827) (yyh) - 33f5535 linter: Add checks that `Program` is in current allocator chunk before JS plugins linting (#21774) (overlookmotel) - d122877 linter/no-extra-non-null-assertions: Add fixer (#21744) (yyh) - 37f0731 linter: `with_plugin_vitest(true)` working realiable in test mode (#21769) (Said Atrahouch) - e42e6a6 linter/role-supports-aria-props: False positive with `combobox` and `haspopup` (#21725) (Leonabcd123) - e24324f linter: Iframe-has-title false positive for template literals (#21714) (Leonabcd123) - 41a6510 linter/vitest/hoisted-apis-on-top: Only check first member (#20068) (Sidharth Vinod) - 98ed888 linter: Check initializer for allowConstantExport in only-export-components (#20608) (Eyüp Can Akman) - 1946e8b linter: Avoid applying override plugin categories to eslint rules (#21521) (bab) - 3d1e83a linter: Parse `<script>` tag attributes with curly braces in Svelte files (#21089) (bab) - bc6ade5 linter: Report actual disable directive prefix (#21682) (camc314) - bf84466 linter: Respect category settings in overrides (#19411) (Connor Shea) - 52ecb45 linter/vitest: Don't treat `test.extend` or `it.extend` as test functions (#21668) (Said Atrahouch) - aa1a00c linter: Support jsx-a11y attributes setting in anchor-is-valid rule (#21665) (camchenry) - 30e0ad3 linter/prefer-default-parameters: Preserve TS annotations in fixer (#21655) (camc314) - 8c425db linter: Allow string for jest version in config schema (#21649) (camc314) - 3617864 linter/react/display-name: Fix false positive for named default class (#21643) (Mikhail Baev) - f3a02cc linter/no-non-null-assertion: Improve diagnostic message (#21616) (Cameron) - c2ada2c linter: Make `--fix-dangerously` fix dangerous fixes and suggestions as documented (#13366) (Ulrich Stark) - 8265ed9 linter/sort-keys: Handle CRLF separated groups (#21608) (camc314) - 96c559e linter/no-shadow: Add note explaining enum member shadowing (#21607) (camc314) - 3b49389 linter: No-irregular-whitespace: add config options (#21559) (camchenry) ### ⚡ Performance - cdc9eae oxlint/lsp: Avoid clones on lsp options deserializion (#21748) (Sysix) - be2db80 linter/sort-keys: Reduce allocations (#21560) (camchenry) ### 📚 Documentation - 453d647 linter: Remove now-unnecessary compatibility notes from shared Jest/Vitest rules. (#21826) (connorshea) - b1574a2 linter: Fix the configuration docs for no-underscore-dangle rule. (#21801) (connorshea) - 6946aee linter: Remove no-longer-relevant documentation about vitest compatibility from shared Jest/Vitest rules. (#21799) (connorshea) - 0652ea2 linter: Misc grammar cleanup for Vitest rules. (#21755) (connorshea) - 99f0b68 linter: Improve docs for `vitest/require-mock-type-parameters` rule. (#21754) (connorshea) - 9e2796b linter: Improve the docs for the `vitest/hoisted-apis-on-top` rule. (#21753) (connorshea) - 2ccede2 linter: Improve function usage examples in doc comments (#21718) (overlookmotel) - 43adae9 linter: Add version section to rules page (#21601) (camchenry) - d15dad2 linter: Export rule version metadata (#21588) (Old Autumn) # Oxfmt ### 💥 BREAKING CHANGES - 502e804 ast: [**BREAKING**] Reduce size of `TSTypePredicateName` (#21711) (overlookmotel) - 5651539 ast: [**BREAKING**] Reduce size of `JSXExpression` (#21710) (overlookmotel) - c44e280 ast: [**BREAKING**] Reduce size of `ArrayExpressionElement` (#21709) (overlookmotel) ### 🚀 Features - 3bc54a9 oxfmt: Respect nested config for `--stdin-filepath` (#21627) (leaysgur) - 144f27a oxfmt: Respect ignore settings for `--stdin-filepath` (#21625) (leaysgur) - 81c7ae4 oxfmt/lsp: Add vite plus version to server info (#21586) (Sysix) ### 🐛 Bug Fixes - 477435b formatter/sort_imports: Keep leading blank line when decreasing group transitions (#21835) (leaysgur) - 38d1e82 oxfmt/lsp: Format non `file://` URIs without a authority (#21647) (Sysix) - 5eb8e2b formatter/sort_imports: Preserve blank lines around ignored side-effect imports (#21692) (leaysgur) - 0dce3c6 oxfmt: Handle invalid `overrides` config without panic (#21661) (Yuji Sugiura) - 9f82ed4 formatter: Escape backticks in JSDoc inline code spans (#21577) (bab) ### ⚡ Performance - db6c603 oxfmt/lsp: Avoid clones on lsp options deserializion (#21749) (Sysix) - 6a96c76 formatter: Avoid heap alloc for jsdoc delimiter (#21597) (leaysgur) --------- Co-authored-by: Boshen <1430279+Boshen@users.noreply.github.com> Co-authored-by: Cameron Clark <cameron.clark@hey.com>
|
When plugin support is added, I wonder how this will interact with eslint-plugin-svelte. I wonder if it's going to cause duplicate checks |
|
@camc314 Thanks for the merge! Should I continue opening small and self-contained PRs for svelte? Or pause for now, especially as a new plugin system is impending? |
Thanks for contributing! Any bug fixes would be much appreciated. But for new features, let's hold until the embedded framework plugins are released! Thanks! |
possibly - we'll probably add an optin to disable the built in svelte linting - TBD |
Summary
Validation
AI usage disclosure
This PR was prepared with AI assistance (Codex). I reviewed and take responsibility for the final changes.