Skip to content

Commit 2f6810a

Browse files
committedApr 4, 2025·
feat(editor): add named fixes for code actions (#10203)
- related to #10038 This allows a `Fix` to have a message associated with it as well, similar to `RuleFix`. This is used by the editor to show code actions for a given lint error. For a start, I've added a message to the `no-debugger` rule and modified a test that shows this gets an improved code action message in VS Code.
1 parent 778b044 commit 2f6810a

29 files changed

+93
-63
lines changed
 

‎apps/oxlint/src/snapshots/_-D correctness fixtures__linter__debugger.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 0 warnings and 1 error.
1717
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/_-c fixtures__linter__eslintrc.json fixtures__linter__debugger.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 0 warnings and 1 error.
1717
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/_-c fixtures__overrides__directories-config.json fixtures__overrides@oxlint.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,28 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
1717
,-[fixtures/overrides/lib/tests/index.js:1:1]
1818
1 | debugger;
1919
: ^^^^^^^^^
2020
`----
21-
help: Delete this code.
21+
help: Remove the debugger statement
2222

2323
x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
2424
,-[fixtures/overrides/src/oxlint.js:1:1]
2525
1 | debugger;
2626
: ^^^^^^^^^
2727
`----
28-
help: Delete this code.
28+
help: Remove the debugger statement
2929
3030
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
3131
,-[fixtures/overrides/src/tests/index.js:1:1]
3232
1 | debugger;
3333
: ^^^^^^^^^
3434
`----
35-
help: Delete this code.
35+
help: Remove the debugger statement
3636

3737
Found 2 warnings and 2 errors.
3838
Finished in <variable>ms on 7 files with 98 rules using 1 threads.

‎apps/oxlint/src/snapshots/_fixtures__astro__debugger.astro@oxlint.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ working directory:
1313
: ^^^^^^^^
1414
3 | ---
1515
`----
16-
help: Delete this code.
16+
help: Remove the debugger statement
1717
1818
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
1919
,-[fixtures/astro/debugger.astro:11:3]
@@ -22,7 +22,7 @@ working directory:
2222
: ^^^^^^^^
2323
12 | </script>
2424
`----
25-
help: Delete this code.
25+
help: Remove the debugger statement
2626

2727
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
2828
,-[fixtures/astro/debugger.astro:15:3]
@@ -31,7 +31,7 @@ working directory:
3131
: ^^^^^^^^
3232
16 | </script>
3333
`----
34-
help: Delete this code.
34+
help: Remove the debugger statement
3535
3636
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
3737
,-[fixtures/astro/debugger.astro:19:3]
@@ -40,7 +40,7 @@ working directory:
4040
: ^^^^^^^^
4141
20 | </script>
4242
`----
43-
help: Delete this code.
43+
help: Remove the debugger statement
4444

4545
Found 4 warnings and 0 errors.
4646
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/_fixtures__linter@oxlint.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
1717
,-[fixtures/linter/fix.js:1:1]
1818
1 | debugger
1919
: ^^^^^^^^
2020
`----
21-
help: Delete this code.
21+
help: Remove the debugger statement
2222

2323
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/use-isnan.html\eslint(use-isnan)]8;;\: Requires calls to isNaN() when checking for NaN
2424
,-[fixtures/linter/nan.js:1:8]

‎apps/oxlint/src/snapshots/_fixtures__linter__debugger.js fixtures__linter__nan.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/use-isnan.html\eslint(use-isnan)]8;;\: Requires calls to isNaN() when checking for NaN
1717
,-[fixtures/linter/nan.js:1:8]

‎apps/oxlint/src/snapshots/_fixtures__linter__debugger.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory:
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 1 warning and 0 errors.
1717
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/_fixtures__svelte__debugger.svelte@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ working directory:
1313
: ^^^^^^^^^
1414
3 |
1515
`----
16-
help: Delete this code.
16+
help: Remove the debugger statement
1717

1818
Found 1 warning and 0 errors.
1919
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/_fixtures__vue__debugger.vue@oxlint.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ working directory:
1313
: ^^^^^^^^
1414
7 | </script>
1515
`----
16-
help: Delete this code.
16+
help: Remove the debugger statement
1717
1818
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
1919
,-[fixtures/vue/debugger.vue:11:5]
@@ -22,7 +22,7 @@ working directory:
2222
: ^^^^^^^^^
2323
12 | </script>
2424
`----
25-
help: Delete this code.
25+
help: Remove the debugger statement
2626

2727
Found 2 warnings and 0 errors.
2828
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__auto_config_detection_debugger.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory: fixtures/auto_config_detection
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 0 warnings and 1 error.
1717
Finished in <variable>ms on 1 file using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__extends_config_--disable-nested-config@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ working directory: fixtures/extends_config
2828
1 | debugger;
2929
: ^^^^^^^^^
3030
`----
31-
help: Delete this code.
31+
help: Remove the debugger statement
3232
3333
Found 3 warnings and 0 errors.
3434
Finished in <variable>ms on 4 files with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__extends_config_overrides_same_directory@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory: fixtures/extends_config
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 1 warning and 0 errors.
1717
Finished in <variable>ms on 1 file using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__linter_debugger.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ working directory: fixtures/linter
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
Found 1 warning and 0 errors.
1717
Finished in <variable>ms on 1 file with 99 rules using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__nested_config_-A no-console@oxlint.snap

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,21 @@ working directory: fixtures/nested_config
1111
1 | debugger;
1212
: ^^^^^^^^^
1313
`----
14-
help: Delete this code.
14+
help: Remove the debugger statement
1515
1616
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
1717
,-[package1-empty-config/debugger.js:1:1]
1818
1 | debugger;
1919
: ^^^^^^^^^
2020
`----
21-
help: Delete this code.
21+
help: Remove the debugger statement
2222

2323
x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
2424
,-[package2-no-config/debugger.js:1:1]
2525
1 | debugger;
2626
: ^^^^^^^^^
2727
`----
28-
help: Delete this code.
28+
help: Remove the debugger statement
2929
3030
Found 1 warning and 2 errors.
3131
Finished in <variable>ms on 7 files using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__nested_config_@oxlint.snap

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@ working directory: fixtures/nested_config
1818
1 | debugger;
1919
: ^^^^^^^^^
2020
`----
21-
help: Delete this code.
21+
help: Remove the debugger statement
2222

2323
! ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html\eslint(no-debugger)]8;;\: `debugger` statement is not allowed
2424
,-[package1-empty-config/debugger.js:1:1]
2525
1 | debugger;
2626
: ^^^^^^^^^
2727
`----
28-
help: Delete this code.
28+
help: Remove the debugger statement
2929
3030
x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-console.html\eslint(no-console)]8;;\: eslint(no-console): Unexpected console statement.
3131
,-[package2-no-config/console.ts:1:1]
@@ -39,7 +39,7 @@ working directory: fixtures/nested_config
3939
1 | debugger;
4040
: ^^^^^^^^^
4141
`----
42-
help: Delete this code.
42+
help: Remove the debugger statement
4343
4444
x ]8;;https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-console.html\eslint(no-console)]8;;\: eslint(no-console): Unexpected console statement.
4545
,-[package3-deep-config/src/components/component.js:2:3]

‎apps/oxlint/src/snapshots/fixtures__output_formatter_diagnostic_--format=default test.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ working directory: fixtures/output_formatter_diagnostic
3030
5 | debugger;
3131
: ^^^^^^^^^
3232
`----
33-
help: Delete this code.
33+
help: Remove the debugger statement
3434
3535
Found 2 warnings and 1 error.
3636
Finished in <variable>ms on 1 file using 1 threads.

‎apps/oxlint/src/snapshots/fixtures__output_formatter_diagnostic_--format=json test.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ arguments: --format=json test.js
66
working directory: fixtures/output_formatter_diagnostic
77
----------
88
[
9-
{"message": "`debugger` statement is not allowed","code": "eslint(no-debugger)","severity": "error","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html","help": "Delete this code.","filename": "test.js","labels": [{"span": {"offset": 38,"length": 9}}],"related": []},
9+
{"message": "`debugger` statement is not allowed","code": "eslint(no-debugger)","severity": "error","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger.html","help": "Remove the debugger statement","filename": "test.js","labels": [{"span": {"offset": 38,"length": 9}}],"related": []},
1010
{"message": "Function 'foo' is declared but never used.","code": "eslint(no-unused-vars)","severity": "warning","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html","help": "Consider removing this declaration.","filename": "test.js","labels": [{"label": "'foo' is declared here","span": {"offset": 9,"length": 3}}],"related": []},
1111
{"message": "Parameter 'b' is declared but never used. Unused parameters should start with a '_'.","code": "eslint(no-unused-vars)","severity": "warning","causes": [],"url": "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-unused-vars.html","help": "Consider removing this parameter.","filename": "test.js","labels": [{"label": "'b' is declared here","span": {"offset": 16,"length": 1}}],"related": []}
1212
]

‎apps/oxlint/src/snapshots/fixtures__report_unused_directives_-c .oxlintrc.json --report-unused-disable-directives test.js@oxlint.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ working directory: fixtures/report_unused_directives
2929
: ^^^^^^^^^
3030
11 |
3131
`----
32-
help: Delete this code.
32+
help: Remove the debugger statement
3333
3434
! Unused eslint-enable directive (no matching eslint-disable directives were found).
3535
,-[test.js:22:3]

‎crates/oxc_language_server/src/linter/error_with_position.rs

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ pub struct ErrorReport {
4040

4141
#[derive(Debug, Clone)]
4242
pub struct FixedContent {
43+
pub message: Option<String>,
4344
pub code: String,
4445
pub range: Range,
4546
}

‎crates/oxc_language_server/src/linter/isolated_lint_handler.rs

+1
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ impl IsolatedLintHandler {
162162
.into_iter()
163163
.map(|msg| {
164164
let fixed_content = msg.fix.map(|f| FixedContent {
165+
message: f.message.map(|m| m.to_string()),
165166
code: f.content.to_string(),
166167
range: Range {
167168
start: offset_to_position(

‎crates/oxc_language_server/src/linter/snapshots/fixtures_linter_astro_debugger.astro.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source: crates/oxc_language_server/src/linter/tester.rs
33
---
44
code: "eslint(no-debugger)"
55
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
6-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
6+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
77
range: Range { start: Position { line: 1, character: 0 }, end: Position { line: 1, character: 8 } }
88
related_information[0].message: ""
99
related_information[0].location.uri: "file://<variable>/fixtures/linter/astro/debugger.astro"
@@ -15,7 +15,7 @@ tags: None
1515

1616
code: "eslint(no-debugger)"
1717
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
18-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
18+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
1919
range: Range { start: Position { line: 10, character: 2 }, end: Position { line: 10, character: 10 } }
2020
related_information[0].message: ""
2121
related_information[0].location.uri: "file://<variable>/fixtures/linter/astro/debugger.astro"
@@ -27,7 +27,7 @@ tags: None
2727

2828
code: "eslint(no-debugger)"
2929
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
30-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
30+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
3131
range: Range { start: Position { line: 14, character: 2 }, end: Position { line: 14, character: 10 } }
3232
related_information[0].message: ""
3333
related_information[0].location.uri: "file://<variable>/fixtures/linter/astro/debugger.astro"
@@ -39,7 +39,7 @@ tags: None
3939

4040
code: "eslint(no-debugger)"
4141
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
42-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
42+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
4343
range: Range { start: Position { line: 18, character: 2 }, end: Position { line: 18, character: 10 } }
4444
related_information[0].message: ""
4545
related_information[0].location.uri: "file://<variable>/fixtures/linter/astro/debugger.astro"

‎crates/oxc_language_server/src/linter/snapshots/fixtures_linter_svelte_debugger.svelte.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source: crates/oxc_language_server/src/linter/tester.rs
33
---
44
code: "eslint(no-debugger)"
55
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
6-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
6+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
77
range: Range { start: Position { line: 1, character: 1 }, end: Position { line: 1, character: 10 } }
88
related_information[0].message: ""
99
related_information[0].location.uri: "file://<variable>/fixtures/linter/svelte/debugger.svelte"

‎crates/oxc_language_server/src/linter/snapshots/fixtures_linter_vue_debugger.vue.snap

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ source: crates/oxc_language_server/src/linter/tester.rs
33
---
44
code: "eslint(no-debugger)"
55
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
6-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
6+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
77
range: Range { start: Position { line: 5, character: 4 }, end: Position { line: 5, character: 12 } }
88
related_information[0].message: ""
99
related_information[0].location.uri: "file://<variable>/fixtures/linter/vue/debugger.vue"
@@ -15,7 +15,7 @@ tags: None
1515

1616
code: "eslint(no-debugger)"
1717
code_description.href: "https://oxc.rs/docs/guide/usage/linter/rules/eslint/no-debugger"
18-
message: "`debugger` statement is not allowed\nhelp: Delete this code."
18+
message: "`debugger` statement is not allowed\nhelp: Remove the debugger statement"
1919
range: Range { start: Position { line: 10, character: 4 }, end: Position { line: 10, character: 13 } }
2020
related_information[0].message: ""
2121
related_information[0].location.uri: "file://<variable>/fixtures/linter/vue/debugger.vue"

‎crates/oxc_language_server/src/main.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -264,11 +264,21 @@ impl LanguageServer for Backend {
264264
}
265265

266266
if let Some(fixed_content) = &report.fixed_content {
267+
// 1) Use `fixed_content.message` if it exists
268+
// 2) Try to parse the report diagnostic message
269+
// 3) Fallback to "Fix this problem"
270+
let title = match fixed_content.message.clone() {
271+
Some(msg) => msg,
272+
None => {
273+
if let Some(code) = report.diagnostic.message.split(':').next() {
274+
format!("Fix this {code} problem")
275+
} else {
276+
"Fix this problem".to_string()
277+
}
278+
}
279+
};
267280
code_actions_vec.push(CodeActionOrCommand::CodeAction(CodeAction {
268-
title: report.diagnostic.message.split(':').next().map_or_else(
269-
|| "Fix this problem".into(),
270-
|s| format!("Fix this {s} problem"),
271-
),
281+
title,
272282
kind: Some(if is_source_fix_all_oxc {
273283
CODE_ACTION_KIND_SOURCE_FIX_ALL_OXC
274284
} else {

‎crates/oxc_linter/src/fixer/fix.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -121,8 +121,6 @@ impl FixKind {
121121
pub struct RuleFix<'a> {
122122
kind: FixKind,
123123
/// A suggestion message. Will be shown in editors via code actions.
124-
///
125-
/// NOTE: code actions aren't implemented yet.
126124
message: Option<Cow<'a, str>>,
127125
/// The actual that will be applied to the source code.
128126
///
@@ -239,7 +237,9 @@ impl<'a> RuleFix<'a> {
239237

240238
#[inline]
241239
pub fn into_fix(self, source_text: &str) -> Fix<'a> {
242-
self.fix.normalize_fixes(source_text)
240+
let mut fix = self.fix.normalize_fixes(source_text);
241+
fix.message = self.message;
242+
fix
243243
}
244244

245245
#[inline]
@@ -275,6 +275,9 @@ impl<'a> Deref for RuleFix<'a> {
275275
#[non_exhaustive]
276276
pub struct Fix<'a> {
277277
pub content: Cow<'a, str>,
278+
/// A brief suggestion message describing the fix. Will be shown in
279+
/// editors via code actions.
280+
pub message: Option<Cow<'a, str>>,
278281
pub span: Span,
279282
}
280283

@@ -288,6 +291,10 @@ impl<'new> CloneIn<'new> for Fix<'_> {
288291
Cow::Owned(s) => Cow::Owned(s.clone()),
289292
},
290293
span: self.span,
294+
message: self.message.as_ref().map(|s| match s {
295+
Cow::Borrowed(s) => Cow::Borrowed(allocator.alloc_str(s)),
296+
Cow::Owned(s) => Cow::Owned(s.clone()),
297+
}),
291298
}
292299
}
293300
}
@@ -300,17 +307,17 @@ impl Default for Fix<'_> {
300307

301308
impl<'a> Fix<'a> {
302309
pub const fn delete(span: Span) -> Self {
303-
Self { content: Cow::Borrowed(""), span }
310+
Self { content: Cow::Borrowed(""), message: None, span }
304311
}
305312

306313
pub fn new<T: Into<Cow<'a, str>>>(content: T, span: Span) -> Self {
307-
Self { content: content.into(), span }
314+
Self { content: content.into(), message: None, span }
308315
}
309316

310317
/// Creates a [`Fix`] that doesn't change the source code.
311318
#[inline]
312319
pub const fn empty() -> Self {
313-
Self { content: Cow::Borrowed(""), span: SPAN }
320+
Self { content: Cow::Borrowed(""), message: None, span: SPAN }
314321
}
315322
}
316323

@@ -506,7 +513,7 @@ impl<'a> CompositeFix<'a> {
506513
let mut output = String::new();
507514

508515
for fix in fixes {
509-
let Fix { content, span } = fix;
516+
let Fix { content, span, .. } = fix;
510517
// negative range or overlapping ranges is invalid
511518
if span.start > span.end {
512519
debug_assert!(false, "Negative range is invalid: {span:?}");

‎crates/oxc_linter/src/fixer/mod.rs

+15-8
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ impl<'a> Fixer<'a> {
304304
let mut filtered_messages = Vec::with_capacity(self.messages.len());
305305

306306
for mut m in self.messages {
307-
let Some(Fix { content, span }) = m.fix.as_ref() else {
307+
let Some(Fix { content, span, .. }) = m.fix.as_ref() else {
308308
filtered_messages.push(m);
309309
continue;
310310
};
@@ -399,16 +399,23 @@ mod test {
399399
}
400400

401401
const TEST_CODE: &str = "var answer = 6 * 7;";
402-
const INSERT_AT_END: Fix = Fix { span: Span::new(19, 19), content: Cow::Borrowed("// end") };
403-
const INSERT_AT_START: Fix = Fix { span: Span::new(0, 0), content: Cow::Borrowed("// start") };
404-
const INSERT_AT_MIDDLE: Fix = Fix { span: Span::new(13, 13), content: Cow::Borrowed("5 *") };
405-
const REPLACE_ID: Fix = Fix { span: Span::new(4, 10), content: Cow::Borrowed("foo") };
406-
const REPLACE_VAR: Fix = Fix { span: Span::new(0, 3), content: Cow::Borrowed("let") };
407-
const REPLACE_NUM: Fix = Fix { span: Span::new(13, 14), content: Cow::Borrowed("5") };
402+
const INSERT_AT_END: Fix =
403+
Fix { span: Span::new(19, 19), content: Cow::Borrowed("// end"), message: None };
404+
const INSERT_AT_START: Fix =
405+
Fix { span: Span::new(0, 0), content: Cow::Borrowed("// start"), message: None };
406+
const INSERT_AT_MIDDLE: Fix =
407+
Fix { span: Span::new(13, 13), content: Cow::Borrowed("5 *"), message: None };
408+
const REPLACE_ID: Fix =
409+
Fix { span: Span::new(4, 10), content: Cow::Borrowed("foo"), message: None };
410+
const REPLACE_VAR: Fix =
411+
Fix { span: Span::new(0, 3), content: Cow::Borrowed("let"), message: None };
412+
const REPLACE_NUM: Fix =
413+
Fix { span: Span::new(13, 14), content: Cow::Borrowed("5"), message: None };
408414
const REMOVE_START: Fix = Fix::delete(Span::new(0, 4));
409415
const REMOVE_MIDDLE: Fix = Fix::delete(Span::new(5, 10));
410416
const REMOVE_END: Fix = Fix::delete(Span::new(14, 18));
411-
const REVERSE_RANGE: Fix = Fix { span: Span::new(3, 0), content: Cow::Borrowed(" ") };
417+
const REVERSE_RANGE: Fix =
418+
Fix { span: Span::new(3, 0), content: Cow::Borrowed(" "), message: None };
412419

413420
fn get_fix_result(messages: Vec<Message>) -> FixResult {
414421
Fixer::new(TEST_CODE, messages).fix()

‎crates/oxc_linter/src/rules/eslint/no_debugger.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ fn no_debugger_diagnostic(span: Span) -> OxcDiagnostic {
99
OxcDiagnostic::warn("`debugger` statement is not allowed").with_label(span)
1010
}
1111

12+
const REMOVE_DEBUGGER: &str = "Remove the debugger statement";
13+
1214
#[derive(Debug, Default, Clone)]
1315
pub struct NoDebugger;
1416

@@ -45,7 +47,7 @@ impl Rule for NoDebugger {
4547
.skip(1)
4648
.find(|p| !matches!(p.kind(), AstKind::ParenthesizedExpression(_)))
4749
else {
48-
return fixer.delete(&stmt.span);
50+
return fixer.delete(&stmt.span).with_message(REMOVE_DEBUGGER);
4951
};
5052

5153
// For statements like `if (foo) debugger;`, we can't just
@@ -55,11 +57,13 @@ impl Rule for NoDebugger {
5557
| AstKind::WhileStatement(_)
5658
| AstKind::ForStatement(_)
5759
| AstKind::ForInStatement(_)
58-
| AstKind::ForOfStatement(_) => fixer.replace(stmt.span, "{}"),
60+
| AstKind::ForOfStatement(_) => {
61+
fixer.replace(stmt.span, "{}").with_message(REMOVE_DEBUGGER)
62+
}
5963
// NOTE: no need to check for
6064
// AstKind::ArrowFunctionExpression because
6165
// `const x = () => debugger` is a parse error
62-
_ => fixer.delete(&stmt.span),
66+
_ => fixer.delete(&stmt.span).with_message(REMOVE_DEBUGGER),
6367
}
6468
});
6569
}

‎crates/oxc_linter/src/snapshots/eslint_no_debugger.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@ source: crates/oxc_linter/src/tester.rs
66
1if (foo) debugger
77
· ────────
88
╰────
9-
help: Replace `debugger` with `{}`.
9+
help: Remove the debugger statement

‎editors/vscode/client/extension.spec.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ suite('E2E Diagnostics', () => {
121121
strictEqual(diagnostics.length, 1);
122122
assert(typeof diagnostics[0].code == 'object');
123123
strictEqual(diagnostics[0].code.target.authority, 'oxc.rs');
124-
strictEqual(diagnostics[0].message, '`debugger` statement is not allowed\nhelp: Delete this code.');
124+
strictEqual(diagnostics[0].message, '`debugger` statement is not allowed\nhelp: Remove the debugger statement');
125125
strictEqual(diagnostics[0].severity, DiagnosticSeverity.Warning);
126126
strictEqual(diagnostics[0].range.start.line, 0);
127127
strictEqual(diagnostics[0].range.start.character, 8);
@@ -159,7 +159,7 @@ suite('E2E Diagnostics', () => {
159159
[
160160
{
161161
isPreferred: true,
162-
title: 'Fix this `debugger` statement is not allowed\nhelp problem',
162+
title: 'Remove the debugger statement',
163163
},
164164
{
165165
isPreferred: false,
@@ -189,7 +189,7 @@ suite('E2E Diagnostics', () => {
189189
strictEqual(diagnostics.length, 1);
190190
assert(typeof diagnostics[0].code == 'object');
191191
strictEqual(diagnostics[0].code.target.authority, 'oxc.rs');
192-
strictEqual(diagnostics[0].message, '`debugger` statement is not allowed\nhelp: Delete this code.');
192+
strictEqual(diagnostics[0].message, '`debugger` statement is not allowed\nhelp: Remove the debugger statement');
193193
strictEqual(diagnostics[0].severity, DiagnosticSeverity.Warning);
194194
strictEqual(diagnostics[0].range.start.line, 0);
195195
strictEqual(diagnostics[0].range.start.character, 8);

0 commit comments

Comments
 (0)
Please sign in to comment.