Use Diagnostic struct in buffer's diagnostics multimap

This commit is contained in:
Max Brunsfeld 2021-11-01 12:59:01 -07:00
parent 1aee7bdb1d
commit 78d97a3db2
3 changed files with 64 additions and 51 deletions

View file

@ -62,7 +62,7 @@ pub struct Buffer {
syntax_tree: Mutex<Option<SyntaxTree>>, syntax_tree: Mutex<Option<SyntaxTree>>,
parsing_in_background: bool, parsing_in_background: bool,
parse_count: usize, parse_count: usize,
diagnostics: AnchorRangeMultimap<(DiagnosticSeverity, String)>, diagnostics: AnchorRangeMultimap<Diagnostic>,
diagnostics_update_count: usize, diagnostics_update_count: usize,
language_server: Option<LanguageServerState>, language_server: Option<LanguageServerState>,
#[cfg(test)] #[cfg(test)]
@ -72,15 +72,14 @@ pub struct Buffer {
pub struct Snapshot { pub struct Snapshot {
text: buffer::Snapshot, text: buffer::Snapshot,
tree: Option<Tree>, tree: Option<Tree>,
diagnostics: AnchorRangeMultimap<(DiagnosticSeverity, String)>, diagnostics: AnchorRangeMultimap<Diagnostic>,
is_parsing: bool, is_parsing: bool,
language: Option<Arc<Language>>, language: Option<Arc<Language>>,
query_cursor: QueryCursorHandle, query_cursor: QueryCursorHandle,
} }
#[derive(Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Diagnostic { pub struct Diagnostic {
pub range: Range<Point>,
pub severity: DiagnosticSeverity, pub severity: DiagnosticSeverity,
pub message: String, pub message: String,
} }
@ -687,8 +686,6 @@ impl Buffer {
); );
let mut end = let mut end =
PointUtf16::new(diagnostic.range.end.line, diagnostic.range.end.character); PointUtf16::new(diagnostic.range.end.line, diagnostic.range.end.character);
let severity = diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR);
if diagnostic if diagnostic
.source .source
.as_ref() .as_ref()
@ -716,7 +713,13 @@ impl Buffer {
range.end.column += 1; range.end.column += 1;
range.end = content.clip_point_utf16(range.end, Bias::Right); range.end = content.clip_point_utf16(range.end, Bias::Right);
} }
Some((range, (severity, diagnostic.message))) Some((
range,
Diagnostic {
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
message: diagnostic.message,
},
))
}), }),
) )
}; };
@ -741,15 +744,11 @@ impl Buffer {
pub fn diagnostics_in_range<'a, T: 'a + ToOffset>( pub fn diagnostics_in_range<'a, T: 'a + ToOffset>(
&'a self, &'a self,
range: Range<T>, range: Range<T>,
) -> impl Iterator<Item = Diagnostic> + 'a { ) -> impl Iterator<Item = (Range<Point>, &Diagnostic)> + 'a {
let content = self.content(); let content = self.content();
self.diagnostics self.diagnostics
.intersecting_ranges(range, content, true) .intersecting_ranges(range, content, true)
.map(move |(_, range, (severity, message))| Diagnostic { .map(move |(_, range, diagnostic)| (range, diagnostic))
range,
severity: *severity,
message: message.clone(),
})
} }
pub fn diagnostics_update_count(&self) -> usize { pub fn diagnostics_update_count(&self) -> usize {
@ -1544,19 +1543,19 @@ impl Snapshot {
let range = range.start.to_offset(&*self)..range.end.to_offset(&*self); let range = range.start.to_offset(&*self)..range.end.to_offset(&*self);
let mut diagnostic_endpoints = Vec::<DiagnosticEndpoint>::new(); let mut diagnostic_endpoints = Vec::<DiagnosticEndpoint>::new();
for (_, range, (severity, _)) in for (_, range, diagnostic) in
self.diagnostics self.diagnostics
.intersecting_ranges(range.clone(), self.content(), true) .intersecting_ranges(range.clone(), self.content(), true)
{ {
diagnostic_endpoints.push(DiagnosticEndpoint { diagnostic_endpoints.push(DiagnosticEndpoint {
offset: range.start, offset: range.start,
is_start: true, is_start: true,
severity: *severity, severity: diagnostic.severity,
}); });
diagnostic_endpoints.push(DiagnosticEndpoint { diagnostic_endpoints.push(DiagnosticEndpoint {
offset: range.end, offset: range.end,
is_start: false, is_start: false,
severity: *severity, severity: diagnostic.severity,
}); });
} }
diagnostic_endpoints.sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start)); diagnostic_endpoints.sort_unstable_by_key(|endpoint| (endpoint.offset, !endpoint.is_start));

View file

@ -468,16 +468,20 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
.diagnostics_in_range(Point::new(3, 0)..Point::new(5, 0)) .diagnostics_in_range(Point::new(3, 0)..Point::new(5, 0))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&[ &[
Diagnostic { (
range: Point::new(3, 9)..Point::new(3, 11), Point::new(3, 9)..Point::new(3, 11),
severity: DiagnosticSeverity::ERROR, &Diagnostic {
message: "undefined variable 'BB'".to_string() severity: DiagnosticSeverity::ERROR,
}, message: "undefined variable 'BB'".to_string()
Diagnostic { },
range: Point::new(4, 9)..Point::new(4, 12), ),
severity: DiagnosticSeverity::ERROR, (
message: "undefined variable 'CCC'".to_string() Point::new(4, 9)..Point::new(4, 12),
} &Diagnostic {
severity: DiagnosticSeverity::ERROR,
message: "undefined variable 'CCC'".to_string()
}
)
] ]
); );
assert_eq!( assert_eq!(
@ -527,16 +531,20 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
.diagnostics_in_range(Point::new(2, 0)..Point::new(3, 0)) .diagnostics_in_range(Point::new(2, 0)..Point::new(3, 0))
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&[ &[
Diagnostic { (
range: Point::new(2, 9)..Point::new(2, 12), Point::new(2, 9)..Point::new(2, 12),
severity: DiagnosticSeverity::WARNING, &Diagnostic {
message: "unreachable statement".to_string() severity: DiagnosticSeverity::WARNING,
}, message: "unreachable statement".to_string()
Diagnostic { }
range: Point::new(2, 9)..Point::new(2, 10), ),
severity: DiagnosticSeverity::ERROR, (
message: "undefined variable 'A'".to_string() Point::new(2, 9)..Point::new(2, 10),
}, &Diagnostic {
severity: DiagnosticSeverity::ERROR,
message: "undefined variable 'A'".to_string()
},
)
] ]
); );
assert_eq!( assert_eq!(
@ -598,16 +606,20 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
.diagnostics_in_range(0..buffer.len()) .diagnostics_in_range(0..buffer.len())
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
&[ &[
Diagnostic { (
range: Point::new(2, 21)..Point::new(2, 22), Point::new(2, 21)..Point::new(2, 22),
severity: DiagnosticSeverity::ERROR, &Diagnostic {
message: "undefined variable 'A'".to_string() severity: DiagnosticSeverity::ERROR,
}, message: "undefined variable 'A'".to_string()
Diagnostic { }
range: Point::new(3, 9)..Point::new(3, 11), ),
severity: DiagnosticSeverity::ERROR, (
message: "undefined variable 'BB'".to_string() Point::new(3, 9)..Point::new(3, 11),
}, &Diagnostic {
severity: DiagnosticSeverity::ERROR,
message: "undefined variable 'BB'".to_string()
},
)
] ]
); );
}); });

View file

@ -3551,11 +3551,13 @@ mod tests {
.collect::<Vec<_>>(); .collect::<Vec<_>>();
assert_eq!( assert_eq!(
diagnostics, diagnostics,
&[Diagnostic { &[(
range: Point::new(0, 9)..Point::new(0, 10), Point::new(0, 9)..Point::new(0, 10),
severity: lsp::DiagnosticSeverity::ERROR, &Diagnostic {
message: "undefined variable 'A'".to_string() severity: lsp::DiagnosticSeverity::ERROR,
}] message: "undefined variable 'A'".to_string()
}
)]
) )
}); });
} }