diff --git a/apps/oxlint/fixtures/linter/fix.js b/apps/oxlint/fixtures/fix_argument/fix.js
similarity index 100%
rename from apps/oxlint/fixtures/linter/fix.js
rename to apps/oxlint/fixtures/fix_argument/fix.js
diff --git a/apps/oxlint/fixtures/fix_argument/fix.vue b/apps/oxlint/fixtures/fix_argument/fix.vue
new file mode 100644
index 0000000000000..ec977d8304df0
--- /dev/null
+++ b/apps/oxlint/fixtures/fix_argument/fix.vue
@@ -0,0 +1,2 @@
+
+
diff --git a/apps/oxlint/src/lint.rs b/apps/oxlint/src/lint.rs
index bbba5b5f9e31c..53bf04e3e2c00 100644
--- a/apps/oxlint/src/lint.rs
+++ b/apps/oxlint/src/lint.rs
@@ -863,7 +863,12 @@ mod test {
#[test]
fn test_fix() {
- Tester::test_fix("fixtures/linter/fix.js", "debugger\n", "\n");
+ Tester::test_fix("fixtures/fix_argument/fix.js", "debugger\n", "\n");
+ Tester::test_fix(
+ "fixtures/fix_argument/fix.vue",
+ "\n\n",
+ "\n\n",
+ );
}
#[test]
diff --git a/apps/oxlint/src/snapshots/_-A all fixtures__linter@oxlint.snap b/apps/oxlint/src/snapshots/_-A all fixtures__linter@oxlint.snap
index 5b9d90b549c4c..fe6cd3391cc4d 100644
--- a/apps/oxlint/src/snapshots/_-A all fixtures__linter@oxlint.snap
+++ b/apps/oxlint/src/snapshots/_-A all fixtures__linter@oxlint.snap
@@ -6,7 +6,7 @@ arguments: -A all fixtures/linter
working directory:
----------
Found 0 warnings and 0 errors.
-Finished in ms on 4 files with 0 rules using 1 threads.
+Finished in ms on 3 files with 0 rules using 1 threads.
----------
CLI result: LintSucceeded
----------
diff --git a/apps/oxlint/src/snapshots/_fixtures__linter@oxlint.snap b/apps/oxlint/src/snapshots/_fixtures__linter@oxlint.snap
index ff3b945fc4ac7..0c7f9e08250ba 100644
--- a/apps/oxlint/src/snapshots/_fixtures__linter@oxlint.snap
+++ b/apps/oxlint/src/snapshots/_fixtures__linter@oxlint.snap
@@ -13,13 +13,6 @@ working directory:
`----
help: Remove the debugger statement
- ! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
- ,-[fixtures/linter/fix.js:1:1]
- 1 | debugger
- : ^^^^^^^^
- `----
- help: Remove the debugger statement
-
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
,-[fixtures/linter/js_as_jsx.js:1:1]
1 | debugger;
@@ -35,8 +28,8 @@ working directory:
`----
help: Use the isNaN function to compare with NaN.
-Found 4 warnings and 0 errors.
-Finished in ms on 4 files with 87 rules using 1 threads.
+Found 3 warnings and 0 errors.
+Finished in ms on 3 files with 87 rules using 1 threads.
----------
CLI result: LintSucceeded
----------
diff --git a/crates/oxc_linter/src/fixer/mod.rs b/crates/oxc_linter/src/fixer/mod.rs
index c02dc496d6351..d78151251d29d 100644
--- a/crates/oxc_linter/src/fixer/mod.rs
+++ b/crates/oxc_linter/src/fixer/mod.rs
@@ -292,11 +292,10 @@ impl<'a> Message<'a> {
Self { error, span: Span::new(start, end), fixes, fixed: false }
}
- /// move the offset of all spans to the right
+ /// move the offset of all spans (except fixes) to the right
+ /// for moving fixes use [`Message::move_fix_offset`].
pub fn move_offset(&mut self, offset: u32) -> &mut Self {
- if offset == 0 {
- return self;
- }
+ debug_assert!(offset != 0);
self.span = self.span.move_right(offset);
@@ -306,6 +305,12 @@ impl<'a> Message<'a> {
}
}
+ self
+ }
+
+ pub fn move_fix_offset(&mut self, offset: u32) -> &mut Self {
+ debug_assert!(offset != 0);
+
match &mut self.fixes {
PossibleFixes::None => {}
PossibleFixes::Single(fix) => {
diff --git a/crates/oxc_linter/src/service/runtime.rs b/crates/oxc_linter/src/service/runtime.rs
index a0c17efaca7c0..7a886e467b909 100644
--- a/crates/oxc_linter/src/service/runtime.rs
+++ b/crates/oxc_linter/src/service/runtime.rs
@@ -494,7 +494,7 @@ impl Runtime {
// clippy: the source field is checked and assumed to be less than 4GB, and
// we assume that the fix offset will not exceed 2GB in either direction
- #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap, clippy::cast_sign_loss)]
+ #[expect(clippy::cast_possible_truncation, clippy::cast_possible_wrap)]
pub(super) fn run(&mut self, tx_error: &DiagnosticSender) {
rayon::scope(|scope| {
self.resolve_modules(scope, true, tx_error, |me, mut module_to_lint| {
@@ -544,7 +544,8 @@ impl Runtime {
let fix_result = Fixer::new(source_text, messages).fix();
if fix_result.fixed {
// write to file, replacing only the changed part
- let start = fix_offset as usize;
+ let start =
+ section.source.start.saturating_add_signed(fix_offset) as usize;
let end = start + source_text.len();
new_source_text
.to_mut()
@@ -646,7 +647,9 @@ impl Runtime {
// adjust offset for multiple source text in a single file
if section.source.start != 0 {
for message in &mut section_messages {
- message.move_offset(section.source.start);
+ message
+ .move_offset(section.source.start)
+ .move_fix_offset(section.source.start);
}
}
@@ -773,7 +776,8 @@ impl Runtime {
.into_iter()
.map(|mut message| {
if section.source.start != 0 {
- message.move_offset(section.source.start);
+ message.move_offset(section.source.start)
+ .move_fix_offset(section.source.start);
}
message.clone_in(allocator)
}),