Skip to content

Commit 8a8ba10

Browse files
committed
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.
1 parent 90ef6e1 commit 8a8ba10

File tree

6 files changed

+43
-99
lines changed

6 files changed

+43
-99
lines changed

Cargo.lock

Lines changed: 3 additions & 22 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ red_knot_test = { path = "crates/red_knot_test" }
4444
red_knot_workspace = { path = "crates/red_knot_workspace", default-features = false }
4545

4646
aho-corasick = { version = "1.1.3" }
47-
annotate-snippets = { version = "0.9.2", features = ["color"] }
4847
anstream = { version = "0.6.18" }
4948
anstyle = { version = "1.0.10" }
5049
anyhow = { version = "1.0.80" }

crates/ruff_linter/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ license = { workspace = true }
1313
[lib]
1414

1515
[dependencies]
16+
ruff_annotate_snippets = { workspace = true }
1617
ruff_cache = { workspace = true }
1718
ruff_diagnostics = { workspace = true, features = ["serde"] }
1819
ruff_index = { workspace = true }
@@ -30,7 +31,6 @@ ruff_source_file = { workspace = true, features = ["serde"] }
3031
ruff_text_size = { workspace = true }
3132

3233
aho-corasick = { workspace = true }
33-
annotate-snippets = { workspace = true, features = ["color"] }
3434
anyhow = { workspace = true }
3535
bitflags = { workspace = true }
3636
chrono = { workspace = true }

crates/ruff_linter/src/message/text.rs

Lines changed: 27 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@ use std::borrow::Cow;
22
use std::fmt::{Display, Formatter};
33
use std::io::Write;
44

5-
use annotate_snippets::display_list::{DisplayList, FormatOptions};
6-
use annotate_snippets::snippet::{Annotation, AnnotationType, Slice, Snippet, SourceAnnotation};
75
use bitflags::bitflags;
86
use colored::Colorize;
7+
use ruff_annotate_snippets::{Level, Renderer, Snippet};
98

109
use ruff_notebook::NotebookIndex;
1110
use ruff_source_file::{OneIndexed, SourceLocation};
@@ -186,12 +185,8 @@ pub(super) struct MessageCodeFrame<'a> {
186185
impl Display for MessageCodeFrame<'_> {
187186
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
188187
let suggestion = self.message.suggestion();
189-
let footer = if suggestion.is_some() {
190-
vec![Annotation {
191-
id: None,
192-
label: suggestion,
193-
annotation_type: AnnotationType::Help,
194-
}]
188+
let footers = if let Some(suggestion) = suggestion {
189+
vec![Level::Help.title(suggestion)]
195190
} else {
196191
Vec::new()
197192
};
@@ -257,51 +252,37 @@ impl Display for MessageCodeFrame<'_> {
257252

258253
let source_text = source.text.show_nonprinting();
259254

260-
let start_char = source.text[TextRange::up_to(source.annotation_range.start())]
261-
.chars()
262-
.count();
263-
264-
let char_length = source.text[source.annotation_range].chars().count();
265-
266255
let label = self
267256
.message
268257
.rule()
269258
.map_or_else(String::new, |rule| rule.noqa_code().to_string());
270259

271-
let snippet = Snippet {
272-
title: None,
273-
slices: vec![Slice {
274-
source: &source_text,
275-
line_start: self.notebook_index.map_or_else(
276-
|| start_index.get(),
277-
|notebook_index| {
278-
notebook_index
279-
.cell_row(start_index)
280-
.unwrap_or(OneIndexed::MIN)
281-
.get()
282-
},
283-
),
284-
annotations: vec![SourceAnnotation {
285-
label: &label,
286-
annotation_type: AnnotationType::Error,
287-
range: (start_char, start_char + char_length),
288-
}],
289-
// The origin (file name, line number, and column number) is already encoded
290-
// in the `label`.
291-
origin: None,
292-
fold: false,
293-
}],
294-
footer,
295-
opt: FormatOptions {
296-
#[cfg(test)]
297-
color: false,
298-
#[cfg(not(test))]
299-
color: colored::control::SHOULD_COLORIZE.should_colorize(),
300-
..FormatOptions::default()
260+
let line_start = self.notebook_index.map_or_else(
261+
|| start_index.get(),
262+
|notebook_index| {
263+
notebook_index
264+
.cell_row(start_index)
265+
.unwrap_or(OneIndexed::MIN)
266+
.get()
301267
},
302-
};
268+
);
303269

304-
writeln!(f, "{message}", message = DisplayList::from(snippet))
270+
let span = usize::from(source.annotation_range.start())
271+
..usize::from(source.annotation_range.end());
272+
let annotation = Level::Error.span(span).label(&label);
273+
let snippet = Snippet::source(&source_text)
274+
.line_start(line_start)
275+
.annotation(annotation)
276+
.fold(false);
277+
let message = Level::None.title("").snippet(snippet).footers(footers);
278+
279+
let renderer = if !cfg!(test) && colored::control::SHOULD_COLORIZE.should_colorize() {
280+
Renderer::styled()
281+
} else {
282+
Renderer::plain()
283+
};
284+
let rendered = renderer.render(message);
285+
writeln!(f, "{rendered}")
305286
}
306287
}
307288

crates/ruff_python_parser/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@ unicode_names2 = { workspace = true }
2828
unicode-normalization = { workspace = true }
2929

3030
[dev-dependencies]
31+
ruff_annotate_snippets = { workspace = true }
3132
ruff_source_file = { workspace = true }
3233

33-
annotate-snippets = { workspace = true }
3434
anyhow = { workspace = true }
3535
insta = { workspace = true, features = ["glob"] }
3636
walkdir = { workspace = true }

crates/ruff_python_parser/tests/fixtures.rs

Lines changed: 11 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ use std::fmt::{Formatter, Write};
33
use std::fs;
44
use std::path::Path;
55

6-
use annotate_snippets::display_list::{DisplayList, FormatOptions};
7-
use annotate_snippets::snippet::{AnnotationType, Slice, Snippet, SourceAnnotation};
8-
6+
use ruff_annotate_snippets::{Level, Renderer, Snippet};
97
use ruff_python_ast::visitor::source_order::{walk_module, SourceOrderVisitor, TraversalSignal};
108
use ruff_python_ast::{AnyNodeRef, Mod};
119
use ruff_python_parser::{parse_unchecked, Mode, ParseErrorType, Token};
@@ -203,33 +201,18 @@ impl std::fmt::Display for CodeFrame<'_> {
203201
.source_code
204202
.slice(TextRange::new(start_offset, end_offset));
205203

206-
let start_char = source[TextRange::up_to(annotation_range.start())]
207-
.chars()
208-
.count();
209-
210-
let char_length = source[annotation_range].chars().count();
211204
let label = format!("Syntax Error: {error}", error = self.error);
212205

213-
let snippet = Snippet {
214-
title: None,
215-
slices: vec![Slice {
216-
source,
217-
line_start: start_index.get(),
218-
annotations: vec![SourceAnnotation {
219-
label: &label,
220-
annotation_type: AnnotationType::Error,
221-
range: (start_char, start_char + char_length),
222-
}],
223-
// The origin (file name, line number, and column number) is already encoded
224-
// in the `label`.
225-
origin: None,
226-
fold: false,
227-
}],
228-
footer: Vec::new(),
229-
opt: FormatOptions::default(),
230-
};
231-
232-
writeln!(f, "{message}", message = DisplayList::from(snippet))
206+
let span = usize::from(annotation_range.start())..usize::from(annotation_range.end());
207+
let annotation = Level::Error.span(span).label(&label);
208+
let snippet = Snippet::source(source)
209+
.line_start(start_index.get())
210+
.annotation(annotation)
211+
.fold(false);
212+
let message = Level::None.title("").snippet(snippet);
213+
let renderer = Renderer::plain();
214+
let rendered = renderer.render(message);
215+
writeln!(f, "{rendered}")
233216
}
234217
}
235218

0 commit comments

Comments
 (0)