miden_diagnostics/
diagnostic.rs1use crate::*;
2
3pub struct InFlightDiagnostic<'h> {
5 handler: &'h DiagnosticsHandler,
6 file_id: Option<SourceId>,
7 diagnostic: Diagnostic,
8 severity: Severity,
9}
10impl<'h> InFlightDiagnostic<'h> {
11 pub(crate) fn new(handler: &'h DiagnosticsHandler, severity: Severity) -> Self {
12 Self {
13 handler,
14 file_id: None,
15 diagnostic: Diagnostic::new(severity),
16 severity,
17 }
18 }
19
20 pub fn severity(&self) -> Severity {
22 self.severity
23 }
24
25 pub fn verbose(&self) -> bool {
30 use crate::term::DisplayStyle;
31 matches!(self.handler.display.display_style, DisplayStyle::Rich)
32 }
33
34 pub fn set_source_file(mut self, filename: impl Into<FileName>) -> Self {
36 let filename = filename.into();
37 let file_id = self.handler.codemap.get_file_id(&filename);
38 self.file_id = file_id;
39 self
40 }
41
42 pub fn with_message(mut self, message: impl ToString) -> Self {
44 self.diagnostic.message = message.to_string();
45 self
46 }
47
48 pub fn with_primary_span(mut self, span: SourceSpan) -> Self {
50 self.diagnostic
51 .labels
52 .push(Label::primary(span.source_id(), span));
53 self
54 }
55
56 pub fn with_primary_label(mut self, span: SourceSpan, message: impl ToString) -> Self {
62 self.diagnostic
63 .labels
64 .push(Label::primary(span.source_id(), span).with_message(message.to_string()));
65 self
66 }
67
68 pub fn with_secondary_label(mut self, span: SourceSpan, message: impl ToString) -> Self {
74 self.diagnostic
75 .labels
76 .push(Label::secondary(span.source_id(), span).with_message(message.to_string()));
77 self
78 }
79
80 pub fn with_primary_label_line_and_col(
84 self,
85 line: u32,
86 column: u32,
87 message: Option<String>,
88 ) -> Self {
89 let file_id = self.file_id;
90 self.with_label_and_file_id(LabelStyle::Primary, file_id, line, column, message)
91 }
92
93 pub fn with_label(
96 self,
97 style: LabelStyle,
98 filename: Option<FileName>,
99 line: u32,
100 column: u32,
101 message: Option<String>,
102 ) -> Self {
103 if let Some(name) = filename {
104 let id = self.handler.lookup_file_id(name);
105 self.with_label_and_file_id(style, id, line, column, message)
106 } else {
107 self
108 }
109 }
110
111 fn with_label_and_file_id(
112 mut self,
113 style: LabelStyle,
114 file_id: Option<SourceId>,
115 line: u32,
116 _column: u32,
117 message: Option<String>,
118 ) -> Self {
119 if let Some(id) = file_id {
120 let source_file = self.handler.codemap.get(id).unwrap();
121 let line_index = (line - 1).into();
122 let span = source_file
123 .line_span(line_index)
124 .expect("invalid line index");
125 let label = if let Some(msg) = message {
126 Label::new(style, id, span).with_message(msg)
127 } else {
128 Label::new(style, id, span)
129 };
130 self.diagnostic.labels.push(label);
131 self
132 } else {
133 self
134 }
135 }
136
137 pub fn with_note(mut self, note: impl ToString) -> Self {
144 self.diagnostic.notes.push(note.to_string());
145 self
146 }
147
148 pub fn add_note(&mut self, note: impl ToString) {
151 self.diagnostic.notes.push(note.to_string());
152 }
153
154 pub fn take(self) -> Diagnostic {
156 self.diagnostic
157 }
158
159 pub fn emit(self) {
161 self.handler.emit(self.diagnostic);
162 }
163}