1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-01-03 04:48:52 -05:00

refactor(lsp): update diagnostics.rs to use structs instead of records (#19799)

Part of https://github.com/denoland/vscode_deno/issues/835
This commit is contained in:
David Sherret 2023-07-11 16:36:39 -04:00 committed by GitHub
parent 9d5f6f67d6
commit 830d10b171
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -54,11 +54,19 @@ pub struct DiagnosticServerUpdateMessage {
pub lint_options: LintOptions, pub lint_options: LintOptions,
} }
pub type DiagnosticRecord = struct DiagnosticRecord {
(ModuleSpecifier, Option<i32>, Vec<lsp::Diagnostic>); pub specifier: ModuleSpecifier,
pub type DiagnosticVec = Vec<DiagnosticRecord>; pub versioned: VersionedDiagnostics,
type DiagnosticMap = }
HashMap<ModuleSpecifier, (Option<i32>, Vec<lsp::Diagnostic>)>;
#[derive(Clone, Default, Debug)]
struct VersionedDiagnostics {
pub version: Option<i32>,
pub diagnostics: Vec<lsp::Diagnostic>,
}
type DiagnosticVec = Vec<DiagnosticRecord>;
type DiagnosticMap = HashMap<ModuleSpecifier, VersionedDiagnostics>;
type DiagnosticsByVersionMap = HashMap<Option<i32>, Vec<lsp::Diagnostic>>; type DiagnosticsByVersionMap = HashMap<Option<i32>, Vec<lsp::Diagnostic>>;
#[derive(Clone)] #[derive(Clone)]
@ -82,7 +90,7 @@ impl DiagnosticsPublisher {
token: &CancellationToken, token: &CancellationToken,
) { ) {
let mut all_diagnostics = self.all_diagnostics.lock().await; let mut all_diagnostics = self.all_diagnostics.lock().await;
for (specifier, version, diagnostics) in diagnostics { for record in diagnostics {
if token.is_cancelled() { if token.is_cancelled() {
return; return;
} }
@ -90,15 +98,20 @@ impl DiagnosticsPublisher {
// the versions of all the published diagnostics should be the same, but just // the versions of all the published diagnostics should be the same, but just
// in case they're not keep track of that // in case they're not keep track of that
let diagnostics_by_version = let diagnostics_by_version =
all_diagnostics.entry(specifier.clone()).or_default(); all_diagnostics.entry(record.specifier.clone()).or_default();
let version_diagnostics = let version_diagnostics = diagnostics_by_version
diagnostics_by_version.entry(version).or_default(); .entry(record.versioned.version)
version_diagnostics.extend(diagnostics); .or_default();
version_diagnostics.extend(record.versioned.diagnostics);
self self
.client .client
.when_outside_lsp_lock() .when_outside_lsp_lock()
.publish_diagnostics(specifier, version_diagnostics.clone(), version) .publish_diagnostics(
record.specifier,
version_diagnostics.clone(),
record.versioned.version,
)
.await; .await;
} }
} }
@ -119,12 +132,10 @@ impl TsDiagnosticsStore {
document_version: Option<i32>, document_version: Option<i32>,
) -> Vec<lsp::Diagnostic> { ) -> Vec<lsp::Diagnostic> {
let ts_diagnostics = self.0.lock(); let ts_diagnostics = self.0.lock();
if let Some((diagnostics_doc_version, diagnostics)) = if let Some(versioned) = ts_diagnostics.get(specifier) {
ts_diagnostics.get(specifier)
{
// only get the diagnostics if they're up to date // only get the diagnostics if they're up to date
if document_version == *diagnostics_doc_version { if document_version == versioned.version {
return diagnostics.clone(); return versioned.diagnostics.clone();
} }
} }
Vec::new() Vec::new()
@ -145,9 +156,7 @@ impl TsDiagnosticsStore {
let mut stored_ts_diagnostics = self.0.lock(); let mut stored_ts_diagnostics = self.0.lock();
*stored_ts_diagnostics = diagnostics *stored_ts_diagnostics = diagnostics
.iter() .iter()
.map(|(specifier, version, diagnostics)| { .map(|record| (record.specifier.clone(), record.versioned.clone()))
(specifier.clone(), (*version, diagnostics.clone()))
})
.collect(); .collect();
} }
} }
@ -585,16 +594,18 @@ async fn generate_lint_diagnostics(
} }
let version = document.maybe_lsp_version(); let version = document.maybe_lsp_version();
diagnostics_vec.push(( diagnostics_vec.push(DiagnosticRecord {
document.specifier().clone(), specifier: document.specifier().clone(),
versioned: VersionedDiagnostics {
version, version,
generate_document_lint_diagnostics( diagnostics: generate_document_lint_diagnostics(
config, config,
lint_options, lint_options,
lint_rules.clone(), lint_rules.clone(),
&document, &document,
), ),
)); },
});
} }
} }
diagnostics_vec diagnostics_vec
@ -668,7 +679,13 @@ async fn generate_ts_diagnostics(
} else { } else {
Vec::new() Vec::new()
}; };
diagnostics_vec.push((specifier, version, ts_diagnostics)); diagnostics_vec.push(DiagnosticRecord {
specifier,
versioned: VersionedDiagnostics {
version,
diagnostics: ts_diagnostics,
},
});
} }
// add an empty diagnostic publish for disabled specifiers in order // add an empty diagnostic publish for disabled specifiers in order
// to clear those diagnostics if they exist // to clear those diagnostics if they exist
@ -677,7 +694,13 @@ async fn generate_ts_diagnostics(
.documents .documents
.get(&specifier) .get(&specifier)
.and_then(|d| d.maybe_lsp_version()); .and_then(|d| d.maybe_lsp_version());
diagnostics_vec.push((specifier, version, Vec::new())); diagnostics_vec.push(DiagnosticRecord {
specifier,
versioned: VersionedDiagnostics {
version,
diagnostics: Vec::new(),
},
});
} }
Ok(diagnostics_vec) Ok(diagnostics_vec)
} }
@ -1156,11 +1179,13 @@ async fn generate_deno_diagnostics(
); );
} }
} }
diagnostics_vec.push(( diagnostics_vec.push(DiagnosticRecord {
specifier.clone(), specifier: specifier.clone(),
document.maybe_lsp_version(), versioned: VersionedDiagnostics {
version: document.maybe_lsp_version(),
diagnostics, diagnostics,
)); },
});
} }
diagnostics_vec diagnostics_vec
@ -1338,8 +1363,12 @@ let c: number = "a";
diagnostic_vec: DiagnosticVec, diagnostic_vec: DiagnosticVec,
) -> Vec<lsp::Diagnostic> { ) -> Vec<lsp::Diagnostic> {
assert_eq!(diagnostic_vec.len(), 1); assert_eq!(diagnostic_vec.len(), 1);
let (_, _, diagnostics) = diagnostic_vec.into_iter().next().unwrap(); diagnostic_vec
diagnostics .into_iter()
.next()
.unwrap()
.versioned
.diagnostics
} }
#[tokio::test] #[tokio::test]
@ -1389,13 +1418,13 @@ let c: number = "a";
let token = CancellationToken::new(); let token = CancellationToken::new();
let actual = generate_deno_diagnostics(&snapshot, &config, token).await; let actual = generate_deno_diagnostics(&snapshot, &config, token).await;
assert_eq!(actual.len(), 2); assert_eq!(actual.len(), 2);
for (specifier, _, diagnostics) in actual { for record in actual {
match specifier.as_str() { match record.specifier.as_str() {
"file:///std/testing/asserts.ts" => { "file:///std/testing/asserts.ts" => {
assert_eq!(json!(diagnostics), json!([])) assert_eq!(json!(record.versioned.diagnostics), json!([]))
} }
"file:///a/file.ts" => assert_eq!( "file:///a/file.ts" => assert_eq!(
json!(diagnostics), json!(record.versioned.diagnostics),
json!([ json!([
{ {
"range": { "range": {
@ -1419,7 +1448,7 @@ let c: number = "a";
} }
]) ])
), ),
_ => unreachable!("unexpected specifier {}", specifier), _ => unreachable!("unexpected specifier {}", record.specifier),
} }
} }
} }
@ -1515,9 +1544,9 @@ let c: number = "a";
let token = CancellationToken::new(); let token = CancellationToken::new();
let actual = generate_deno_diagnostics(&snapshot, &config, token).await; let actual = generate_deno_diagnostics(&snapshot, &config, token).await;
assert_eq!(actual.len(), 1); assert_eq!(actual.len(), 1);
let (_, _, diagnostics) = actual.first().unwrap(); let record = actual.first().unwrap();
assert_eq!( assert_eq!(
json!(diagnostics), json!(record.versioned.diagnostics),
json!([ json!([
{ {
"range": { "range": {