mirror of
https://gitee.com/openharmony/third_party_rust_codespan
synced 2024-11-23 15:30:26 +00:00
move handling of label start to renderer
this eliminates a failure condition from RichDiagnostic::render because the full source code does not have to be loaded here any more
This commit is contained in:
parent
593ed5372b
commit
56b3f2f7e2
@ -25,17 +25,18 @@ pub type SingleLabel<'diagnostic> = (LabelStyle, Range<usize>, &'diagnostic str)
|
||||
///
|
||||
/// Locations are relative to the start of where the source code is rendered.
|
||||
pub enum MultiLabel<'diagnostic> {
|
||||
/// Left top corner for multi-line labels.
|
||||
///
|
||||
/// ```text
|
||||
/// ╭
|
||||
/// ```
|
||||
TopLeft,
|
||||
/// Multi-line label top.
|
||||
///
|
||||
/// ```text
|
||||
/// ╭────────────^
|
||||
/// ```
|
||||
///
|
||||
/// Can also be rendered at the beginning of the line
|
||||
/// if there is only whitespace before the label starts.
|
||||
///
|
||||
/// /// ```text
|
||||
/// ╭
|
||||
/// ```
|
||||
Top(RangeTo<usize>),
|
||||
/// Left vertical labels for multi-line labels.
|
||||
///
|
||||
@ -263,7 +264,9 @@ impl<'writer, 'config> Renderer<'writer, 'config> {
|
||||
match multi_labels_iter.peek() {
|
||||
Some((label_index, label_style, label)) if *label_index == label_column => {
|
||||
match label {
|
||||
MultiLabel::TopLeft => {
|
||||
MultiLabel::Top(range)
|
||||
if range.end <= source.len() - source.trim_start().len() =>
|
||||
{
|
||||
self.label_multi_top_left(severity, *label_style)?;
|
||||
}
|
||||
MultiLabel::Top(..) => self.inner_gutter_space()?,
|
||||
@ -290,7 +293,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> {
|
||||
*ls == LabelStyle::Primary
|
||||
&& match label {
|
||||
MultiLabel::Top(range) => column_range.start >= range.end,
|
||||
MultiLabel::TopLeft | MultiLabel::Left => true,
|
||||
MultiLabel::Left => true,
|
||||
MultiLabel::Bottom(range, _) => column_range.end <= range.end,
|
||||
}
|
||||
});
|
||||
@ -537,7 +540,13 @@ impl<'writer, 'config> Renderer<'writer, 'config> {
|
||||
// ```
|
||||
for (multi_label_index, (_, label_style, label)) in multi_labels.iter().enumerate() {
|
||||
let (label_style, range, bottom_message) = match label {
|
||||
MultiLabel::TopLeft | MultiLabel::Left => continue, // no label caret needed
|
||||
MultiLabel::Left => continue, // no label caret needed
|
||||
// no label caret needed if this can be started in front of the line
|
||||
MultiLabel::Top(range_to)
|
||||
if range_to.end <= source.len() - source.trim_start().len() =>
|
||||
{
|
||||
continue
|
||||
}
|
||||
MultiLabel::Top(range) => (*label_style, range, None),
|
||||
MultiLabel::Bottom(range, message) => (*label_style, range, Some(message)),
|
||||
};
|
||||
@ -556,7 +565,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> {
|
||||
match multi_labels_iter.peek() {
|
||||
Some((i, (label_index, ls, label))) if *label_index == label_column => {
|
||||
match label {
|
||||
MultiLabel::TopLeft | MultiLabel::Left => {
|
||||
MultiLabel::Left => {
|
||||
self.label_multi_left(severity, *ls, underline.map(|(s, _)| s))?;
|
||||
}
|
||||
MultiLabel::Top(..) if multi_label_index > *i => {
|
||||
@ -944,7 +953,7 @@ impl<'writer, 'config> Renderer<'writer, 'config> {
|
||||
for label_column in 0..num_multi_labels {
|
||||
match multi_labels_iter.peek() {
|
||||
Some((label_index, ls, label)) if *label_index == label_column => match label {
|
||||
MultiLabel::TopLeft | MultiLabel::Left | MultiLabel::Bottom(..) => {
|
||||
MultiLabel::Left | MultiLabel::Bottom(..) => {
|
||||
self.label_multi_left(severity, *ls, None)?;
|
||||
multi_labels_iter.next();
|
||||
}
|
||||
|
@ -83,11 +83,6 @@ where
|
||||
|
||||
// Group labels by file
|
||||
for label in &self.diagnostic.labels {
|
||||
let source = files
|
||||
.source(label.file_id)
|
||||
.ok_or(RenderError::FileMissing)?;
|
||||
let source = source.as_ref();
|
||||
|
||||
let start_line_index = files
|
||||
.line_index(label.file_id, label.range.start)
|
||||
.ok_or(RenderError::InvalidIndex)?;
|
||||
@ -213,7 +208,6 @@ where
|
||||
|
||||
// First labeled line
|
||||
let label_start = label.range.start - start_line_range.start;
|
||||
let prefix_source = &source[start_line_range.start..label.range.start];
|
||||
|
||||
let start_line = labeled_file.get_or_insert_line(
|
||||
start_line_index,
|
||||
@ -221,26 +215,11 @@ where
|
||||
start_line_number,
|
||||
);
|
||||
|
||||
start_line
|
||||
.multi_labels
|
||||
// TODO: Do this in the `Renderer`?
|
||||
.push(match prefix_source.trim() {
|
||||
// Section is prefixed by empty space, so we don't need to take
|
||||
// up a new line.
|
||||
//
|
||||
// ```text
|
||||
// 4 │ ╭ case (mod num 5) (mod num 3) of
|
||||
// ```
|
||||
"" => (label_index, label.style, MultiLabel::TopLeft),
|
||||
// There's source code in the prefix, so run a label
|
||||
// underneath it to get to the start of the range.
|
||||
//
|
||||
// ```text
|
||||
// 4 │ fizz₁ num = case (mod num 5) (mod num 3) of
|
||||
// │ ╭─────────────^
|
||||
// ```
|
||||
_ => (label_index, label.style, MultiLabel::Top(..label_start)),
|
||||
});
|
||||
start_line.multi_labels.push((
|
||||
label_index,
|
||||
label.style,
|
||||
MultiLabel::Top(..label_start),
|
||||
));
|
||||
|
||||
// The first line has to be rendered so the start of the label is visible.
|
||||
start_line.must_render = true;
|
||||
|
Loading…
Reference in New Issue
Block a user