mirror of
https://github.com/zed-industries/zed.git
synced 2024-09-19 18:41:56 +03:00
Assign diagnostics a group_id
based on their related_information
Co-Authored-By: Nathan Sobo <nathan@zed.dev>
This commit is contained in:
parent
2d6285a6e1
commit
78bbb83448
@ -85,6 +85,7 @@ pub struct Snapshot {
|
|||||||
pub struct Diagnostic {
|
pub struct Diagnostic {
|
||||||
pub severity: DiagnosticSeverity,
|
pub severity: DiagnosticSeverity,
|
||||||
pub message: String,
|
pub message: String,
|
||||||
|
pub group_id: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LanguageServerState {
|
struct LanguageServerState {
|
||||||
@ -699,6 +700,7 @@ impl Buffer {
|
|||||||
} else {
|
} else {
|
||||||
self.content()
|
self.content()
|
||||||
};
|
};
|
||||||
|
let abs_path = self.file.as_ref().and_then(|f| f.abs_path());
|
||||||
|
|
||||||
let empty_set = HashSet::new();
|
let empty_set = HashSet::new();
|
||||||
let disk_based_sources = self
|
let disk_based_sources = self
|
||||||
@ -714,17 +716,28 @@ impl Buffer {
|
|||||||
.peekable();
|
.peekable();
|
||||||
let mut last_edit_old_end = PointUtf16::zero();
|
let mut last_edit_old_end = PointUtf16::zero();
|
||||||
let mut last_edit_new_end = PointUtf16::zero();
|
let mut last_edit_new_end = PointUtf16::zero();
|
||||||
|
let mut groups = HashMap::new();
|
||||||
|
let mut next_group_id = 0;
|
||||||
|
|
||||||
content.anchor_range_multimap(
|
content.anchor_range_multimap(
|
||||||
Bias::Left,
|
Bias::Left,
|
||||||
Bias::Right,
|
Bias::Right,
|
||||||
diagnostics.into_iter().filter_map(|diagnostic| {
|
diagnostics.iter().filter_map(|diagnostic| {
|
||||||
let mut start = PointUtf16::new(
|
let mut start = diagnostic.range.start.to_point_utf16();
|
||||||
diagnostic.range.start.line,
|
let mut end = diagnostic.range.end.to_point_utf16();
|
||||||
diagnostic.range.start.character,
|
let source = diagnostic.source.as_ref();
|
||||||
);
|
let code = diagnostic.code.as_ref();
|
||||||
let mut end =
|
let group_id = diagnostic_ranges(&diagnostic, abs_path.as_deref())
|
||||||
PointUtf16::new(diagnostic.range.end.line, diagnostic.range.end.character);
|
.find_map(|range| groups.get(&(source, code, range)))
|
||||||
|
.copied()
|
||||||
|
.unwrap_or_else(|| {
|
||||||
|
let group_id = post_inc(&mut next_group_id);
|
||||||
|
for range in diagnostic_ranges(&diagnostic, abs_path.as_deref()) {
|
||||||
|
groups.insert((source, code, range), group_id);
|
||||||
|
}
|
||||||
|
group_id
|
||||||
|
});
|
||||||
|
|
||||||
if diagnostic
|
if diagnostic
|
||||||
.source
|
.source
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@ -760,7 +773,8 @@ impl Buffer {
|
|||||||
range,
|
range,
|
||||||
Diagnostic {
|
Diagnostic {
|
||||||
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
||||||
message: diagnostic.message,
|
message: diagnostic.message.clone(),
|
||||||
|
group_id,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
@ -1888,6 +1902,44 @@ impl ToTreeSitterPoint for Point {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
trait ToPointUtf16 {
|
||||||
|
fn to_point_utf16(self) -> PointUtf16;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToPointUtf16 for lsp::Position {
|
||||||
|
fn to_point_utf16(self) -> PointUtf16 {
|
||||||
|
PointUtf16::new(self.line, self.character)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn diagnostic_ranges<'a>(
|
||||||
|
diagnostic: &'a lsp::Diagnostic,
|
||||||
|
abs_path: Option<&'a Path>,
|
||||||
|
) -> impl 'a + Iterator<Item = Range<PointUtf16>> {
|
||||||
|
diagnostic
|
||||||
|
.related_information
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.filter_map(move |info| {
|
||||||
|
if info.location.uri.to_file_path().ok()? == abs_path? {
|
||||||
|
let info_start = PointUtf16::new(
|
||||||
|
info.location.range.start.line,
|
||||||
|
info.location.range.start.character,
|
||||||
|
);
|
||||||
|
let info_end = PointUtf16::new(
|
||||||
|
info.location.range.end.line,
|
||||||
|
info.location.range.end.character,
|
||||||
|
);
|
||||||
|
Some(info_start..info_end)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.chain(Some(
|
||||||
|
diagnostic.range.start.to_point_utf16()..diagnostic.range.end.to_point_utf16(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
fn contiguous_ranges(
|
fn contiguous_ranges(
|
||||||
values: impl IntoIterator<Item = u32>,
|
values: impl IntoIterator<Item = u32>,
|
||||||
max_len: usize,
|
max_len: usize,
|
||||||
|
@ -141,6 +141,7 @@ pub fn serialize_diagnostics(map: &AnchorRangeMultimap<Diagnostic>) -> proto::Di
|
|||||||
DiagnosticSeverity::HINT => proto::diagnostic::Severity::Hint,
|
DiagnosticSeverity::HINT => proto::diagnostic::Severity::Hint,
|
||||||
_ => proto::diagnostic::Severity::None,
|
_ => proto::diagnostic::Severity::None,
|
||||||
} as i32,
|
} as i32,
|
||||||
|
group_id: diagnostic.group_id as u64,
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
}
|
}
|
||||||
@ -308,6 +309,7 @@ pub fn deserialize_diagnostics(message: proto::DiagnosticSet) -> AnchorRangeMult
|
|||||||
proto::diagnostic::Severity::None => return None,
|
proto::diagnostic::Severity::None => return None,
|
||||||
},
|
},
|
||||||
message: diagnostic.message,
|
message: diagnostic.message,
|
||||||
|
group_id: diagnostic.group_id as usize,
|
||||||
},
|
},
|
||||||
))
|
))
|
||||||
}),
|
}),
|
||||||
|
@ -482,14 +482,16 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||||||
Point::new(3, 9)..Point::new(3, 11),
|
Point::new(3, 9)..Point::new(3, 11),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::ERROR,
|
severity: DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'BB'".to_string()
|
message: "undefined variable 'BB'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Point::new(4, 9)..Point::new(4, 12),
|
Point::new(4, 9)..Point::new(4, 12),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::ERROR,
|
severity: DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'CCC'".to_string()
|
message: "undefined variable 'CCC'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -545,14 +547,16 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||||||
Point::new(2, 9)..Point::new(2, 12),
|
Point::new(2, 9)..Point::new(2, 12),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::WARNING,
|
severity: DiagnosticSeverity::WARNING,
|
||||||
message: "unreachable statement".to_string()
|
message: "unreachable statement".to_string(),
|
||||||
|
group_id: 0,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Point::new(2, 9)..Point::new(2, 10),
|
Point::new(2, 9)..Point::new(2, 10),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::ERROR,
|
severity: DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'A'".to_string()
|
message: "undefined variable 'A'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -620,14 +624,16 @@ async fn test_diagnostics(mut cx: gpui::TestAppContext) {
|
|||||||
Point::new(2, 21)..Point::new(2, 22),
|
Point::new(2, 21)..Point::new(2, 22),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::ERROR,
|
severity: DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'A'".to_string()
|
message: "undefined variable 'A'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
Point::new(3, 9)..Point::new(3, 11),
|
Point::new(3, 9)..Point::new(3, 11),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: DiagnosticSeverity::ERROR,
|
severity: DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'BB'".to_string()
|
message: "undefined variable 'BB'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
]
|
]
|
||||||
@ -706,31 +712,30 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||||||
"
|
"
|
||||||
.unindent();
|
.unindent();
|
||||||
|
|
||||||
let mut buffer = Buffer::new(0, text, cx);
|
let file = FakeFile::new("/example.rs");
|
||||||
|
let mut buffer = Buffer::from_file(0, text, Box::new(file.clone()), cx);
|
||||||
buffer.set_language(Some(Arc::new(rust_lang())), None, cx);
|
buffer.set_language(Some(Arc::new(rust_lang())), None, cx);
|
||||||
let diagnostics = vec![
|
let diagnostics = vec![
|
||||||
lsp::Diagnostic {
|
lsp::Diagnostic {
|
||||||
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
severity: Some(DiagnosticSeverity::WARNING),
|
severity: Some(DiagnosticSeverity::WARNING),
|
||||||
message: "unused variable: `x`\n`#[warn(unused_variables)]` on by default"
|
message: "error 1".to_string(),
|
||||||
.to_string(),
|
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
},
|
},
|
||||||
message: "if this is intentional, prefix it with an underscore: `_x`"
|
message: "error 1 hint 1".to_string(),
|
||||||
.to_string(),
|
|
||||||
}]),
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
lsp::Diagnostic {
|
lsp::Diagnostic {
|
||||||
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
severity: Some(DiagnosticSeverity::HINT),
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
message: "if this is intentional, prefix it with an underscore: `_x`".to_string(),
|
message: "error 1 hint 1".to_string(),
|
||||||
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
location: lsp::Location {
|
location: lsp::Location {
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
range: lsp::Range::new(lsp::Position::new(1, 8), lsp::Position::new(1, 9)),
|
||||||
},
|
},
|
||||||
message: "original diagnostic".to_string(),
|
message: "original diagnostic".to_string(),
|
||||||
@ -738,67 +743,108 @@ async fn test_grouped_diagnostics(mut cx: gpui::TestAppContext) {
|
|||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
lsp::Diagnostic {
|
lsp::Diagnostic {
|
||||||
range: lsp::Range::new( lsp::Position::new(2, 8), lsp::Position::new(2, 17)),
|
range: lsp::Range::new(lsp::Position::new(2, 8), lsp::Position::new(2, 17)),
|
||||||
severity: Some(DiagnosticSeverity::ERROR),
|
severity: Some(DiagnosticSeverity::ERROR),
|
||||||
message: "cannot borrow `v` as mutable because it is also borrowed as immutable\nmutable borrow occurs here".to_string(),
|
message: "error 2".to_string(),
|
||||||
related_information: Some(
|
related_information: Some(vec![
|
||||||
vec![
|
lsp::DiagnosticRelatedInformation {
|
||||||
lsp::DiagnosticRelatedInformation {
|
location: lsp::Location {
|
||||||
location: lsp::Location {
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
range: lsp::Range::new(
|
||||||
range: lsp::Range::new(lsp::Position::new( 1, 13, ), lsp::Position::new(1, 15)),
|
lsp::Position::new(1, 13),
|
||||||
},
|
lsp::Position::new(1, 15),
|
||||||
message: "immutable borrow occurs here".to_string(),
|
),
|
||||||
},
|
},
|
||||||
lsp::DiagnosticRelatedInformation {
|
message: "error 2 hint 1".to_string(),
|
||||||
location: lsp::Location {
|
},
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
lsp::DiagnosticRelatedInformation {
|
||||||
range: lsp::Range::new(lsp::Position::new( 1, 13, ), lsp::Position::new(1, 15)),
|
location: lsp::Location {
|
||||||
},
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
message: "immutable borrow later used here".to_string(),
|
range: lsp::Range::new(
|
||||||
|
lsp::Position::new(1, 13),
|
||||||
|
lsp::Position::new(1, 15),
|
||||||
|
),
|
||||||
},
|
},
|
||||||
],
|
message: "error 2 hint 2".to_string(),
|
||||||
),
|
},
|
||||||
|
]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
lsp::Diagnostic {
|
lsp::Diagnostic {
|
||||||
range: lsp::Range::new( lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
range: lsp::Range::new(lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
||||||
severity: Some( DiagnosticSeverity::HINT),
|
|
||||||
message: "immutable borrow occurs here".to_string(),
|
|
||||||
related_information: Some(
|
|
||||||
vec![
|
|
||||||
lsp::DiagnosticRelatedInformation {
|
|
||||||
location: lsp::Location {
|
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
|
||||||
range: lsp::Range::new(lsp::Position::new( 2, 8, ), lsp::Position::new(2, 17)),
|
|
||||||
},
|
|
||||||
message: "original diagnostic".to_string(),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
),
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
lsp::Diagnostic {
|
|
||||||
range: lsp::Range::new( lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
|
||||||
severity: Some(DiagnosticSeverity::HINT),
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
message: "immutable borrow later used here".to_string(),
|
message: "error 2 hint 1".to_string(),
|
||||||
related_information: Some(
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
vec![
|
location: lsp::Location {
|
||||||
lsp::DiagnosticRelatedInformation {
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
location: lsp::Location {
|
range: lsp::Range::new(lsp::Position::new(2, 8), lsp::Position::new(2, 17)),
|
||||||
uri: lsp::Url::from_file_path("/example.rs").unwrap(),
|
},
|
||||||
range: lsp::Range::new(lsp::Position::new( 2, 8, ), lsp::Position::new(2, 17)),
|
message: "original diagnostic".to_string(),
|
||||||
},
|
}]),
|
||||||
message: "original diagnostic".to_string(),
|
..Default::default()
|
||||||
},
|
},
|
||||||
],
|
lsp::Diagnostic {
|
||||||
),
|
range: lsp::Range::new(lsp::Position::new(1, 13), lsp::Position::new(1, 15)),
|
||||||
|
severity: Some(DiagnosticSeverity::HINT),
|
||||||
|
message: "error 2 hint 2".to_string(),
|
||||||
|
related_information: Some(vec![lsp::DiagnosticRelatedInformation {
|
||||||
|
location: lsp::Location {
|
||||||
|
uri: lsp::Url::from_file_path(&file.abs_path).unwrap(),
|
||||||
|
range: lsp::Range::new(lsp::Position::new(2, 8), lsp::Position::new(2, 17)),
|
||||||
|
},
|
||||||
|
message: "original diagnostic".to_string(),
|
||||||
|
}]),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
buffer.update_diagnostics(None, diagnostics, cx).unwrap();
|
buffer.update_diagnostics(None, diagnostics, cx).unwrap();
|
||||||
|
assert_eq!(
|
||||||
// TODO: Group these diagnostics somehow.
|
buffer
|
||||||
|
.diagnostics_in_range::<_, Point>(0..buffer.len())
|
||||||
|
.collect::<Vec<_>>(),
|
||||||
|
&[
|
||||||
|
(
|
||||||
|
Point::new(1, 8)..Point::new(1, 9),
|
||||||
|
&Diagnostic {
|
||||||
|
severity: DiagnosticSeverity::WARNING,
|
||||||
|
message: "error 1".to_string(),
|
||||||
|
group_id: 0
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Point::new(1, 8)..Point::new(1, 9),
|
||||||
|
&Diagnostic {
|
||||||
|
severity: DiagnosticSeverity::HINT,
|
||||||
|
message: "error 1 hint 1".to_string(),
|
||||||
|
group_id: 0
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Point::new(1, 13)..Point::new(1, 15),
|
||||||
|
&Diagnostic {
|
||||||
|
severity: DiagnosticSeverity::HINT,
|
||||||
|
message: "error 2 hint 1".to_string(),
|
||||||
|
group_id: 1
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Point::new(1, 13)..Point::new(1, 15),
|
||||||
|
&Diagnostic {
|
||||||
|
severity: DiagnosticSeverity::HINT,
|
||||||
|
message: "error 2 hint 2".to_string(),
|
||||||
|
group_id: 1
|
||||||
|
}
|
||||||
|
),
|
||||||
|
(
|
||||||
|
Point::new(2, 8)..Point::new(2, 17),
|
||||||
|
&Diagnostic {
|
||||||
|
severity: DiagnosticSeverity::ERROR,
|
||||||
|
message: "error 2".to_string(),
|
||||||
|
group_id: 1
|
||||||
|
}
|
||||||
|
)
|
||||||
|
]
|
||||||
|
);
|
||||||
|
|
||||||
buffer
|
buffer
|
||||||
});
|
});
|
||||||
@ -875,3 +921,80 @@ fn rust_lang() -> Language {
|
|||||||
fn empty(point: Point) -> Range<Point> {
|
fn empty(point: Point) -> Range<Point> {
|
||||||
point..point
|
point..point
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
struct FakeFile {
|
||||||
|
abs_path: PathBuf,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FakeFile {
|
||||||
|
fn new(abs_path: impl Into<PathBuf>) -> Self {
|
||||||
|
Self {
|
||||||
|
abs_path: abs_path.into(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl File for FakeFile {
|
||||||
|
fn worktree_id(&self) -> usize {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn entry_id(&self) -> Option<usize> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mtime(&self) -> SystemTime {
|
||||||
|
SystemTime::now()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn path(&self) -> &Arc<Path> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn abs_path(&self) -> Option<PathBuf> {
|
||||||
|
Some(self.abs_path.clone())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn full_path(&self) -> PathBuf {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn file_name(&self) -> Option<OsString> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_deleted(&self) -> bool {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn save(
|
||||||
|
&self,
|
||||||
|
_: u64,
|
||||||
|
_: Rope,
|
||||||
|
_: clock::Global,
|
||||||
|
_: &mut MutableAppContext,
|
||||||
|
) -> Task<Result<(clock::Global, SystemTime)>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn load_local(&self, _: &AppContext) -> Option<Task<Result<String>>> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buffer_updated(&self, _: u64, _: super::Operation, _: &mut MutableAppContext) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn buffer_removed(&self, _: u64, _: &mut MutableAppContext) {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn boxed_clone(&self) -> Box<dyn File> {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn as_any(&self) -> &dyn Any {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -3633,7 +3633,8 @@ mod tests {
|
|||||||
Point::new(0, 9)..Point::new(0, 10),
|
Point::new(0, 9)..Point::new(0, 10),
|
||||||
&Diagnostic {
|
&Diagnostic {
|
||||||
severity: lsp::DiagnosticSeverity::ERROR,
|
severity: lsp::DiagnosticSeverity::ERROR,
|
||||||
message: "undefined variable 'A'".to_string()
|
message: "undefined variable 'A'".to_string(),
|
||||||
|
group_id: 0,
|
||||||
}
|
}
|
||||||
)]
|
)]
|
||||||
)
|
)
|
||||||
|
@ -256,6 +256,7 @@ message Diagnostic {
|
|||||||
uint64 end = 2;
|
uint64 end = 2;
|
||||||
Severity severity = 3;
|
Severity severity = 3;
|
||||||
string message = 4;
|
string message = 4;
|
||||||
|
uint64 group_id = 5;
|
||||||
enum Severity {
|
enum Severity {
|
||||||
None = 0;
|
None = 0;
|
||||||
Error = 1;
|
Error = 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user