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:
parent
9d5f6f67d6
commit
830d10b171
1 changed files with 74 additions and 45 deletions
|
@ -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": {
|
||||||
|
|
Loading…
Reference in a new issue