diff options
author | Kitson Kelly <me@kitsonkelly.com> | 2021-04-20 07:10:43 +1000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-04-20 07:10:43 +1000 |
commit | 65f7a021f092f2c475969a6f6762ab5e35d65123 (patch) | |
tree | 008dec74a2d1ac88a59db15e0e8a78ed02ae6011 | |
parent | d6233100bd6a5c5b2a1c541f580cc47053f6f90d (diff) |
feat(lsp): improve diagnostic status page (#10253)
-rw-r--r-- | cli/lsp/documents.rs | 4 | ||||
-rw-r--r-- | cli/lsp/language_server.rs | 51 | ||||
-rw-r--r-- | cli/lsp/performance.rs | 31 | ||||
-rw-r--r-- | cli/lsp/sources.rs | 13 |
4 files changed, 83 insertions, 16 deletions
diff --git a/cli/lsp/documents.rs b/cli/lsp/documents.rs index 47a23eb49..ef37396a2 100644 --- a/cli/lsp/documents.rs +++ b/cli/lsp/documents.rs @@ -202,6 +202,10 @@ impl DocumentCache { } } + pub fn specifiers(&self) -> Vec<ModuleSpecifier> { + self.docs.keys().cloned().collect() + } + pub fn version(&self, specifier: &ModuleSpecifier) -> Option<i32> { self.docs.get(specifier).and_then(|doc| doc.version) } diff --git a/cli/lsp/language_server.rs b/cli/lsp/language_server.rs index d5de93593..275a0873d 100644 --- a/cli/lsp/language_server.rs +++ b/cli/lsp/language_server.rs @@ -2302,18 +2302,59 @@ impl Inner { let specifier = self.url_map.normalize_url(¶ms.text_document.uri); let contents = if specifier.as_str() == "deno:/status.md" { let mut contents = String::new(); + let mut documents_specifiers = self.documents.specifiers(); + documents_specifiers.sort(); + let mut sources_specifiers = self.sources.specifiers(); + sources_specifiers.sort(); + let measures = self.performance.to_vec(); contents.push_str(&format!( r#"# Deno Language Server Status - - Documents in memory: {} + - <details><summary>Documents in memory: {}</summary> + + - {} + + </details> + + - <details><summary>Sources in memory: {}</summary> + + - {} + + </details> + + - <details><summary>Performance measures: {}</summary> + + - {} + + </details> "#, - self.documents.len() + self.documents.len(), + documents_specifiers + .into_iter() + .map(|s| s.to_string()) + .collect::<Vec<String>>() + .join("\n - "), + self.sources.len(), + sources_specifiers + .into_iter() + .map(|s| s.to_string()) + .collect::<Vec<String>>() + .join("\n - "), + measures.len(), + measures + .iter() + .map(|m| m.to_string()) + .collect::<Vec<String>>() + .join("\n - ") )); - contents.push_str("\n## Performance\n\n"); - for average in self.performance.averages() { + contents + .push_str("\n## Performance\n\n|Name|Duration|Count|\n|---|---|---|\n"); + let mut averages = self.performance.averages(); + averages.sort(); + for average in averages { contents.push_str(&format!( - " - {}: {}ms ({})\n", + "|{}|{}ms|{}|\n", average.name, average.average_duration, average.count )); } diff --git a/cli/lsp/performance.rs b/cli/lsp/performance.rs index 537583141..9a2ac24ab 100644 --- a/cli/lsp/performance.rs +++ b/cli/lsp/performance.rs @@ -2,14 +2,16 @@ use deno_core::serde::Deserialize; use deno_core::serde::Serialize; +use std::cmp; use std::collections::HashMap; use std::collections::VecDeque; +use std::fmt; use std::sync::Arc; use std::sync::Mutex; use std::time::Duration; use std::time::Instant; -#[derive(Debug, Deserialize, Serialize)] +#[derive(Debug, Deserialize, Serialize, PartialEq, Eq)] #[serde(rename_all = "camelCase")] pub struct PerformanceAverage { pub name: String, @@ -17,6 +19,18 @@ pub struct PerformanceAverage { pub average_duration: u32, } +impl PartialOrd for PerformanceAverage { + fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for PerformanceAverage { + fn cmp(&self, other: &Self) -> cmp::Ordering { + self.name.cmp(&other.name) + } +} + /// A structure which serves as a start of a measurement span. #[derive(Debug)] pub struct PerformanceMark { @@ -33,6 +47,12 @@ pub struct PerformanceMeasure { pub duration: Duration, } +impl fmt::Display for PerformanceMeasure { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{} ({}ms)", self.name, self.duration.as_millis()) + } +} + impl From<PerformanceMark> for PerformanceMeasure { fn from(value: PerformanceMark) -> Self { Self { @@ -131,12 +151,17 @@ impl Performance { let measure = PerformanceMeasure::from(mark); let duration = measure.duration; let mut measures = self.measures.lock().unwrap(); - measures.push_back(measure); + measures.push_front(measure); while measures.len() > self.max_size { - measures.pop_front(); + measures.pop_back(); } duration } + + pub fn to_vec(&self) -> Vec<PerformanceMeasure> { + let measures = self.measures.lock().unwrap(); + measures.iter().cloned().collect() + } } #[cfg(test)] diff --git a/cli/lsp/sources.rs b/cli/lsp/sources.rs index d8134d5a2..072e49470 100644 --- a/cli/lsp/sources.rs +++ b/cli/lsp/sources.rs @@ -197,6 +197,10 @@ impl Sources { self.0.lock().unwrap().get_source(specifier) } + pub fn len(&self) -> usize { + self.0.lock().unwrap().metadata.len() + } + pub fn resolve_import( &self, specifier: &str, @@ -206,14 +210,7 @@ impl Sources { } pub fn specifiers(&self) -> Vec<ModuleSpecifier> { - self - .0 - .lock() - .unwrap() - .metadata - .iter() - .map(|(s, _)| s.clone()) - .collect() + self.0.lock().unwrap().metadata.keys().cloned().collect() } } |