refactor(linter): clean up diagnostics in fixer

This commit is contained in:
Boshen 2024-05-12 10:45:22 +08:00
parent 1b4ebb3166
commit 5671714adb
No known key found for this signature in database
GPG key ID: 9C7A8C8AB22BEBD1

View file

@ -19,14 +19,12 @@ impl<'a> Fix<'a> {
}
}
#[derive(Debug)]
pub struct FixResult<'a> {
pub fixed: bool,
pub fixed_code: Cow<'a, str>,
pub messages: Vec<Message<'a>>,
}
#[derive(Debug)]
pub struct Message<'a> {
pub error: Error,
start: u32,
@ -108,7 +106,7 @@ impl<'a> Fixer<'a> {
let mut messages = self.messages.into_iter().filter(|m| !m.fixed).collect::<Vec<_>>();
messages.sort_by_key(|m| (m.start, m.end));
return FixResult { fixed, fixed_code: Cow::Owned(output), messages };
FixResult { fixed, fixed_code: Cow::Owned(output), messages }
}
}
@ -116,103 +114,101 @@ impl<'a> Fixer<'a> {
mod test {
use std::borrow::Cow;
use oxc_diagnostics::{
miette::{self, Diagnostic},
thiserror::Error,
Error,
};
use oxc_diagnostics::{Error, OxcDiagnostic};
use oxc_span::Span;
use super::{Fix, FixResult, Fixer, Message};
fn insert_at_end() -> OxcDiagnostic {
OxcDiagnostic::warning("End")
}
fn insert_at_start() -> OxcDiagnostic {
OxcDiagnostic::warning("Start")
}
fn insert_at_middle() -> OxcDiagnostic {
OxcDiagnostic::warning("Multiply")
}
fn replace_id() -> OxcDiagnostic {
OxcDiagnostic::warning("foo")
}
fn replace_var() -> OxcDiagnostic {
OxcDiagnostic::warning("let")
}
fn replace_num() -> OxcDiagnostic {
OxcDiagnostic::warning("5")
}
fn remove_start() -> OxcDiagnostic {
OxcDiagnostic::warning("removestart")
}
fn remove_middle(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warning("removemiddle").with_labels([span0.into()])
}
fn remove_end() -> OxcDiagnostic {
OxcDiagnostic::warning("removeend")
}
fn reverse_range() -> OxcDiagnostic {
OxcDiagnostic::warning("reversed range")
}
fn no_fix(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warning("nofix").with_labels([span0.into()])
}
fn no_fix_1(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warning("nofix1").with_labels([span0.into()])
}
fn no_fix_2(span0: Span) -> OxcDiagnostic {
OxcDiagnostic::warning("nofix2").with_labels([span0.into()])
}
const TEST_CODE: &str = "var answer = 6 * 7;";
#[derive(Debug, Error, Diagnostic)]
#[error("End")]
struct InsertAtEnd;
const INSERT_AT_END: Fix = Fix { span: Span::new(19, 19), content: Cow::Borrowed("// end") };
#[derive(Debug, Error, Diagnostic)]
#[error("Start")]
struct InsertAtStart;
const INSERT_AT_START: Fix = Fix { span: Span::new(0, 0), content: Cow::Borrowed("// start") };
#[derive(Debug, Error, Diagnostic)]
#[error("Multiply")]
struct InsertAtMiddle;
const INSERT_AT_MIDDLE: Fix = Fix { span: Span::new(13, 13), content: Cow::Borrowed("5 *") };
#[derive(Debug, Error, Diagnostic)]
#[error("foo")]
struct ReplaceId;
const REPLACE_ID: Fix = Fix { span: Span::new(4, 10), content: Cow::Borrowed("foo") };
#[derive(Debug, Error, Diagnostic)]
#[error("let")]
struct ReplaceVar;
const REPLACE_VAR: Fix = Fix { span: Span::new(0, 3), content: Cow::Borrowed("let") };
#[derive(Debug, Error, Diagnostic)]
#[error("5")]
struct ReplaceNum;
const REPLACE_NUM: Fix = Fix { span: Span::new(13, 14), content: Cow::Borrowed("5") };
#[derive(Debug, Error, Diagnostic)]
#[error("removestart")]
struct RemoveStart;
const REMOVE_START: Fix = Fix::delete(Span::new(0, 4));
#[derive(Debug, Error, Diagnostic)]
#[error("removemiddle")]
struct RemoveMiddle(#[label] pub Span);
const REMOVE_MIDDLE: Fix = Fix::delete(Span::new(5, 10));
#[derive(Debug, Error, Diagnostic)]
#[error("removeend")]
struct RemoveEnd;
const REMOVE_END: Fix = Fix::delete(Span::new(14, 18));
#[derive(Debug, Error, Diagnostic)]
#[error("reversed range")]
struct ReverseRange;
const REVERSE_RANGE: Fix = Fix { span: Span::new(3, 0), content: Cow::Borrowed(" ") };
#[derive(Debug, Error, Diagnostic)]
#[error("nofix")]
struct NoFix(#[label] pub Span);
#[derive(Debug, Error, Diagnostic)]
#[error("nofix1")]
struct NoFix1(#[label] pub Span);
#[derive(Debug, Error, Diagnostic)]
#[error("nofix2")]
struct NoFix2(#[label] pub Span);
fn get_fix_result(messages: Vec<Message>) -> FixResult {
Fixer::new(TEST_CODE, messages).fix()
}
fn create_message<T: Into<Error>>(error: T, fix: Option<Fix>) -> Message {
Message::new(error.into(), fix)
fn create_message(error: OxcDiagnostic, fix: Option<Fix>) -> Message {
Message::new(Error::from(error), fix)
}
#[test]
fn insert_at_the_end() {
let result = get_fix_result(vec![create_message(InsertAtEnd, Some(INSERT_AT_END))]);
let result = get_fix_result(vec![create_message(insert_at_end(), Some(INSERT_AT_END))]);
assert_eq!(result.fixed_code, TEST_CODE.to_string() + INSERT_AT_END.content.as_ref());
assert_eq!(result.messages.len(), 0);
}
#[test]
fn insert_at_the_start() {
let result = get_fix_result(vec![create_message(InsertAtStart, Some(INSERT_AT_START))]);
let result = get_fix_result(vec![create_message(insert_at_start(), Some(INSERT_AT_START))]);
assert_eq!(result.fixed_code, INSERT_AT_START.content.to_string() + TEST_CODE);
assert_eq!(result.messages.len(), 0);
}
#[test]
fn insert_at_the_middle() {
let result = get_fix_result(vec![create_message(InsertAtMiddle, Some(INSERT_AT_MIDDLE))]);
let result =
get_fix_result(vec![create_message(insert_at_middle(), Some(INSERT_AT_MIDDLE))]);
assert_eq!(
result.fixed_code,
TEST_CODE.replace("6 *", &format!("{}{}", INSERT_AT_MIDDLE.content, "6 *"))
@ -223,9 +219,9 @@ mod test {
#[test]
fn insert_at_the_start_middle_end() {
let messages = vec![
create_message(InsertAtMiddle, Some(INSERT_AT_MIDDLE)),
create_message(InsertAtStart, Some(INSERT_AT_START)),
create_message(InsertAtEnd, Some(INSERT_AT_END)),
create_message(insert_at_middle(), Some(INSERT_AT_MIDDLE)),
create_message(insert_at_start(), Some(INSERT_AT_START)),
create_message(insert_at_end(), Some(INSERT_AT_END)),
];
let result = get_fix_result(messages);
assert_eq!(
@ -242,13 +238,13 @@ mod test {
#[test]
fn ignore_reverse_range() {
let result = get_fix_result(vec![create_message(ReverseRange, Some(REVERSE_RANGE))]);
let result = get_fix_result(vec![create_message(reverse_range(), Some(REVERSE_RANGE))]);
assert_eq!(result.fixed_code, TEST_CODE);
}
#[test]
fn replace_at_the_start() {
let result = get_fix_result(vec![create_message(ReplaceVar, Some(REPLACE_VAR))]);
let result = get_fix_result(vec![create_message(replace_var(), Some(REPLACE_VAR))]);
assert_eq!(result.fixed_code, TEST_CODE.replace("var", "let"));
assert_eq!(result.messages.len(), 0);
assert!(result.fixed);
@ -256,7 +252,7 @@ mod test {
#[test]
fn replace_at_the_middle() {
let result = get_fix_result(vec![create_message(ReplaceId, Some(REPLACE_ID))]);
let result = get_fix_result(vec![create_message(replace_id(), Some(REPLACE_ID))]);
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
assert_eq!(result.messages.len(), 0);
assert!(result.fixed);
@ -264,7 +260,7 @@ mod test {
#[test]
fn replace_at_the_end() {
let result = get_fix_result(vec![create_message(ReplaceNum, Some(REPLACE_NUM))]);
let result = get_fix_result(vec![create_message(replace_num(), Some(REPLACE_NUM))]);
assert_eq!(result.fixed_code, TEST_CODE.replace('6', "5"));
assert_eq!(result.messages.len(), 0);
assert!(result.fixed);
@ -273,9 +269,9 @@ mod test {
#[test]
fn replace_at_the_start_middle_end() {
let messages = vec![
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(ReplaceVar, Some(REPLACE_VAR)),
create_message(ReplaceNum, Some(REPLACE_NUM)),
create_message(replace_id(), Some(REPLACE_ID)),
create_message(replace_var(), Some(REPLACE_VAR)),
create_message(replace_num(), Some(REPLACE_NUM)),
];
let result = get_fix_result(messages);
assert_eq!(result.fixed_code, "let foo = 5 * 7;");
@ -285,7 +281,7 @@ mod test {
#[test]
fn remove_at_the_start() {
let result = get_fix_result(vec![create_message(RemoveStart, Some(REMOVE_START))]);
let result = get_fix_result(vec![create_message(remove_start(), Some(REMOVE_START))]);
assert_eq!(result.fixed_code, TEST_CODE.replace("var ", ""));
assert_eq!(result.messages.len(), 0);
assert!(result.fixed);
@ -294,7 +290,7 @@ mod test {
#[test]
fn remove_at_the_middle() {
let result = get_fix_result(vec![create_message(
RemoveMiddle(Span::default()),
remove_middle(Span::default()),
Some(REMOVE_MIDDLE),
)]);
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "a"));
@ -304,7 +300,7 @@ mod test {
#[test]
fn remove_at_the_end() {
let result = get_fix_result(vec![create_message(RemoveEnd, Some(REMOVE_END))]);
let result = get_fix_result(vec![create_message(remove_end(), Some(REMOVE_END))]);
assert_eq!(result.fixed_code, TEST_CODE.replace(" * 7", ""));
assert_eq!(result.messages.len(), 0);
assert!(result.fixed);
@ -313,9 +309,9 @@ mod test {
#[test]
fn replace_at_start_remove_at_middle_insert_at_end() {
let result = get_fix_result(vec![
create_message(InsertAtEnd, Some(INSERT_AT_END)),
create_message(RemoveEnd, Some(REMOVE_END)),
create_message(ReplaceVar, Some(REPLACE_VAR)),
create_message(insert_at_end(), Some(INSERT_AT_END)),
create_message(remove_end(), Some(REMOVE_END)),
create_message(replace_var(), Some(REPLACE_VAR)),
]);
assert_eq!(result.fixed_code, "let answer = 6;// end");
assert_eq!(result.messages.len(), 0);
@ -325,8 +321,8 @@ mod test {
#[test]
fn apply_one_fix_when_spans_overlap() {
let result = get_fix_result(vec![
create_message(RemoveMiddle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(replace_id(), Some(REPLACE_ID)),
]);
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
assert_eq!(result.messages.len(), 1);
@ -337,8 +333,8 @@ mod test {
#[test]
fn apply_one_fix_when_the_start_the_same_as_the_previous_end() {
let result = get_fix_result(vec![
create_message(RemoveStart, Some(REMOVE_START)),
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(remove_start(), Some(REMOVE_START)),
create_message(replace_id(), Some(REPLACE_ID)),
]);
assert_eq!(result.fixed_code, TEST_CODE.replace("var ", ""));
assert_eq!(result.messages.len(), 1);
@ -349,9 +345,9 @@ mod test {
#[test]
fn apply_one_fix_when_range_overlap_and_one_message_has_no_fix() {
let result = get_fix_result(vec![
create_message(RemoveMiddle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(NoFix(Span::default()), None),
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(replace_id(), Some(REPLACE_ID)),
create_message(no_fix(Span::default()), None),
]);
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
assert_eq!(result.messages.len(), 2);
@ -363,19 +359,19 @@ mod test {
#[test]
fn apply_same_fix_when_span_overlap_regardless_of_order() {
let result1 = get_fix_result(vec![
create_message(RemoveMiddle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(replace_id(), Some(REPLACE_ID)),
]);
let result2 = get_fix_result(vec![
create_message(ReplaceId, Some(REPLACE_ID)),
create_message(RemoveMiddle(Span::default()), Some(REMOVE_MIDDLE)),
create_message(replace_id(), Some(REPLACE_ID)),
create_message(remove_middle(Span::default()), Some(REMOVE_MIDDLE)),
]);
assert_eq!(result1.fixed_code, result2.fixed_code);
}
#[test]
fn should_not_apply_fix_with_one_no_fix() {
let result = get_fix_result(vec![create_message(NoFix(Span::default()), None)]);
let result = get_fix_result(vec![create_message(no_fix(Span::default()), None)]);
assert_eq!(result.fixed_code, TEST_CODE);
assert_eq!(result.messages.len(), 1);
assert_eq!(result.messages[0].error.to_string(), "nofix");
@ -385,9 +381,9 @@ mod test {
#[test]
fn sort_no_fix_messages_correctly() {
let result = get_fix_result(vec![
create_message(ReplaceId, Some(REPLACE_ID)),
Message::new(NoFix2(Span::new(1, 7)).into(), None),
Message::new(NoFix1(Span::new(1, 3)).into(), None),
create_message(replace_id(), Some(REPLACE_ID)),
Message::new(no_fix_2(Span::new(1, 7)).into(), None),
Message::new(no_fix_1(Span::new(1, 3)).into(), None),
]);
assert_eq!(result.fixed_code, TEST_CODE.replace("answer", "foo"));
assert_eq!(result.messages.len(), 2);