summaryrefslogtreecommitdiff
path: root/cli/lsp/diagnostics.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/lsp/diagnostics.rs')
-rw-r--r--cli/lsp/diagnostics.rs76
1 files changed, 76 insertions, 0 deletions
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index 1d0a1fac9..c468fb0fa 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -2,6 +2,7 @@
use super::analysis::get_lint_references;
use super::analysis::references_to_diagnostics;
+use super::analysis::ResolvedDependency;
use super::language_server::StateSnapshot;
use super::memory_cache::FileId;
use super::tsc;
@@ -9,6 +10,7 @@ use super::tsc;
use crate::diagnostics;
use crate::media_type::MediaType;
+use deno_core::error::custom_error;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::serde_json::Value;
@@ -19,6 +21,7 @@ use std::mem;
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum DiagnosticSource {
+ Deno,
Lint,
TypeScript,
}
@@ -261,3 +264,76 @@ pub async fn generate_ts_diagnostics(
Ok(diagnostics)
}
+
+pub async fn generate_dependency_diagnostics(
+ state_snapshot: StateSnapshot,
+ diagnostic_collection: DiagnosticCollection,
+) -> Result<DiagnosticVec, AnyError> {
+ tokio::task::spawn_blocking(move || {
+ let mut diagnostics = Vec::new();
+
+ let file_cache = state_snapshot.file_cache.read().unwrap();
+ let mut sources = if let Ok(sources) = state_snapshot.sources.write() {
+ sources
+ } else {
+ return Err(custom_error("Deadlock", "deadlock locking sources"));
+ };
+ for (specifier, doc_data) in state_snapshot.doc_data.iter() {
+ let file_id = file_cache.lookup(specifier).unwrap();
+ let version = doc_data.version;
+ let current_version = diagnostic_collection.get_version(&file_id);
+ if version != current_version {
+ let mut diagnostic_list = Vec::new();
+ if let Some(dependencies) = &doc_data.dependencies {
+ for (_, dependency) in dependencies.iter() {
+ if let (Some(code), Some(range)) = (
+ &dependency.maybe_code,
+ &dependency.maybe_code_specifier_range,
+ ) {
+ match code.clone() {
+ ResolvedDependency::Err(message) => {
+ diagnostic_list.push(lsp_types::Diagnostic {
+ range: *range,
+ severity: Some(lsp_types::DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("deno".to_string()),
+ message,
+ related_information: None,
+ tags: None,
+ data: None,
+ })
+ }
+ ResolvedDependency::Resolved(specifier) => {
+ if !(state_snapshot.doc_data.contains_key(&specifier) || sources.contains(&specifier)) {
+ let is_local = specifier.as_url().scheme() == "file";
+ diagnostic_list.push(lsp_types::Diagnostic {
+ range: *range,
+ severity: Some(lsp_types::DiagnosticSeverity::Error),
+ code: None,
+ code_description: None,
+ source: Some("deno".to_string()),
+ message: if is_local {
+ format!("Unable to load a local module: \"{}\".\n Please check the file path.", specifier)
+ } else {
+ format!("Unable to load the module: \"{}\".\n If the module exists, running `deno cache {}` should resolve this error.", specifier, specifier)
+ },
+ related_information: None,
+ tags: None,
+ data: None,
+ })
+ }
+ },
+ }
+ }
+ }
+ }
+ diagnostics.push((file_id, version, diagnostic_list))
+ }
+ }
+
+ Ok(diagnostics)
+ })
+ .await
+ .unwrap()
+}