fix(linter): preserve source text for JS plugin ignore fixes - #25280
Merged
Conversation
Merging this PR will not alter performance
Comparing Footnotes
|
camc314
approved these changes
Aug 9, 2026
graphite-app Bot
pushed a commit
that referenced
this pull request
Aug 10, 2026
# Oxlint ### 💥 BREAKING CHANGES - a33788e ast: [**BREAKING**] Group class heritage into `ClassHeritage` (#25360) (camc314) - 5c5cdcd ast: [**BREAKING**] Narrow `TSInterfaceHeritage::expression` to TSTypeName (#24360) (camc314) - 6be314f ast: [**BREAKING**] Remove duplicated `VariableDeclarator::kind` (#25319) (camc314) - 44fd320 ast: [**BREAKING**] Split TS external modules & Namespace Declarations (#25284) (camc314) ### 🚀 Features - ccb8fe8 linter/jsdoc: Implement `no-blank-blocks` rule (#25207) (Mikhail Baev) - d4a897c linter/eslint: Implement `one-var` rule (#24470) (Cole Ellison) - 5ab9340 linter/jsx-a11y/anchor-has-content: Add options to match eslint (#24571) (Cole Ellison) ### 🐛 Bug Fixes - b746e00 linter/eslint/no-implicit-coercion: Preserve template coercion whitespace (#25470) (camc314) - a92c541 linter: Preserve source text for JS plugin ignore fixes (#25280) (Norcleeh) - 675c840 linter/eslint/prefer-promise-reject-errors: Handle parenthesized calls (#25378) (camc314) - 1703739 linter/unicorn/new-for-builtins: Ignore optional chains (#25411) (tanakalucky) - 95ece63 linter/unicorn/prefer-code-point: Downgrade the auto-fix to dangerous (#25412) (leemr) - c451a0e linter/vitest: Validate `consistent-test-filename` regex patterns (#25408) (Mikhail Baev) - 937825c react_compiler: Disable exhaustive memo validation by default (#25417) (Boshen) - f0f7dae linter/eslint/no-unused-vars: Report invalid regex options (#25380) (Cameron) - 44e73fd linter/unicorn/prefer-array-flat: Fix `concat.apply` suggestions (#25373) (Cameron) - 6846a9a linter/react/rules-of-hooks: Detect constructor callbacks (#25377) (camc314) - b247a9d linter/unicorn/new-for-builtins: Support `Float16Array` (#25382) (tanakalucky) - 19109cd linter/unicorn/error-message: Support `SuppressedError` messages (#25375) (camc314) - 9c13f5e linter: Assert token lookup invariants (#25368) (camc314) - bc35f83 linter/eslint/no-unused-vars: Bound catch parameter lookup (#25367) (camc314) - c159fb9 linter/unicorn/switch-case-braces: Bound token lookup (#25363) (camc314) - 03b2eb2 linter/unicorn/no-static-only-class: Bound token lookup (#25361) (camc314) - 0afc59e linter/unicorn/empty-brace-spaces: Bound token lookup (#25353) (camc314) - 2963d98 linter/eslint/no-unreachable-loop: Do not report loops whose body has a finally block (#25335) (Todor Andonov) - 589e5fb linter/eslint/no-param-reassign: Validate `ignorePropertyModificationsForRegex` property (#25346) (Mikhail Baev) - aae5d8b linter/eslint/no-throw-literal: False positive on variable declared without initializer (#25275) (cjnoname) - 6b1c479 oxlint: Normalize customized rule names (#25316) (camc314) - d494eb5 linter/unicorn/consistent-existence-index-check: Bound token lookup (#25325) (camc314) - 4266037 linter/typescript/prefer-namespace-keyword: Bound token lookup (#25322) (camc314) - 4745b4e linter/typescript/no-namespace: Bound token lookup (#25321) (camc314) - 648a481 linter/eslint/one-var: Avoid joining exported declarations (#25314) (camc314) - 9573937 linter/typescript: Validate `ban-ts-comment` description_format (#25320) (Mikhail Baev) - ebf7d18 linter/typescript/consistent-type-definitions: Bound token lookup (#25281) (camc314) - 1501ccf linter/typescript/consistent-generic-constructors: Bound token lookup (#25258) (camc314) ### ⚡ Performance - 8f784f3 linter: Reduce rule config dispatch size (#25461) (Boshen) - 2de4ec2 linter: Reduce visitor code size (#25441) (Boshen) - 6fb7f47 linter/unicorn/prefer-export-from: Narrow `ExportFromDeclaration` lookup (#25381) (camc314) - e3f6263 linter/unicorn/prefer-default-parameters: Avoid reference allocation (#25379) (camc314) - d863473 linter/vue/max-props: Narrow AST dispatch (#25372) (camc314) - 273d867 linter: Avoid diagnostic sorting after applying fixes (#25079) (Sysix) - 4ec9189 oxlint/lsp: Avoid second lock for getting/removing unused directives (#25350) (Sysix) - 6c0d01b oxlint/lsp: Preallocate fix-content vec (#25351) (Sysix) - 3a94055 linter: Avoid per-call heap allocations in jest and unicorn helpers (#25210) (Connor Shea) - 4abff11 linter: Avoid redundant message work in the agent reporter (#25315) (Connor Shea) - 6bb5421 linter: Hoist `current_dir` out of the stylish reporter loop (#25313) (Connor Shea) - 9a7c323 linter: Compute diagnostic `Info` once per diagnostic in junit reporter (#25312) (Connor Shea) - 1cf7dde oxlint: Render JSON report into a single buffer (#25295) (connorshea) - 8492cfd linter/typescript/ban-ts-comment: Bail early with substring guard (#25301) (Jacob Asper) - 7607f04 linter/typescript/ban-tslint-comment: Replace regex with manual parser (#25299) (Jacob Asper) # Oxfmt ### 💥 BREAKING CHANGES - a33788e ast: [**BREAKING**] Group class heritage into `ClassHeritage` (#25360) (camc314) - 5c5cdcd ast: [**BREAKING**] Narrow `TSInterfaceHeritage::expression` to TSTypeName (#24360) (camc314) - 6be314f ast: [**BREAKING**] Remove duplicated `VariableDeclarator::kind` (#25319) (camc314) - 44fd320 ast: [**BREAKING**] Split TS external modules & Namespace Declarations (#25284) (camc314) ### 🚀 Features - fd02a89 oxfmt: Dispatch yaml-in-css(frontmatter) to `oxc_formatter_yaml` (#25336) (leaysgur) - ab12665 formatter_core: Add `hardlineWithoutBreakParent` equivalent IR (#25273) (leaysgur) ### 🐛 Bug Fixes - 95dc917 oxfmt: Drop IR Space at line start for js-in-xxx (#25460) (leaysgur) - b63eccc formatter: Keep comments after TS this_param (#25459) (leaysgur) - ab52a59 formatter: Format xxx-in-js inside JSDoc js fence (#25414) (leaysgur) - 1a2c64a formatter,oxfmt: Apply effective print width for JSDoc fence (#25413) (leaysgur) - 2eaede9 formatter_core: Unify leading-BOM handlings (#25340) (leaysgur) - ef1d04b formatter: Break mapped type brackets (#25297) (leaysgur) - 4e6f3f1 formatter: Break index signature brackets (#25296) (leaysgur) - e23dccf formatter_css: Bump oxc-css-parser to accept unknown at-rule with interpolated (#25277) (leaysgur) - c29b587 formatter_core: Measure decided-flat fill separator as flat during group re-measure (#25276) (leaysgur) - f3c6953 formatter_yaml: Don't rewrite overflowing key to implicit (#25274) (leaysgur) ### ⚡ Performance - c9d1a5b oxfmt: Spawn tinypool lazily (#25298) (leaysgur) ### 📚 Documentation - 6eae5c9 formatter,oxfmt: Record embed-layer decisions in place (#25422) (leaysgur) - 51224a7 formatter_yaml: Pin EOF blank lines divergence (#25269) (leaysgur)
|
Thank you!! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #25278
Overview
This PR resolves an oxlint language server crash that could occur when requesting code actions for diagnostics reported by JS plugins, particularly when the diagnostic appears after the beginning of a file.
JS plugin diagnostics can now safely provide regular fixes as well as line-level and file-level disable actions.
Root cause
run_external_rules(), thesemanticis being taken to run the external JS plugin rules, leaving the formersemanticinside the context host empty:oxc/crates/oxc_linter/src/lib.rs
Line 539 in e23dccf
with_ignore_fixesto generate ignore fixes, but inside theadd_ignore_fix(), it doesn't check thesection_source_text.semanticpasses the empty source text to theadd_ignore_fix()assection_source_text, and the empty string just causes the crash.oxc/crates/oxc_linter/src/context/host.rs
Lines 329 to 334 in e23dccf
What changed
A new property
source_textis added to the context sub host, which stores a reference to the real source text string. Even if thesemanticis taken and becomes empty, the reference can still get the real string and make things work.pub struct ContextSubHost<'a> { /// Semantic information about the file being linted, which includes scopes, symbols and AST nodes. /// See [`Semantic`]. pub(super) semantic: Semantic<'a>, // ... + /// Stable source text for this script section + /// which remains available even after `semantic` is taken while running JS plugins. + pub(super) source_text: &'a str, /// The source text offset of the sub host pub(super) source_text_offset: u32, }And I added a new utility method to get the
source_textfrom the context sub host.When passing source text to
add_ignore_fix(), just use the newsource_text()method.if self.with_ignore_fixes { - let source_text = self.semantic().source_text(); + let source_text = self.source_text(); for diagnostic in &mut diagnostics { diagnostic.add_ignore_fix(self.current_sub_host().source_text_offset, source_text); } } // (the same as other occursAlso, I added the necessary check for the
section_source_textinadd_ignore_fix().Notes
This is my first contribution to oxc project. Thanks for reviewing!