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.rs201
1 files changed, 98 insertions, 103 deletions
diff --git a/cli/lsp/diagnostics.rs b/cli/lsp/diagnostics.rs
index a7f027c1b..1d0a1fac9 100644
--- a/cli/lsp/diagnostics.rs
+++ b/cli/lsp/diagnostics.rs
@@ -2,8 +2,8 @@
use super::analysis::get_lint_references;
use super::analysis::references_to_diagnostics;
+use super::language_server::StateSnapshot;
use super::memory_cache::FileId;
-use super::state::ServerStateSnapshot;
use super::tsc;
use crate::diagnostics;
@@ -12,52 +12,11 @@ use crate::media_type::MediaType;
use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_core::serde_json::Value;
-use deno_core::url::Url;
-use deno_core::JsRuntime;
+use lspower::lsp_types;
use std::collections::HashMap;
use std::collections::HashSet;
use std::mem;
-impl<'a> From<&'a diagnostics::DiagnosticCategory>
- for lsp_types::DiagnosticSeverity
-{
- fn from(category: &'a diagnostics::DiagnosticCategory) -> Self {
- match category {
- diagnostics::DiagnosticCategory::Error => {
- lsp_types::DiagnosticSeverity::Error
- }
- diagnostics::DiagnosticCategory::Warning => {
- lsp_types::DiagnosticSeverity::Warning
- }
- diagnostics::DiagnosticCategory::Suggestion => {
- lsp_types::DiagnosticSeverity::Hint
- }
- diagnostics::DiagnosticCategory::Message => {
- lsp_types::DiagnosticSeverity::Information
- }
- }
- }
-}
-
-impl<'a> From<&'a diagnostics::Position> for lsp_types::Position {
- fn from(pos: &'a diagnostics::Position) -> Self {
- Self {
- line: pos.line as u32,
- character: pos.character as u32,
- }
- }
-}
-
-fn to_lsp_range(
- start: &diagnostics::Position,
- end: &diagnostics::Position,
-) -> lsp_types::Range {
- lsp_types::Range {
- start: start.into(),
- end: end.into(),
- }
-}
-
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub enum DiagnosticSource {
Lint,
@@ -108,41 +67,84 @@ impl DiagnosticCollection {
pub type DiagnosticVec = Vec<(FileId, Option<i32>, Vec<lsp_types::Diagnostic>)>;
-pub fn generate_linting_diagnostics(
- state: &ServerStateSnapshot,
+pub async fn generate_lint_diagnostics(
+ state_snapshot: StateSnapshot,
+ diagnostic_collection: DiagnosticCollection,
) -> DiagnosticVec {
- if !state.config.settings.lint {
- return Vec::new();
- }
- let mut diagnostics = Vec::new();
- let file_cache = state.file_cache.read().unwrap();
- for (specifier, doc_data) in state.doc_data.iter() {
- let file_id = file_cache.lookup(specifier).unwrap();
- let version = doc_data.version;
- let current_version = state.diagnostics.get_version(&file_id);
- if version != current_version {
- let media_type = MediaType::from(specifier);
- if let Ok(source_code) = file_cache.get_contents(file_id) {
- if let Ok(references) =
- get_lint_references(specifier, &media_type, &source_code)
- {
- if !references.is_empty() {
- diagnostics.push((
- file_id,
- version,
- references_to_diagnostics(references),
- ));
- } else {
- diagnostics.push((file_id, version, Vec::new()));
+ tokio::task::spawn_blocking(move || {
+ let mut diagnostic_list = Vec::new();
+
+ let file_cache = state_snapshot.file_cache.read().unwrap();
+ 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 media_type = MediaType::from(specifier);
+ if let Ok(source_code) = file_cache.get_contents(file_id) {
+ if let Ok(references) =
+ get_lint_references(specifier, &media_type, &source_code)
+ {
+ if !references.is_empty() {
+ diagnostic_list.push((
+ file_id,
+ version,
+ references_to_diagnostics(references),
+ ));
+ } else {
+ diagnostic_list.push((file_id, version, Vec::new()));
+ }
}
+ } else {
+ error!("Missing file contents for: {}", specifier);
}
- } else {
- error!("Missing file contents for: {}", specifier);
}
}
+
+ diagnostic_list
+ })
+ .await
+ .unwrap()
+}
+
+impl<'a> From<&'a diagnostics::DiagnosticCategory>
+ for lsp_types::DiagnosticSeverity
+{
+ fn from(category: &'a diagnostics::DiagnosticCategory) -> Self {
+ match category {
+ diagnostics::DiagnosticCategory::Error => {
+ lsp_types::DiagnosticSeverity::Error
+ }
+ diagnostics::DiagnosticCategory::Warning => {
+ lsp_types::DiagnosticSeverity::Warning
+ }
+ diagnostics::DiagnosticCategory::Suggestion => {
+ lsp_types::DiagnosticSeverity::Hint
+ }
+ diagnostics::DiagnosticCategory::Message => {
+ lsp_types::DiagnosticSeverity::Information
+ }
+ }
+ }
+}
+
+impl<'a> From<&'a diagnostics::Position> for lsp_types::Position {
+ fn from(pos: &'a diagnostics::Position) -> Self {
+ Self {
+ line: pos.line as u32,
+ character: pos.character as u32,
+ }
}
+}
- diagnostics
+fn to_lsp_range(
+ start: &diagnostics::Position,
+ end: &diagnostics::Position,
+) -> lsp_types::Range {
+ lsp_types::Range {
+ start: start.into(),
+ end: end.into(),
+ }
}
type TsDiagnostics = Vec<diagnostics::Diagnostic>;
@@ -168,7 +170,7 @@ fn to_lsp_related_information(
if let (Some(source), Some(start), Some(end)) =
(&ri.source, &ri.start, &ri.end)
{
- let uri = Url::parse(&source).unwrap();
+ let uri = lsp_types::Url::parse(&source).unwrap();
Some(lsp_types::DiagnosticRelatedInformation {
location: lsp_types::Location {
uri,
@@ -223,43 +225,36 @@ fn ts_json_to_diagnostics(
)
}
-pub fn generate_ts_diagnostics(
- state: &ServerStateSnapshot,
- runtime: &mut JsRuntime,
+pub async fn generate_ts_diagnostics(
+ ts_server: &tsc::TsServer,
+ diagnostic_collection: &DiagnosticCollection,
+ state_snapshot: StateSnapshot,
) -> Result<DiagnosticVec, AnyError> {
- if !state.config.settings.enable {
- return Ok(Vec::new());
- }
let mut diagnostics = Vec::new();
- let file_cache = state.file_cache.read().unwrap();
- for (specifier, doc_data) in state.doc_data.iter() {
- let file_id = file_cache.lookup(specifier).unwrap();
+ let state_snapshot_ = state_snapshot.clone();
+ for (specifier, doc_data) in state_snapshot_.doc_data.iter() {
+ let file_id = {
+ // TODO(lucacasonato): this is highly inefficient
+ let file_cache = state_snapshot_.file_cache.read().unwrap();
+ file_cache.lookup(specifier).unwrap()
+ };
let version = doc_data.version;
- let current_version = state.diagnostics.get_version(&file_id);
+ let current_version = diagnostic_collection.get_version(&file_id);
if version != current_version {
// TODO(@kitsonk): consider refactoring to get all diagnostics in one shot
// for a file.
- let request_semantic_diagnostics =
- tsc::RequestMethod::GetSemanticDiagnostics(specifier.clone());
- let mut ts_diagnostics = ts_json_to_diagnostics(tsc::request(
- runtime,
- state,
- request_semantic_diagnostics,
- )?)?;
- let request_suggestion_diagnostics =
- tsc::RequestMethod::GetSuggestionDiagnostics(specifier.clone());
- ts_diagnostics.append(&mut ts_json_to_diagnostics(tsc::request(
- runtime,
- state,
- request_suggestion_diagnostics,
- )?)?);
- let request_syntactic_diagnostics =
- tsc::RequestMethod::GetSyntacticDiagnostics(specifier.clone());
- ts_diagnostics.append(&mut ts_json_to_diagnostics(tsc::request(
- runtime,
- state,
- request_syntactic_diagnostics,
- )?)?);
+ let req = tsc::RequestMethod::GetSemanticDiagnostics(specifier.clone());
+ let mut ts_diagnostics = ts_json_to_diagnostics(
+ ts_server.request(state_snapshot.clone(), req).await?,
+ )?;
+ let req = tsc::RequestMethod::GetSuggestionDiagnostics(specifier.clone());
+ ts_diagnostics.append(&mut ts_json_to_diagnostics(
+ ts_server.request(state_snapshot.clone(), req).await?,
+ )?);
+ let req = tsc::RequestMethod::GetSyntacticDiagnostics(specifier.clone());
+ ts_diagnostics.append(&mut ts_json_to_diagnostics(
+ ts_server.request(state_snapshot.clone(), req).await?,
+ )?);
diagnostics.push((file_id, version, ts_diagnostics));
}
}