Skip to content

Commit e7cfe84

Browse files
committed
Fix SourceAnnotation range
1 parent 7e73a1b commit e7cfe84

File tree

10 files changed

+128
-70
lines changed

10 files changed

+128
-70
lines changed

benches/simple.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![allow(clippy::unit_arg)]
12
#[macro_use]
23
extern crate criterion;
34

src/display_list/from_snippet.rs

+64-41
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use crate::snippet;
55
fn format_label(label: Option<&str>, style: Option<DisplayTextStyle>) -> Vec<DisplayTextFragment> {
66
let mut result = vec![];
77
if let Some(label) = label {
8-
let elements: Vec<&str> = label.split("__").collect();
9-
for (idx, element) in elements.iter().enumerate() {
8+
for (idx, element) in label.split("__").enumerate() {
109
let element_style = match style {
1110
Some(s) => s,
1211
None => {
@@ -26,22 +25,22 @@ fn format_label(label: Option<&str>, style: Option<DisplayTextStyle>) -> Vec<Dis
2625
result
2726
}
2827

29-
fn format_title(annotation: &snippet::Annotation) -> DisplayLine {
30-
let label = annotation.label.clone().unwrap_or_default();
28+
fn format_title(annotation: snippet::Annotation) -> DisplayLine {
29+
let label = annotation.label.unwrap_or_default();
3130
DisplayLine::Raw(DisplayRawLine::Annotation {
3231
annotation: Annotation {
3332
annotation_type: DisplayAnnotationType::from(annotation.annotation_type),
34-
id: annotation.id.clone(),
33+
id: annotation.id,
3534
label: format_label(Some(&label), Some(DisplayTextStyle::Emphasis)),
3635
},
3736
source_aligned: false,
3837
continuation: false,
3938
})
4039
}
4140

42-
fn format_annotation(annotation: &snippet::Annotation) -> Vec<DisplayLine> {
41+
fn format_annotation(annotation: snippet::Annotation) -> Vec<DisplayLine> {
4342
let mut result = vec![];
44-
let label = annotation.label.clone().unwrap_or_default();
43+
let label = annotation.label.unwrap_or_default();
4544
for (i, line) in label.lines().enumerate() {
4645
result.push(DisplayLine::Raw(DisplayRawLine::Annotation {
4746
annotation: Annotation {
@@ -56,11 +55,14 @@ fn format_annotation(annotation: &snippet::Annotation) -> Vec<DisplayLine> {
5655
result
5756
}
5857

59-
fn format_slice(slice: &snippet::Slice, is_first: bool, has_footer: bool) -> Vec<DisplayLine> {
58+
fn format_slice(mut slice: snippet::Slice, is_first: bool, has_footer: bool) -> Vec<DisplayLine> {
59+
let main_range = slice.annotations.get(0).map(|x| x.range.0);
60+
let row = slice.line_start;
61+
let origin = slice.origin.take();
6062
let mut body = format_body(slice, has_footer);
63+
let header = format_header(origin, main_range, row, &body, is_first);
6164
let mut result = vec![];
6265

63-
let header = format_header(slice, &body, is_first);
6466
if let Some(header) = header {
6567
result.push(header);
6668
}
@@ -69,46 +71,45 @@ fn format_slice(slice: &snippet::Slice, is_first: bool, has_footer: bool) -> Vec
6971
}
7072

7173
fn format_header(
72-
slice: &snippet::Slice,
74+
origin: Option<String>,
75+
main_range: Option<usize>,
76+
mut row: usize,
7377
body: &[DisplayLine],
7478
is_first: bool,
7579
) -> Option<DisplayLine> {
76-
let main_annotation = slice.annotations.get(0);
77-
7880
let display_header = if is_first {
7981
DisplayHeaderType::Initial
8082
} else {
8183
DisplayHeaderType::Continuation
8284
};
8385

84-
if let Some(annotation) = main_annotation {
86+
if let Some(main_range) = main_range {
8587
let mut col = 1;
86-
let mut row = slice.line_start;
8788

88-
for item in body.iter() {
89+
for item in body {
8990
if let DisplayLine::Source {
9091
line: DisplaySourceLine::Content { range, .. },
9192
..
9293
} = item
9394
{
94-
if annotation.range.0 >= range.0 && annotation.range.0 <= range.1 {
95-
col = annotation.range.0 - range.0 + 1;
95+
if main_range >= range.0 && main_range <= range.1 {
96+
col = main_range - range.0 + 1;
9697
break;
9798
}
9899
row += 1;
99100
}
100101
}
101-
if let Some(ref path) = slice.origin {
102+
if let Some(path) = origin {
102103
return Some(DisplayLine::Raw(DisplayRawLine::Origin {
103-
path: path.to_string(),
104+
path,
104105
pos: Some((row, col)),
105106
header_type: display_header,
106107
}));
107108
}
108109
}
109-
if let Some(ref path) = slice.origin {
110+
if let Some(path) = origin {
110111
return Some(DisplayLine::Raw(DisplayRawLine::Origin {
111-
path: path.to_string(),
112+
path,
112113
pos: None,
113114
header_type: display_header,
114115
}));
@@ -175,15 +176,30 @@ fn fold_body(body: &[DisplayLine]) -> Vec<DisplayLine> {
175176
new_body
176177
}
177178

178-
fn format_body(slice: &snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
179-
let mut body = vec![];
179+
fn format_body(slice: snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
180+
let source_len = slice.source.chars().count();
181+
if let Some(bigger) = slice.annotations.iter().find_map(|x| {
182+
if source_len < x.range.1 {
183+
Some(x.range)
184+
} else {
185+
None
186+
}
187+
}) {
188+
panic!(
189+
"SourceAnnotation range `{:?}` is bigger than source length `{}`",
190+
bigger, source_len
191+
)
192+
}
180193

194+
let mut body = vec![];
181195
let mut current_line = slice.line_start;
182196
let mut current_index = 0;
183197
let mut line_index_ranges = vec![];
184198

185-
for line in slice.source.lines() {
186-
let line_length = line.chars().count() + 1;
199+
let lines = slice.source.lines();
200+
let lines_len = lines.clone().count();
201+
for (i, line) in lines.enumerate() {
202+
let line_length = line.chars().count();
187203
let line_range = (current_index, current_index + line_length);
188204
body.push(DisplayLine::Source {
189205
lineno: Some(current_line),
@@ -195,13 +211,14 @@ fn format_body(slice: &snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
195211
});
196212
line_index_ranges.push(line_range);
197213
current_line += 1;
198-
current_index += line_length + 1;
214+
if i + 1 < lines_len {
215+
current_index += line_length + 1;
216+
}
199217
}
200218

201219
let mut annotation_line_count = 0;
202-
let mut annotations = slice.annotations.clone();
203-
for idx in 0..body.len() {
204-
let (line_start, line_end) = line_index_ranges[idx];
220+
let mut annotations = slice.annotations;
221+
for (idx, (line_start, line_end)) in line_index_ranges.into_iter().enumerate() {
205222
// It would be nice to use filter_drain here once it's stable.
206223
annotations = annotations
207224
.into_iter()
@@ -214,7 +231,10 @@ fn format_body(slice: &snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
214231
};
215232
match annotation.range {
216233
(start, _) if start > line_end => true,
217-
(start, end) if start >= line_start && end <= line_end => {
234+
(start, end)
235+
if start >= line_start && end <= line_end
236+
|| start == line_end && end - start <= 1 =>
237+
{
218238
let range = (start - line_start, end - line_start);
219239
body.insert(
220240
body_idx + 1,
@@ -305,6 +325,7 @@ fn format_body(slice: &snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
305325
),
306326
});
307327
}
328+
308329
let range = (end - line_start, end - line_start + 1);
309330
body.insert(
310331
body_idx + 1,
@@ -368,22 +389,24 @@ fn format_body(slice: &snippet::Slice, has_footer: bool) -> Vec<DisplayLine> {
368389
}
369390

370391
impl From<snippet::Snippet> for DisplayList {
371-
fn from(snippet: snippet::Snippet) -> Self {
392+
fn from(
393+
snippet::Snippet {
394+
title,
395+
footer,
396+
slices,
397+
}: snippet::Snippet,
398+
) -> Self {
372399
let mut body = vec![];
373-
if let Some(annotation) = snippet.title {
374-
body.push(format_title(&annotation));
400+
if let Some(annotation) = title {
401+
body.push(format_title(annotation));
375402
}
376403

377-
for (idx, slice) in snippet.slices.iter().enumerate() {
378-
body.append(&mut format_slice(
379-
&slice,
380-
idx == 0,
381-
!snippet.footer.is_empty(),
382-
));
404+
for (idx, slice) in slices.into_iter().enumerate() {
405+
body.append(&mut format_slice(slice, idx == 0, !footer.is_empty()));
383406
}
384407

385-
for annotation in snippet.footer {
386-
body.append(&mut format_annotation(&annotation));
408+
for annotation in footer {
409+
body.append(&mut format_annotation(annotation));
387410
}
388411

389412
Self { body }

src/stylesheets/color.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,7 @@ impl Style for AnsiTermStyleWrapper {
1313
}
1414

1515
fn bold(&self) -> Box<dyn Style> {
16-
Box::new(AnsiTermStyleWrapper {
17-
style: self.style.clone(),
18-
})
16+
Box::new(AnsiTermStyleWrapper { style: self.style })
1917
}
2018
}
2119

tests/diff/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,5 @@ pub fn get_diff(left: &str, right: &str) -> String {
3939
}
4040
}
4141
}
42-
return output;
42+
output
4343
}

0 commit comments

Comments
 (0)