Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
  • Loading branch information
InSyncWithFoo committed Nov 6, 2024
1 parent 6ee779d commit e54e9a0
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 49 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ memchr = { version = "2.7.1" }
mimalloc = { version = "0.1.39" }
natord = { version = "1.0.9" }
notify = { version = "7.0.0" }
once_cell = { version = "1.20.2" }
ordermap = { version = "0.5.0" }
path-absolutize = { version = "3.1.1" }
path-slash = { version = "0.2.1" }
Expand Down
1 change: 1 addition & 0 deletions crates/ruff_linter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ libcst = { workspace = true }
log = { workspace = true }
memchr = { workspace = true }
natord = { workspace = true }
once_cell = { workspace = true }
path-absolutize = { workspace = true, features = [
"once_cell_cache",
"use_unix_paths_on_wasm",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
use crate::noqa::{Directive, ParseError, ParsedFileExemption};
use crate::Locator;
use once_cell::sync::Lazy;
use regex::Regex;
use ruff_diagnostics::{AlwaysFixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_trivia::CommentRanges;
use ruff_text_size::TextRange;
use ruff_text_size::TextSize;

type EndIndex = usize;

const KNOWN_COMMON_HINT: [&str; 6] = ["fmt", "isort", "mypy", "nopycln", "pyright", "type"];

#[derive(Debug, Eq, PartialEq)]
enum SpecialComment {
/// `# noqa`, `# noqa: A123, B456`
Expand All @@ -33,15 +31,13 @@ enum SpecialComment {
impl SpecialComment {
fn formatted(&self) -> String {
match self {
SpecialComment::Common { hint, rest } => format!("# {}: {}", hint.to_lowercase(), rest)
.trim_ascii_end()
.to_owned(),
SpecialComment::Common { hint, rest } => {
format!("# {}: {}", hint.to_lowercase(), rest)
}
SpecialComment::RuffIsort(rest) => {
format!("# ruff: isort: {rest}")
}
SpecialComment::Noqa(None) => {
format!("# noqa")
}
SpecialComment::Noqa(None) => "# noqa".to_string(),
SpecialComment::Noqa(Some(codes)) => {
format!("# noqa: {}", codes.join(", "))
}
Expand Down Expand Up @@ -102,34 +98,34 @@ fn add_diagnostic_if_applicable(
diagnostics: &mut Vec<Diagnostic>,
comment: SpecialComment,
original_comment_text: &str,
range: TextRange,
original_comment_text_range: TextRange,
) {
let formatted_comment = comment.formatted();
let formatted_comment_text = comment.formatted();

if original_comment_text == formatted_comment {
if original_comment_text == formatted_comment_text {
return;
}

let edit = Edit::range_replacement(formatted_comment, range);
let edit = Edit::range_replacement(formatted_comment_text, original_comment_text_range);
let fix = Fix::safe_edit(edit);

let violation = UnformattedSpecialComment(comment);
let diagnostic = Diagnostic::new(violation, range).with_fix(fix);
let diagnostic = Diagnostic::new(violation, original_comment_text_range).with_fix(fix);

diagnostics.push(diagnostic);
}

fn parse_code_list(code_list: &str) -> Vec<String> {
static PATTERN: Regex = Lazy::new(Regex::new(r"[A-Z]+[A-Za-z0-9]+"));
static PATTERN: Lazy<Regex> = Lazy::new(|| Regex::new(r"[A-Z]+[A-Za-z0-9]+").unwrap());

PATTERN
.find_iter(list)
.find_iter(code_list)
.map(|code| code.as_str().to_owned())
.collect()
}

fn try_parse_file_level_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
static PATTERN: Regex = Lazy::new(
static PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"(?x)
^
Expand All @@ -147,12 +143,10 @@ fn try_parse_file_level_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
$
",
)
.unwrap(),
);
.unwrap()
});

let Some(result) = PATTERN.captures(text) else {
return None;
};
let result = PATTERN.captures(text)?;

let end_index = result.get(0).unwrap().end();
let hint = result.name("hint").unwrap().as_str().to_owned();
Expand All @@ -164,7 +158,7 @@ fn try_parse_file_level_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
}

fn try_parse_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
static PATTERN: Regex = Lazy::new(
static PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"(?x)
^
Expand All @@ -174,18 +168,16 @@ fn try_parse_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
:\s*
(?<code_list>
[A-Z]+[A-Za-z0-9]+
(?:[\h,]+[A-Z]+[A-Za-z0-9]+)*
(?:[\s,]+[A-Z]+[A-Za-z0-9]+)*
)?
)?
$
",
)
.unwrap(),
);
.unwrap()
});

let Some(result) = PATTERN.captures(text) else {
return None;
};
let result = PATTERN.captures(text)?;

let end_index = result.get(0).unwrap().end();
let codes = result
Expand All @@ -196,7 +188,7 @@ fn try_parse_noqa(text: &str) -> Option<(EndIndex, SpecialComment)> {
}

fn try_parse_ruff_isort(text: &str) -> Option<(EndIndex, SpecialComment)> {
static PATTERN: Regex = Lazy::new(
static PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"(?x)
^
Expand All @@ -206,12 +198,10 @@ fn try_parse_ruff_isort(text: &str) -> Option<(EndIndex, SpecialComment)> {
(?<rest>.+)
",
)
.unwrap(),
);
.unwrap()
});

let Some(result) = PATTERN.captures(text) else {
return None;
};
let result = PATTERN.captures(text)?;

let end_index = result.get(0).unwrap().end();
let rest = result.name("rest").unwrap().as_str().to_owned();
Expand All @@ -220,43 +210,52 @@ fn try_parse_ruff_isort(text: &str) -> Option<(EndIndex, SpecialComment)> {
}

fn try_parse_common(text: &str) -> Option<(EndIndex, SpecialComment)> {
static PATTERN: Lazy<Regex> = Lazy::new(
static PATTERN: Lazy<Regex> = Lazy::new(|| {
Regex::new(
r"(?x)
^
\#\s*
(?<hint>type|mypy|pyright|fmt|isort|nopycln):\s*
(?<rest>.+)
"
",
)
.unwrap()
);
});

let Some(result) = PATTERN.captures(text);
let result = PATTERN.captures(text)?;

let end_index = result.get(0).unwrap().end();
let hint = result.name("hint").unwrap().as_str().to_owned();
let rest = result.name("rest").unwrap().as_str().to_owned();

Some((end_index, SpecialComment::Common(hint, rest)))
Some((end_index, SpecialComment::Common { hint, rest }))
}

macro_rules! parse_and_handle_comment {
($parse:ident, $text:ident, $diagnostics:ident, $range:ident) => {
if let Some((end_index, comment)) = $parse($text) {
($parse:ident, $text:ident, $diagnostics:ident, $absolute_start_index:ident) => {
if let Some((relative_end_index, comment)) = $parse($text) {
let comment_text = &$text[..end_index];
let absolute_end_index = $absolute_start_index + relative_end_index;

let Ok(start) = TryInto::<TextSize>::try_into($absolute_start_index) else {
return;
};
let Ok(end) = TryInto::<TextSize>::try_into(absolute_end_index) else {
return;
};
let range = TextRange::new(start, end);

add_diagnostic_if_applicable($diagnostics, comment, comment_text, $range);
add_diagnostic_if_applicable($diagnostics, comment, comment_text, range);
return;
}
};
}

fn check_single_comment(diagnostics: &mut Vec<Diagnostic>, text: &str, range: TextRange) {
parse_and_handle_comment!(try_parse_file_level_noqa, text, diagnostics, range);
parse_and_handle_comment!(try_parse_noqa, text, diagnostics, range);
parse_and_handle_comment!(try_parse_ruff_isort, text, diagnostics, range);
parse_and_handle_comment!(try_parse_common, text, diagnostics, range);
fn check_single_comment(diagnostics: &mut Vec<Diagnostic>, text: &str, start_index: usize) {
parse_and_handle_comment!(try_parse_file_level_noqa, text, diagnostics, start_index);
parse_and_handle_comment!(try_parse_noqa, text, diagnostics, start_index);
parse_and_handle_comment!(try_parse_ruff_isort, text, diagnostics, start_index);
parse_and_handle_comment!(try_parse_common, text, diagnostics, start_index);
}

/// RUF104
Expand All @@ -273,7 +272,7 @@ pub(crate) fn unformatted_special_comment(
continue;
}

check_single_comment(diagnostics, text, range);
check_single_comment(diagnostics, &text[index..], index);
}
}
}

0 comments on commit e54e9a0

Please sign in to comment.