10000 refactor(linter): add `diagnostics_with_multiple_fixes` to `LintConte… · oxc-project/oxc@50ef691 · GitHub
[go: up one dir, main page]

Skip to content

Commit 50ef691

Browse files
committed
refactor(linter): add diagnostics_with_multiple_fixes to LintContext (#11357)
With something like that win `forward_ref_uses_ref`: ``` fn check_forward_ref_inner<'a>( exp: &Expression, call_expr: &CallExpression, ctx: &LintContext<'a>, ) { let (params, span) = match exp { Expression::ArrowFunctionExpression(f) => (&f.params, f.span), Expression::FunctionExpression(f) => (&f.params, f.span), _ => return, }; if params.parameters_count() != 1 || params.rest.is_some() { return; } ctx.diagnostics_with_multiple_fixes( forward_ref_uses_ref_diagnostic(span), ( FixKind::Suggestion, |fixer: RuleFixer<'_, 'a>| { fixer.replace_with(call_expr, exp).with_message("remove `forwardRef` wrapper") } ), ( FixKind::Suggestion, |fixer: RuleFixer<'_, 'a>| { fixer.replace_with(call_expr, exp).with_message("add `ref` parameter") } ), ); } ``` I get in VSCode the setting 🥳 ![grafik](https://github.com/user-attachments/assets/acf7783f-99d9-441a-8813-b968ac8d9027)
1 parent 606bb34 commit 50ef691

File tree

1 file changed

+59
-14
lines changed
  • crates/oxc_linter/src/context

1 file changed

+59
-14
lines changed

crates/oxc_linter/src/context/mod.rs

Lines changed: 59 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
AllowWarnDeny, FrameworkFlags, ModuleRecord, OxlintEnv, OxlintGlobals, OxlintSettings,
1717
config::GlobalValue,
1818
disable_directives::DisableDirectives,
19-
fixer::{FixKind, Message, PossibleFixes, RuleFix, RuleFixer},
19+
fixer::{Fix, FixKind, Message, PossibleFixes, RuleFix, RuleFixer},
2020
};
2121

2222
mod host;
@@ -325,7 +325,6 @@ impl<'a> LintContext<'a> {
325325
< 8000 span class=pl-c>/// returns something that can turn into a [`RuleFix`].
326326
///
327327
/// [closure]: <https://doc.rust-lang.org/book/ch13-01-closures.html>
328-
#[cfg_attr(debug_assertions, expect(clippy::missing_panics_doc))] // Only panics in debug mode
329328
pub fn diagnostic_with_fix_of_kind<C, F>(
330329
&self,
331330
diagnostic: OxcDiagnostic,
@@ -334,29 +333,74 @@ impl<'a> LintContext<'a> {
334333
) where
335334
C: Into<RuleFix<'a>>,
336335
F: FnOnce(RuleFixer<'_, 'a>) -> C,
336+
{
337+
let (diagnostic, fix) = self.create_fix(fix_kind, fix, diagnostic);
338+
if let Some(fix) = fix {
339+
self.add_diagnostic(Message::new(diagnostic, PossibleFixes::Single(fix)));
340+
} else {
341+
self.diagnostic(diagnostic);
342+
}
343+
}
344+
345+
/// Report a lint rule violation and provide an automatic fix of a specific kind.
346+
/// This method is used when the rule can provide multiple fixes for the same diagnostic.
< 8000 code>347+
pub fn diagnostics_with_multiple_fixes<C, F1, F2>(
348+
&self,
349+
diagnostic: OxcDiagnostic,
350+
fix_one: (FixKind, F1),
351+
fix_two: (FixKind, F2),
352+
) where
353+
C: Into<RuleFix<'a>>,
354+
F1: FnOnce(RuleFixer<'_, 'a>) -> C,
355+
F2: FnOnce(RuleFixer<'_, 'a>) -> C,
356+
{
357+
let fixes_result: Vec<Fix<'a>> = vec![
358+
self.create_fix(fix_one.0, fix_one.1, diagnostic.clone()).1,
359+
self.create_fix(fix_two.0, fix_two.1, diagnostic.clone()).1,
360+
]
361+
.into_iter()
362+
.flatten()
363+
.collect();
364+
365+
if fixes_result.is_empty() {
366+
self.diagnostic(diagnostic);
367+
} else {
368+
self.add_diagnostic(Message::new(diagnostic, PossibleFixes::Multiple(fixes_result)));
369+
}
370+
}
371+
372+
fn create_fix<C, F>(
373+
&self,
374+
fix_kind: FixKind,
375+
fix: F,
376+
diagnostic: OxcDiagnostic,
377+
) -> (OxcDiagnostic, Option<Fix<'a>>)
378+
where
379+
C: Into<RuleFix<'a>>,
380+
F: FnOnce(RuleFixer<'_, 'a>) -> C,
337381
{
338382
let fixer = RuleFixer::new(fix_kind, self);
339383
let rule_fix: RuleFix<'a> = fix(fixer).into();
340384
#[cfg(debug_assertions)]
341-
{
342-
assert!(
343-
self.current_rule_fix_capabilities.supports_fix(fix_kind),
344-
"Rule `{}` does not support safe fixes. Did you forget to update f 8000 ix capabilities in declare_oxc_lint?.\n\tSupported fix kinds: {:?}\n\tAttempted fix kind: {:?}",
345-
self.current_rule_name,
346-
FixKind::from(self.current_rule_fix_capabilities),
347-
rule_fix.kind()
348-
);
349-
}
385+
debug_assert!(
386+
self.current_rule_fix_capabilities.supports_fix(fix_kind),
387+
"Rule `{}` does not support safe fixes. Did you forget to update fix capabilities in declare_oxc_lint?.\n\tSupported fix kinds: {:?}\n\tAttempted fix kind: {:?}",
388+
self.current_rule_name,
389+
FixKind::from(self.current_rule_fix_capabilities),
390+
rule_fix.kind()
391+
);
392+
350393
let diagnostic = match (rule_fix.message(), &diagnostic.help) {
351394
(Some(message), None) => diagnostic.with_help(message.to_owned()),
352395
_ => diagnostic,
353396
};
397+
354398
if self.parent.fix.can_apply(rule_fix.kind()) && !rule_fix.is_empty() {
355399
let fix = rule_fix.into_fix(self.source_text());
356400
#[cfg(debug_assertions)]
357401
{
358402
if fix.span.size() > 1 {
359-
assert!(
403+
debug_assert!(
360404
fix.message.as_ref().is_some_and(|msg| !msg.is_empty()),
361405
"Rule `{}/{}` fix should have a message for a complex fix. Did you forget to add a message?\n Source text: {:?}\n Fixed text: {:?}\nhelp: You can add a message to a fix with `RuleFix.with_message()`",
362406
self.current_plugin_name,
@@ -366,9 +410,10 @@ impl<'a> LintContext<'a> {
366410
);
367411
}
368412
}
369-
self.add_diagnostic(Message::new(diagnostic, PossibleFixes::Single(fix)));
413+
414+
(diagnostic, Some(fix))
370415
} else {
371-
self.diagnostic(diagnostic);
416+
(diagnostic, None)
372417
}
373418
}
374419

0 commit comments

Comments
 (0)
0