ruff_linter,ruff_python_parser: migrate to updated annotate-snippets

This is pretty much just moving to the new API and taking care to use
byte offsets. This is *almost* enough. The next commit will fix a bug
involving the handling of unprintable characters as a result of
switching to byte offsets.
This commit is contained in:
Andrew Gallant 2024-12-20 14:19:32 -05:00 committed by Andrew Gallant
parent 1b97677779
commit 84179aaa96
6 changed files with 43 additions and 99 deletions

25
Cargo.lock generated
View file

@ -57,16 +57,6 @@ version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7021ce4924a3f25f802b2cccd1af585e39ea1a363a1aa2e72afe54b67a3a7a7"
[[package]]
name = "annotate-snippets"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ccaf7e9dfbb6ab22c82e473cd1a8a7bd313c19a5b7e40970f3d89ef5a5c9e81e"
dependencies = [
"unicode-width 0.1.13",
"yansi-term",
]
[[package]]
name = "anstream"
version = "0.6.18"
@ -326,7 +316,7 @@ version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5b5db619f3556839cb2223ae86ff3f9a09da2c5013be42bc9af08c9589bf70c"
dependencies = [
"annotate-snippets 0.6.1",
"annotate-snippets",
]
[[package]]
@ -2837,7 +2827,6 @@ name = "ruff_linter"
version = "0.9.1"
dependencies = [
"aho-corasick",
"annotate-snippets 0.9.2",
"anyhow",
"bitflags 2.7.0",
"chrono",
@ -2861,6 +2850,7 @@ dependencies = [
"pyproject-toml",
"quick-junit",
"regex",
"ruff_annotate_snippets",
"ruff_cache",
"ruff_diagnostics",
"ruff_index",
@ -3020,13 +3010,13 @@ dependencies = [
name = "ruff_python_parser"
version = "0.0.0"
dependencies = [
"annotate-snippets 0.9.2",
"anyhow",
"bitflags 2.7.0",
"bstr",
"compact_str",
"insta",
"memchr",
"ruff_annotate_snippets",
"ruff_python_ast",
"ruff_python_trivia",
"ruff_source_file",
@ -4651,15 +4641,6 @@ version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
[[package]]
name = "yansi-term"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
dependencies = [
"winapi",
]
[[package]]
name = "yoke"
version = "0.7.4"

View file

@ -44,7 +44,6 @@ red_knot_test = { path = "crates/red_knot_test" }
red_knot_workspace = { path = "crates/red_knot_workspace", default-features = false }
aho-corasick = { version = "1.1.3" }
annotate-snippets = { version = "0.9.2", features = ["color"] }
anstream = { version = "0.6.18" }
anstyle = { version = "1.0.10" }
anyhow = { version = "1.0.80" }

View file

@ -13,6 +13,7 @@ license = { workspace = true }
[lib]
[dependencies]
ruff_annotate_snippets = { workspace = true }
ruff_cache = { workspace = true }
ruff_diagnostics = { workspace = true, features = ["serde"] }
ruff_index = { workspace = true }
@ -30,7 +31,6 @@ ruff_source_file = { workspace = true, features = ["serde"] }
ruff_text_size = { workspace = true }
aho-corasick = { workspace = true }
annotate-snippets = { workspace = true, features = ["color"] }
anyhow = { workspace = true }
bitflags = { workspace = true }
chrono = { workspace = true }

View file

@ -2,10 +2,9 @@ use std::borrow::Cow;
use std::fmt::{Display, Formatter};
use std::io::Write;
use annotate_snippets::display_list::{DisplayList, FormatOptions};
use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation};
use bitflags::bitflags;
use colored::Colorize;
use ruff_annotate_snippets::{Level, Renderer, Snippet};
use ruff_notebook::NotebookIndex;
use ruff_source_file::{OneIndexed, SourceLocation};
@ -186,12 +185,8 @@ pub(super) struct MessageCodeFrame<'a> {
impl Display for MessageCodeFrame<'_> {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
let suggestion = self.message.suggestion();
let footer = if suggestion.is_some() {
vec![Annotation {
id: None,
label: suggestion,
annotation_type: AnnotationType::Help,
}]
let footers = if let Some(suggestion) = suggestion {
vec![Level::Help.title(suggestion)]
} else {
Vec::new()
};
@ -257,51 +252,37 @@ impl Display for MessageCodeFrame<'_> {
let source_text = source.text.show_nonprinting();
let start_char = source.text[TextRange::up_to(source.annotation_range.start())]
.chars()
.count();
let char_length = source.text[source.annotation_range].chars().count();
let label = self
.message
.rule()
.map_or_else(String::new, |rule| rule.noqa_code().to_string());
let snippet = Snippet {
title: None,
slices: vec![Slice {
source: &source_text,
line_start: self.notebook_index.map_or_else(
|| start_index.get(),
|notebook_index| {
notebook_index
.cell_row(start_index)
.unwrap_or(OneIndexed::MIN)
.get()
},
),
annotations: vec![SourceAnnotation {
label: &label,
annotation_type: AnnotationType::Error,
range: (start_char, start_char + char_length),
}],
// The origin (file name, line number, and column number) is already encoded
// in the `label`.
origin: None,
fold: false,
}],
footer,
opt: FormatOptions {
#[cfg(test)]
color: false,
#[cfg(not(test))]
color: colored::control::SHOULD_COLORIZE.should_colorize(),
..FormatOptions::default()
let line_start = self.notebook_index.map_or_else(
|| start_index.get(),
|notebook_index| {
notebook_index
.cell_row(start_index)
.unwrap_or(OneIndexed::MIN)
.get()
},
};
);
writeln!(f, "{message}", message = DisplayList::from(snippet))
let span = usize::from(source.annotation_range.start())
..usize::from(source.annotation_range.end());
let annotation = Level::Error.span(span).label(&label);
let snippet = Snippet::source(&source_text)
.line_start(line_start)
.annotation(annotation)
.fold(false);
let message = Level::None.title("").snippet(snippet).footers(footers);
let renderer = if !cfg!(test) && colored::control::SHOULD_COLORIZE.should_colorize() {
Renderer::styled()
} else {
Renderer::plain()
};
let rendered = renderer.render(message);
writeln!(f, "{rendered}")
}
}

View file

@ -28,9 +28,9 @@ unicode_names2 = { workspace = true }
unicode-normalization = { workspace = true }
[dev-dependencies]
ruff_annotate_snippets = { workspace = true }
ruff_source_file = { workspace = true }
annotate-snippets = { workspace = true }
anyhow = { workspace = true }
insta = { workspace = true, features = ["glob"] }
walkdir = { workspace = true }

View file

@ -3,9 +3,7 @@ use std::fmt::{Formatter, Write};
use std::fs;
use std::path::Path;
use annotate_snippets::display_list::{DisplayList, FormatOptions};
use annotate_snippets::snippet::{AnnotationType, Slice, Snippet, SourceAnnotation};
use ruff_annotate_snippets::{Level, Renderer, Snippet};
use ruff_python_ast::visitor::source_order::{walk_module, SourceOrderVisitor, TraversalSignal};
use ruff_python_ast::{AnyNodeRef, Mod};
use ruff_python_parser::{parse_unchecked, Mode, ParseErrorType, Token};
@ -203,33 +201,18 @@ impl std::fmt::Display for CodeFrame<'_> {
.source_code
.slice(TextRange::new(start_offset, end_offset));
let start_char = source[TextRange::up_to(annotation_range.start())]
.chars()
.count();
let char_length = source[annotation_range].chars().count();
let label = format!("Syntax Error: {error}", error = self.error);
let snippet = Snippet {
title: None,
slices: vec![Slice {
source,
line_start: start_index.get(),
annotations: vec![SourceAnnotation {
label: &label,
annotation_type: AnnotationType::Error,
range: (start_char, start_char + char_length),
}],
// The origin (file name, line number, and column number) is already encoded
// in the `label`.
origin: None,
fold: false,
}],
footer: Vec::new(),
opt: FormatOptions::default(),
};
writeln!(f, "{message}", message = DisplayList::from(snippet))
let span = usize::from(annotation_range.start())..usize::from(annotation_range.end());
let annotation = Level::Error.span(span).label(&label);
let snippet = Snippet::source(source)
.line_start(start_index.get())
.annotation(annotation)
.fold(false);
let message = Level::None.title("").snippet(snippet);
let renderer = Renderer::plain();
let rendered = renderer.render(message);
writeln!(f, "{rendered}")
}
}