1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use crate::common::Span;
/// The kind of a slide diagnostic.
pub enum DiagnosticKind {
/// An error diagnostic. Generally, this diagnostic should be emitted for unrecoverable errors.
/// In other cases, a warning or a note may be more applicable.
Error,
/// A note diagnostic is a generic annotation with no specific connotation like `error`. It can
/// be particularly useful as an associated diagnostic, for example in expanding on a primary
/// error.
Note,
/// A help diagnostic should instruct the user how their code can be changed to work correctly
/// with slide.
Help,
}
/// A secondary diagnostic associated with a primary `Diagnostic`.
pub struct AssociatedDiagnostic {
pub kind: DiagnosticKind,
pub span: Span,
pub msg: String,
}
/// A diagnostic for slide source code.
pub struct Diagnostic {
pub kind: DiagnosticKind,
pub span: Span,
pub title: String,
pub msg: Option<String>,
pub associated_diagnostics: Vec<AssociatedDiagnostic>,
pub unspanned_associated_diagnostics: Vec<AssociatedDiagnostic>,
}
impl Diagnostic {
/// Creates an error diagnostic at a span.
pub(crate) fn span_err<S, M, N>(span: S, title: M, err: N) -> Diagnostic
where
S: Into<Span>,
M: Into<String>,
N: Into<Option<String>>,
{
Diagnostic {
kind: DiagnosticKind::Error,
span: span.into(),
title: title.into(),
msg: err.into(),
associated_diagnostics: Vec::with_capacity(2),
unspanned_associated_diagnostics: Vec::with_capacity(2),
}
}
/// Adds a note to the diagnostic.
pub(crate) fn with_note<M>(mut self, note: M) -> Diagnostic
where
M: Into<String>,
{
self.unspanned_associated_diagnostics
.push(AssociatedDiagnostic {
kind: DiagnosticKind::Note,
span: self.span,
msg: note.into(),
});
self
}
/// Adds a help message to the diagnostic.
pub(crate) fn with_help<M>(mut self, note: M) -> Diagnostic
where
M: Into<String>,
{
self.unspanned_associated_diagnostics
.push(AssociatedDiagnostic {
kind: DiagnosticKind::Help,
span: self.span,
msg: note.into(),
});
self
}
/// Adds a help message to the diagnostic, possibly at a different span.
pub(crate) fn with_help_note<S, M>(mut self, span: S, note: M) -> Diagnostic
where
S: Into<Span>,
M: Into<String>,
{
self.associated_diagnostics.push(AssociatedDiagnostic {
kind: DiagnosticKind::Help,
span: span.into(),
msg: note.into(),
});
self
}
}