Skip to content

Commit 31dcea7

Browse files
committed
refactor(linter): accept PossibleFixes instead of Fix for Messages
1 parent d8815f9 commit 31dcea7

File tree

4 files changed

+70
-51
lines changed

4 files changed

+70
-51
lines changed

crates/oxc_linter/src/context/host.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::{
88
AllowWarnDeny, FrameworkFlags,
99
config::{LintConfig, LintPlugins},
1010
disable_directives::{DisableDirectives, DisableDirectivesBuilder},
11-
fixer::{FixKind, Message},
11+
fixer::{FixKind, Message, PossibleFixes},
1212
frameworks,
1313
module_record::ModuleRecord,
1414
options::LintOptions,
@@ -210,7 +210,7 @@ impl<'a> ContextHost<'a> {
210210
OxcDiagnostic::error(message).with_label(span).with_severity(rule_severity),
211211
// TODO: fixer
212212
// if all rules in the same directive are unused, fixer should remove the entire comment
213-
None,
213+
PossibleFixes::None,
214214
)
215215
})
216216
.collect(),

crates/oxc_linter/src/context/mod.rs

Lines changed: 3 additions & 3 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, RuleFix, RuleFixer},
19+
fixer::{FixKind, Message, PossibleFixes, RuleFix, RuleFixer},
2020
};
2121

2222
mod host;
@@ -246,7 +246,7 @@ impl<'a> LintContext<'a> {
246246
/// Use [`LintContext::diagnostic_with_fix`] to provide an automatic fix.
247247
#[inline]
248248
pub fn diagnostic(&self, diagnostic: OxcDiagnostic) {
249-
self.add_diagnostic(Message::new(diagnostic, None));
249+
self.add_diagnostic(Message::new(diagnostic, PossibleFixes::None));
250250
}
251251

252252
/// Report a lint rule violation and provide an automatic fix.
@@ -366,7 +366,7 @@ impl<'a> LintContext<'a> {
366366
);
367367
}
368368
}
369-
self.add_diagnostic(Message::new(diagnostic, Some(fix)));
369+
self.add_diagnostic(Message::new(diagnostic, PossibleFixes::Single(fix)));
370370
} else {
371371
self.diagnostic(diagnostic);
372372
}

crates/oxc_linter/src/fixer/mod.rs

Lines changed: 57 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ impl<'new> CloneIn<'new> for Message<'_> {
274274

275275
impl<'a> Message<'a> {
276276
#[expect(clippy::cast_possible_truncation)] // for `as u32`
277-
pub fn new(error: OxcDiagnostic, fix: Option<Fix<'a>>) -> Self {
277+
pub fn new(error: OxcDiagnostic, fixes: PossibleFixes<'a>) -> Self {
278278
let (start, end) = if let Some(labels) = &error.labels {
279279
let start = labels
280280
.iter()
@@ -288,8 +288,6 @@ impl<'a> Message<'a> {
288288
} else {
289289
(0, 0)
290290
};
291-
// ToDo support multiple fixes
292-
let fixes = fix.map_or(PossibleFixes::None, PossibleFixes::Single);
293291
Self { error, span: Span::new(start, end), fixes, fixed: false }
294292
}
295293
}
@@ -387,7 +385,7 @@ mod test {
387385
use oxc_diagnostics::OxcDiagnostic;
388386
use oxc_span::Span;
389387

390-
use super::{CompositeFix, Fix, FixResult, Fixer, Message};
388+
use super::{CompositeFix, Fix, FixResult, Fixer, Message, PossibleFixes};
391389

392390
fn insert_at_end() -> OxcDiagnostic {
393391
OxcDiagnostic::warn("End")
@@ -464,28 +462,36 @@ mod test {
464462
Fixer::new(TEST_CODE, messages).fix()
465463
}
466464

467-
fn create_message(error: OxcDiagnostic, fix: Option<Fix>) -> Message {
465+
fn create_message(error: OxcDiagnostic, fix: PossibleFixes) -> Message {
468466
Message::new(error, fix)
469467
}
470468

471469
#[test]
472470
fn insert_at_the_end() {
473-
let result = get_fix_result(vec![create_message(insert_at_end(), Some(INSERT_AT_END))]);
471+
let result = get_fix_result(vec![create_message(
472+
insert_at_end(),
473+
PossibleFixes::Single(INSERT_AT_END),
474+
)]);
474475
assert_eq!(result.fixed_code, TEST_CODE.to_string() + INSERT_AT_END.content.as_ref());
475476
assert_eq!(result.messages.len(), 0);
476477
}
477478

478479
#[test]
479480
fn insert_at_the_start() {
480-
let result = get_fix_result(vec![create_message(insert_at_start(), Some(INSERT_AT_START))]);
481+
let result = get_fix_result(vec![create_message(
482+
insert_at_start(),
483+
PossibleFixes::Single(INSERT_AT_START),
484+
)]);
481485
assert_eq!(result.fixed_code, INSERT_AT_START.content.to_string() + TEST_CODE);
482486
assert_eq!(result.messages.len(), 0);
483487
}
484488

485489
#[test]
486490
fn insert_at_the_middle() {
487-
let result =
488-
get_fix_result(vec![create_message(insert_at_middle(), Some(INSERT_AT_MIDDLE))]);
491+
let result = get_fix_result(vec![create_message(
492+
insert_at_middle(),
493+
PossibleFixes::Single(INSERT_AT_MIDDLE),
494+
)]);
489495
assert_eq!(
490496
result.fixed_code,
491497
TEST_CODE.cow_replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *"))
@@ -496,9 +502,9 @@ mod test {
496502
#[test]
497503
fn insert_at_the_start_middle_end() {
498504
let messages = vec![
499-
create_message(insert_at_middle(), Some(INSERT_AT_MIDDLE)),
500-
create_message(insert_at_start(), Some(INSERT_AT_START)),
501-
create_message(insert_at_end(), Some(INSERT_AT_END)),
505+
create_message(insert_at_middle(), PossibleFixes::Single(INSERT_AT_MIDDLE)),
506+
create_message(insert_at_start(), PossibleFixes::Single(INSERT_AT_START)),
507+
create_message(insert_at_end(), PossibleFixes::Single(INSERT_AT_END)),
502508
];
503509
let result = get_fix_result(messages);
504510
assert_eq!(
@@ -516,29 +522,35 @@ mod test {
516522
#[test]
517523
#[should_panic = "Negative range is invalid"]
518524
fn ignore_reverse_range() {
519-
let result = get_fix_result(vec![create_message(reverse_range(), Some(REVERSE_RANGE))]);
525+
let result = get_fix_result(vec![create_message(
526+
reverse_range(),
527+
PossibleFixes::Single(REVERSE_RANGE),
528+
)]);
520529
assert_eq!(result.fixed_code, TEST_CODE);
521530
}
522531

523532
#[test]
524533
fn replace_at_the_start() {
525-
let result = get_fix_result(vec![create_message(replace_var(), Some(REPLACE_VAR))]);
534+
let result =
535+
get_fix_result(vec![create_message(replace_var(), PossibleFixes::Single(REPLACE_VAR))]);
526536
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var", "let"));
527537
assert_eq!(result.messages.len(), 0);
528538
assert!(result.fixed);
529539
}
530540

531541
#[test]
532542
fn replace_at_the_middle() {
533-
let result = get_fix_result(vec![create_message(replace_id(), Some(REPLACE_ID))]);
543+
let result =
544+
get_fix_result(vec![create_message(replace_id(), PossibleFixes::Single(REPLACE_ID))]);
534545
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
535546
assert_eq!(result.messages.len(), 0);
536547
assert!(result.fixed);
537548
}
538549

539550
#[test]
540551
fn replace_at_the_end() {
541-
let result = get_fix_result(vec![create_message(replace_num(), Some(REPLACE_NUM))]);
552+
let result =
553+
get_fix_result(vec![create_message(replace_num(), PossibleFixes::Single(REPLACE_NUM))]);
542554
assert_eq!(result.fixed_code, TEST_CODE.cow_replace('6', "5"));
543555
assert_eq!(result.messages.len(), 0);
544556
assert!(result.fixed);
@@ -547,9 +559,9 @@ mod test {
547559
#[test]
548560
fn replace_at_the_start_middle_end() {
549561
let messages = vec![
550-
create_message(replace_id(), Some(REPLACE_ID)),
551-
create_message(replace_var(), Some(REPLACE_VAR)),
552-
create_message(replace_num(), Some(REPLACE_NUM)),
562+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
563+
create_message(replace_var(), PossibleFixes::Single(REPLACE_VAR)),
564+
create_message(replace_num(), PossibleFixes::Single(REPLACE_NUM)),
553565
];
554566
let result = get_fix_result(messages);
555567
assert_eq!(result.fixed_code, "let foo = 5 * 7;");
@@ -559,7 +571,10 @@ mod test {
559571

560572
#[test]
561573
fn remove_at_the_start() {
562-
let result = get_fix_result(vec![create_message(remove_start(), Some(REMOVE_START))]);
574+
let result = get_fix_result(vec![create_message(
575+
remove_start(),
576+
PossibleFixes::Single(REMOVE_START),
577+
)]);
563578
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var ", ""));
564579
assert_eq!(result.messages.len(), 0);
565580
assert!(result.fixed);
@@ -569,7 +584,7 @@ mod test {
569584
fn remove_at_the_middle() {
570585
let result = get_fix_result(vec![create_message(
571586
remove_middle(Span::default()),
572-
Some(REMOVE_MIDDLE),
587+
PossibleFixes::Single(REMOVE_MIDDLE),
573588
)]);
574589
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "a"));
575590
assert_eq!(result.messages.len(), 0);
@@ -578,7 +593,8 @@ mod test {
578593

579594
#[test]
580595
fn remove_at_the_end() {
581-
let result = get_fix_result(vec![create_message(remove_end(), Some(REMOVE_END))]);
596+
let result =
597+
get_fix_result(vec![create_message(remove_end(), PossibleFixes::Single(REMOVE_END))]);
582598
assert_eq!(result.fixed_code, TEST_CODE.cow_replace(" * 7", ""));
583599
assert_eq!(result.messages.len(), 0);
584600
assert!(result.fixed);
@@ -587,9 +603,9 @@ mod test {
587603
#[test]
588604
fn replace_at_start_remove_at_middle_insert_at_end() {
589605
let result = get_fix_result(vec![
590-
create_message(insert_at_end(), Some(INSERT_AT_END)),
591-
create_message(remove_end(), Some(REMOVE_END)),
592-
create_message(replace_var(), Some(REPLACE_VAR)),
606+
create_message(insert_at_end(), PossibleFixes::Single(INSERT_AT_END)),
607+
create_message(remove_end(), PossibleFixes::Single(REMOVE_END)),
608+
create_message(replace_var(), PossibleFixes::Single(REPLACE_VAR)),
593609
]);
594610
assert_eq!(result.fixed_code, "let answer = 6;// end");
595611
assert_eq!(result.messages.len(), 0);
@@ -599,8 +615,8 @@ mod test {
599615
#[test]
600616
fn apply_one_fix_when_spans_overlap() {
601617
let result = get_fix_result(vec![
602-
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
603-
create_message(replace_id(), Some(REPLACE_ID)),
618+
create_message(remove_middle(Span::default()), PossibleFixes::Single(REMOVE_MIDDLE)),
619+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
604620
]);
605621
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
606622
assert_eq!(result.messages.len(), 1);
@@ -611,8 +627,8 @@ mod test {
611627
#[test]
612628
fn apply_two_fix_when_the_start_the_same_as_the_previous_end() {
613629
let result = get_fix_result(vec![
614-
create_message(remove_start(), Some(REMOVE_START)),
615-
create_message(replace_id(), Some(REPLACE_ID)),
630+
create_message(remove_start(), PossibleFixes::Single(REMOVE_START)),
631+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
616632
]);
617633
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("var answer", "foo"));
618634
assert_eq!(result.messages.len(), 0);
@@ -622,9 +638,9 @@ mod test {
622638
#[test]
623639
fn apply_one_fix_when_range_overlap_and_one_message_has_no_fix() {
624640
let result = get_fix_result(vec![
625-
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
626-
create_message(replace_id(), Some(REPLACE_ID)),
627-
create_message(no_fix(Span::default()), None),
641+
create_message(remove_middle(Span::default()), PossibleFixes::Single(REMOVE_MIDDLE)),
642+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
643+
create_message(no_fix(Span::default()), PossibleFixes::None),
628644
]);
629645
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
630646
assert_eq!(result.messages.len(), 2);
@@ -636,19 +652,20 @@ mod test {
636652
#[test]
637653
fn apply_same_fix_when_span_overlap_regardless_of_order() {
638654
let result1 = get_fix_result(vec![
639-
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
640-
create_message(replace_id(), Some(REPLACE_ID)),
655+
create_message(remove_middle(Span::default()), PossibleFixes::Single(REMOVE_MIDDLE)),
656+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
641657
]);
642658
let result2 = get_fix_result(vec![
643-
create_message(replace_id(), Some(REPLACE_ID)),
644-
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
659+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
660+
create_message(remove_middle(Span::default()), PossibleFixes::Single(REMOVE_MIDDLE)),
645661
]);
646662
assert_eq!(result1.fixed_code, result2.fixed_code);
647663
}
648664

649665
#[test]
650666
fn should_not_apply_fix_with_one_no_fix() {
651-
let result = get_fix_result(vec![create_message(no_fix(Span::default()), None)]);
667+
let result =
668+
get_fix_result(vec![create_message(no_fix(Span::default()), PossibleFixes::None)]);
652669
assert_eq!(result.fixed_code, TEST_CODE);
653670
assert_eq!(result.messages.len(), 1);
654671
assert_eq!(result.messages[0].error.to_string(), "nofix");
@@ -658,9 +675,9 @@ mod test {
658675
#[test]
659676
fn sort_no_fix_messages_correctly() {
660677
let result = get_fix_result(vec![
661-
create_message(replace_id(), Some(REPLACE_ID)),
662-
Message::new(no_fix_2(Span::new(1, 7)), None),
663-
Message::new(no_fix_1(Span::new(1, 3)), None),
678+
create_message(replace_id(), PossibleFixes::Single(REPLACE_ID)),
679+
Message::new(no_fix_2(Span::new(1, 7)), PossibleFixes::None),
680+
Message::new(no_fix_1(Span::new(1, 3)), PossibleFixes::None),
664681
]);
665682
assert_eq!(result.fixed_code, TEST_CODE.cow_replace("answer", "foo"));
666683
assert_eq!(result.messages.len(), 2);

crates/oxc_linter/src/service/runtime.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -495,9 +495,10 @@ impl<'l> Runtime<'l> {
495495
Rc::new(section.semantic.unwrap()),
496496
Arc::clone(&module_record),
497497
),
498-
Err(errors) => {
499-
errors.into_iter().map(|err| Message::new(err, None)).collect()
500-
}
498+
Err(errors) => errors
499+
.into_iter()
500+
.map(|err| Message::new(err, PossibleFixes::None))
501+
.collect(),
501502
};
502503

503504
let source_text = section.source.source_text;
@@ -705,9 +706,10 @@ impl<'l> Runtime<'l> {
705706
Rc::new(section.semantic.unwrap()),
706707
Arc::clone(&module_record),
707708
),
708-
Err(errors) => {
709-
errors.into_iter().map(|err| Message::new(err, None)).collect()
710-
}
709+
Err(errors) => errors
710+
.into_iter()
711+
.map(|err| Message::new(err, PossibleFixes::None))
712+
.collect(),
711713
}
712714
.into_iter()
713715
.map(|message| message.clone_in(allocator)),

0 commit comments

Comments
 (0)