mirror of
https://github.com/zed-industries/zed.git
synced 2025-02-05 10:20:51 +00:00
wip
This commit is contained in:
parent
d5a17053df
commit
4f774e2bde
4 changed files with 105 additions and 104 deletions
|
@ -637,7 +637,7 @@ mod tests {
|
||||||
|
|
||||||
worktree.update(&mut cx, |worktree, cx| {
|
worktree.update(&mut cx, |worktree, cx| {
|
||||||
worktree
|
worktree
|
||||||
.update_diagnostic_entries(
|
.update_point_utf16_diagnostics(
|
||||||
"lsp".into(),
|
"lsp".into(),
|
||||||
Arc::from("/test/main.rs".as_ref()),
|
Arc::from("/test/main.rs".as_ref()),
|
||||||
None,
|
None,
|
||||||
|
@ -764,7 +764,7 @@ mod tests {
|
||||||
|
|
||||||
worktree.update(&mut cx, |worktree, cx| {
|
worktree.update(&mut cx, |worktree, cx| {
|
||||||
worktree
|
worktree
|
||||||
.update_diagnostic_entries(
|
.update_point_utf16_diagnostics(
|
||||||
"lsp".into(),
|
"lsp".into(),
|
||||||
Arc::from("/test/a.rs".as_ref()),
|
Arc::from("/test/a.rs".as_ref()),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -66,12 +66,12 @@ pub struct BracketPair {
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait DiagnosticSource: 'static + Send + Sync {
|
pub trait DiagnosticSource: 'static + Send + Sync {
|
||||||
fn name(&self) -> &'static str;
|
fn name(&self) -> Arc<str>;
|
||||||
|
|
||||||
async fn diagnose(
|
async fn diagnose(
|
||||||
&self,
|
&self,
|
||||||
path: Arc<Path>,
|
path: Arc<Path>,
|
||||||
) -> Result<Vec<(PathBuf, Vec<DiagnosticEntry<Point>>)>>;
|
) -> Result<Vec<(PathBuf, Vec<DiagnosticEntry<usize>>)>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Language {
|
pub struct Language {
|
||||||
|
|
|
@ -511,17 +511,22 @@ impl Project {
|
||||||
let worktree_path = worktree.abs_path().clone();
|
let worktree_path = worktree.abs_path().clone();
|
||||||
let worktree_handle = worktree_handle.downgrade();
|
let worktree_handle = worktree_handle.downgrade();
|
||||||
cx.spawn_weak(|_, mut cx| async move {
|
cx.spawn_weak(|_, mut cx| async move {
|
||||||
if let Some(diagnostics) =
|
let diagnostics =
|
||||||
diagnostic_source.diagnose(worktree_path).await.log_err()
|
diagnostic_source.diagnose(worktree_path).await.log_err()?;
|
||||||
{
|
let worktree_handle = worktree_handle.upgrade(&cx)?;
|
||||||
if let Some(worktree_handle) = worktree_handle.upgrade(&cx) {
|
worktree_handle.update(&mut cx, |worktree, cx| {
|
||||||
worktree_handle.update(&mut cx, |worktree, cx| {
|
for (path, diagnostics) in diagnostics {
|
||||||
for (path, diagnostics) in diagnostics {
|
worktree
|
||||||
todo!()
|
.update_offset_diagnostics(
|
||||||
}
|
diagnostic_source.name(),
|
||||||
})
|
path.into(),
|
||||||
|
diagnostics,
|
||||||
|
cx,
|
||||||
|
)
|
||||||
|
.log_err()?;
|
||||||
}
|
}
|
||||||
}
|
Some(())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
.detach();
|
.detach();
|
||||||
}
|
}
|
||||||
|
|
|
@ -743,7 +743,7 @@ impl Worktree {
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
self.update_diagnostic_entries(
|
self.update_point_utf16_diagnostics(
|
||||||
provider_name,
|
provider_name,
|
||||||
worktree_path,
|
worktree_path,
|
||||||
params.version,
|
params.version,
|
||||||
|
@ -752,87 +752,54 @@ impl Worktree {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_diagnostics(
|
pub fn update_offset_diagnostics(
|
||||||
&mut self,
|
&mut self,
|
||||||
provider_name: Arc<str>,
|
provider_name: Arc<str>,
|
||||||
mut params: lsp::PublishDiagnosticsParams,
|
path: Arc<Path>,
|
||||||
disk_based_sources: &HashSet<String>,
|
diagnostics: Vec<DiagnosticEntry<usize>>,
|
||||||
cx: &mut ModelContext<Worktree>,
|
cx: &mut ModelContext<Worktree>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let this = self.as_local_mut().ok_or_else(|| anyhow!("not local"))?;
|
let this = self.as_local_mut().unwrap();
|
||||||
let abs_path = params
|
for buffer in this.open_buffers.values() {
|
||||||
.uri
|
if let Some(buffer) = buffer.upgrade(cx) {
|
||||||
.to_file_path()
|
if buffer
|
||||||
.map_err(|_| anyhow!("URI is not a file"))?;
|
.read(cx)
|
||||||
let worktree_path = Arc::from(
|
.file()
|
||||||
abs_path
|
.map_or(false, |file| *file.path() == path)
|
||||||
.strip_prefix(&this.abs_path)
|
{
|
||||||
.context("path is not within worktree")?,
|
let (remote_id, operation) = buffer.update(cx, |buffer, cx| {
|
||||||
);
|
(
|
||||||
|
buffer.remote_id(),
|
||||||
let mut group_ids_by_diagnostic_range = HashMap::default();
|
buffer.update_diagnostics(
|
||||||
let mut diagnostics_by_group_id = HashMap::default();
|
provider_name,
|
||||||
let mut next_group_id = 0;
|
None,
|
||||||
for diagnostic in &mut params.diagnostics {
|
diagnostics
|
||||||
let source = diagnostic.source.as_ref();
|
.iter()
|
||||||
let code = diagnostic.code.as_ref();
|
.map(|entry| DiagnosticEntry {
|
||||||
let group_id = diagnostic_ranges(&diagnostic, &abs_path)
|
range: buffer.offset_to_point_utf16(entry.range.start)
|
||||||
.find_map(|range| group_ids_by_diagnostic_range.get(&(source, code, range)))
|
..buffer.offset_to_point_utf16(entry.range.end),
|
||||||
.copied()
|
diagnostic: entry.diagnostic.clone(),
|
||||||
.unwrap_or_else(|| {
|
})
|
||||||
let group_id = post_inc(&mut next_group_id);
|
.collect(),
|
||||||
for range in diagnostic_ranges(&diagnostic, &abs_path) {
|
cx,
|
||||||
group_ids_by_diagnostic_range.insert((source, code, range), group_id);
|
),
|
||||||
}
|
)
|
||||||
group_id
|
});
|
||||||
});
|
self.send_buffer_update(remote_id, operation?, cx);
|
||||||
|
break;
|
||||||
diagnostics_by_group_id
|
}
|
||||||
.entry(group_id)
|
}
|
||||||
.or_insert(Vec::new())
|
|
||||||
.push(DiagnosticEntry {
|
|
||||||
range: diagnostic.range.start.to_point_utf16()
|
|
||||||
..diagnostic.range.end.to_point_utf16(),
|
|
||||||
diagnostic: Diagnostic {
|
|
||||||
code: diagnostic.code.clone().map(|code| match code {
|
|
||||||
lsp::NumberOrString::Number(code) => code.to_string(),
|
|
||||||
lsp::NumberOrString::String(code) => code,
|
|
||||||
}),
|
|
||||||
severity: diagnostic.severity.unwrap_or(DiagnosticSeverity::ERROR),
|
|
||||||
message: mem::take(&mut diagnostic.message),
|
|
||||||
group_id,
|
|
||||||
is_primary: false,
|
|
||||||
is_valid: true,
|
|
||||||
is_disk_based: diagnostic
|
|
||||||
.source
|
|
||||||
.as_ref()
|
|
||||||
.map_or(false, |source| disk_based_sources.contains(source)),
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let diagnostics = diagnostics_by_group_id
|
let this = self.as_local_mut().unwrap();
|
||||||
.into_values()
|
this.diagnostic_summaries
|
||||||
.flat_map(|mut diagnostics| {
|
.insert(path.clone(), DiagnosticSummary::new(&diagnostics));
|
||||||
let primary = diagnostics
|
this.offset_diagnostics.insert(path.clone(), diagnostics);
|
||||||
.iter_mut()
|
cx.emit(Event::DiagnosticsUpdated(path.clone()));
|
||||||
.min_by_key(|entry| entry.diagnostic.severity)
|
Ok(())
|
||||||
.unwrap();
|
|
||||||
primary.diagnostic.is_primary = true;
|
|
||||||
diagnostics
|
|
||||||
})
|
|
||||||
.collect::<Vec<_>>();
|
|
||||||
|
|
||||||
self.update_diagnostic_entries(
|
|
||||||
provider_name,
|
|
||||||
worktree_path,
|
|
||||||
params.version,
|
|
||||||
diagnostics,
|
|
||||||
cx,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_diagnostic_entries(
|
pub fn update_point_utf16_diagnostics(
|
||||||
&mut self,
|
&mut self,
|
||||||
provider_name: Arc<str>,
|
provider_name: Arc<str>,
|
||||||
path: Arc<Path>,
|
path: Arc<Path>,
|
||||||
|
@ -868,11 +835,26 @@ impl Worktree {
|
||||||
let this = self.as_local_mut().unwrap();
|
let this = self.as_local_mut().unwrap();
|
||||||
this.diagnostic_summaries
|
this.diagnostic_summaries
|
||||||
.insert(path.clone(), DiagnosticSummary::new(&diagnostics));
|
.insert(path.clone(), DiagnosticSummary::new(&diagnostics));
|
||||||
this.diagnostics.insert(path.clone(), diagnostics);
|
this.point_utf16_diagnostics
|
||||||
|
.insert(path.clone(), diagnostics);
|
||||||
cx.emit(Event::DiagnosticsUpdated(path.clone()));
|
cx.emit(Event::DiagnosticsUpdated(path.clone()));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn convert_diagnostics(
|
||||||
|
diagnostics: &[DiagnosticEntry<usize>],
|
||||||
|
buffer: &Buffer,
|
||||||
|
) -> Vec<DiagnosticEntry<PointUtf16>> {
|
||||||
|
diagnostics
|
||||||
|
.iter()
|
||||||
|
.map(|entry| DiagnosticEntry {
|
||||||
|
range: buffer.offset_to_point_utf16(entry.range.start)
|
||||||
|
..buffer.offset_to_point_utf16(entry.range.end),
|
||||||
|
diagnostic: entry.diagnostic.clone(),
|
||||||
|
})
|
||||||
|
.collect()
|
||||||
|
}
|
||||||
|
|
||||||
fn send_buffer_update(
|
fn send_buffer_update(
|
||||||
&mut self,
|
&mut self,
|
||||||
buffer_id: u64,
|
buffer_id: u64,
|
||||||
|
@ -943,7 +925,8 @@ pub struct LocalWorktree {
|
||||||
loading_buffers: LoadingBuffers,
|
loading_buffers: LoadingBuffers,
|
||||||
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
open_buffers: HashMap<usize, WeakModelHandle<Buffer>>,
|
||||||
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
shared_buffers: HashMap<PeerId, HashMap<u64, ModelHandle<Buffer>>>,
|
||||||
diagnostics: HashMap<Arc<Path>, Vec<DiagnosticEntry<PointUtf16>>>,
|
point_utf16_diagnostics: HashMap<Arc<Path>, Vec<DiagnosticEntry<PointUtf16>>>,
|
||||||
|
offset_diagnostics: HashMap<Arc<Path>, Vec<DiagnosticEntry<usize>>>,
|
||||||
diagnostic_summaries: BTreeMap<Arc<Path>, DiagnosticSummary>,
|
diagnostic_summaries: BTreeMap<Arc<Path>, DiagnosticSummary>,
|
||||||
queued_operations: Vec<(u64, Operation)>,
|
queued_operations: Vec<(u64, Operation)>,
|
||||||
language_registry: Arc<LanguageRegistry>,
|
language_registry: Arc<LanguageRegistry>,
|
||||||
|
@ -1051,7 +1034,8 @@ impl LocalWorktree {
|
||||||
loading_buffers: Default::default(),
|
loading_buffers: Default::default(),
|
||||||
open_buffers: Default::default(),
|
open_buffers: Default::default(),
|
||||||
shared_buffers: Default::default(),
|
shared_buffers: Default::default(),
|
||||||
diagnostics: Default::default(),
|
point_utf16_diagnostics: Default::default(),
|
||||||
|
offset_diagnostics: Default::default(),
|
||||||
diagnostic_summaries: Default::default(),
|
diagnostic_summaries: Default::default(),
|
||||||
queued_operations: Default::default(),
|
queued_operations: Default::default(),
|
||||||
language_registry: languages,
|
language_registry: languages,
|
||||||
|
@ -1200,27 +1184,39 @@ impl LocalWorktree {
|
||||||
.update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx))
|
.update(&mut cx, |t, cx| t.as_local().unwrap().load(&path, cx))
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let (diagnostics, language, language_server) = this.update(&mut cx, |this, cx| {
|
let (point_utf16_diagnostics, offset_diagnostics, language, language_server) = this
|
||||||
let this = this.as_local_mut().unwrap();
|
.update(&mut cx, |this, cx| {
|
||||||
let diagnostics = this.diagnostics.remove(&path);
|
let this = this.as_local_mut().unwrap();
|
||||||
let language = this
|
let point_utf16_diagnostics = this.point_utf16_diagnostics.remove(&path);
|
||||||
.language_registry
|
let offset_diagnostics = this.offset_diagnostics.remove(&path);
|
||||||
.select_language(file.full_path())
|
let language = this
|
||||||
.cloned();
|
.language_registry
|
||||||
let server = language
|
.select_language(file.full_path())
|
||||||
.as_ref()
|
.cloned();
|
||||||
.and_then(|language| this.register_language(language, cx));
|
let server = language
|
||||||
(diagnostics, language, server)
|
.as_ref()
|
||||||
});
|
.and_then(|language| this.register_language(language, cx));
|
||||||
|
(
|
||||||
|
point_utf16_diagnostics,
|
||||||
|
offset_diagnostics,
|
||||||
|
language,
|
||||||
|
server,
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
let buffer = cx.add_model(|cx| {
|
let buffer = cx.add_model(|cx| {
|
||||||
let mut buffer = Buffer::from_file(0, contents, Box::new(file), cx);
|
let mut buffer = Buffer::from_file(0, contents, Box::new(file), cx);
|
||||||
buffer.set_language(language, language_server, cx);
|
buffer.set_language(language, language_server, cx);
|
||||||
if let Some(diagnostics) = diagnostics {
|
if let Some(diagnostics) = point_utf16_diagnostics {
|
||||||
buffer
|
buffer
|
||||||
.update_diagnostics(todo!(), None, diagnostics, cx)
|
.update_diagnostics(todo!(), None, diagnostics, cx)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
if let Some(diagnostics) = offset_diagnostics {
|
||||||
|
buffer
|
||||||
|
.update_offset_diagnostics(todo!(), None, diagnostics, cx)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
buffer
|
buffer
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue