From 214c4bcf87f3440c4e8adc89b44cd6a97227637b Mon Sep 17 00:00:00 2001 From: Jonatan Waern Date: Tue, 24 Jun 2025 11:09:37 +0200 Subject: [PATCH] Set 'source' field of diagnostics according to the analysis source Allows to differentiate errors from other extensions (and between analysis and linting) Signed-off-by: Jonatan Waern --- CHANGELOG.md | 1 + src/actions/mod.rs | 42 +++++++++++++++++++++++++++++++++++------- src/analysis/mod.rs | 26 +++++++------------------- 3 files changed, 43 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 090920f..e9c63f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ # Change Log ## 0.9.12 +- Diagnostics sent from the server will now indicate their source as 'dml' or 'dml-lint' ## 0.9.11 - Fixed deadlock when a configuration update happens diff --git a/src/actions/mod.rs b/src/actions/mod.rs index bfdf9d4..cd9180e 100644 --- a/src/actions/mod.rs +++ b/src/actions/mod.rs @@ -31,6 +31,7 @@ use crate::file_management::{PathResolver, CanonPath}; use crate::lint::{LintCfg, maybe_parse_lint_cfg}; use crate::lsp_data; use crate::lsp_data::*; +use crate::lsp_data::ls_util::{dls_to_range, dls_to_location}; use crate::server::{Output, ServerToHandle, error_message, Request, RequestId, SentRequest}; use crate::server::message::RawResponse; @@ -305,6 +306,31 @@ impl ContextDefinition { } } +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct SourcedDMLError { + pub error: DMLError, + pub source: &'static str, +} + +impl SourcedDMLError { + pub fn to_diagnostic(&self) -> Diagnostic { + Diagnostic::new( + dls_to_range(self.error.span.range), + self.error.severity, + None, + Some(self.source.to_string()), + self.error.description.clone(), + Some( + self.error.related.iter().map( + |(span, desc)|DiagnosticRelatedInformation { + location: dls_to_location(span), + message: desc.clone(), + }).collect()), + None + ) + } +} + pub type ActiveDeviceContexts = HashSet; impl InitActionContext { @@ -452,22 +478,24 @@ impl InitActionContext { .collect(); let direct_opens = self.direct_opens.lock().unwrap(); for file in files { - let mut sorted_errors: Vec = - isolated.get(file).into_iter().flatten() - .chain(device.get(file).into_iter().flatten()) + let mut sorted_errors: Vec = + isolated.get(file).into_iter().flatten().cloned() + .map(|e|e.with_source("dml")) + .chain(device.get(file).into_iter().flatten().cloned() + .map(|e|e.with_source("dml"))) .chain( lint.get(file).into_iter().flatten() .filter( |_|!config.lint_direct_only || direct_opens.contains( &file.clone().into()) - )) - .cloned() + ).cloned() + .map(|e|e.with_source("dml-lint"))) .collect(); debug!("Reporting errors for {:?}", file); // Sort by line sorted_errors.sort_unstable_by( - |e1, e2|if e1.span.range > e2.span.range { + |e1, e2|if e1.error.span.range > e2.error.span.range { Ordering::Greater } else { Ordering::Less @@ -477,7 +505,7 @@ impl InitActionContext { PublishDiagnosticsParams::new( url, sorted_errors.iter() - .map(DMLError::to_diagnostic).collect(), + .map(SourcedDMLError::to_diagnostic).collect(), None)), // The Url crate does not report interesting errors Err(_) => error!("Could not convert {:?} to Url", file), diff --git a/src/analysis/mod.rs b/src/analysis/mod.rs index a50611c..8380e90 100644 --- a/src/analysis/mod.rs +++ b/src/analysis/mod.rs @@ -21,11 +21,12 @@ use std::sync::Mutex; use itertools::Itertools; -use lsp_types::{Diagnostic, DiagnosticRelatedInformation, DiagnosticSeverity}; +use lsp_types::{DiagnosticSeverity}; use logos::Logos; use log::{debug, error, info, trace}; use rayon::prelude::*; +use crate::actions::SourcedDMLError; use crate::actions::analysis_storage::TimestampedStorage; use crate::analysis::symbols::{SimpleSymbol, DMLSymbolKind, Symbol, SymbolSource}; @@ -67,7 +68,6 @@ use crate::analysis::templating::types::DMLResolvedType; use crate::file_management::{PathResolver, CanonPath}; use crate::vfs::{TextFile, Error}; -use crate::lsp_data::ls_util::{dls_to_range, dls_to_location}; #[derive(Clone, Copy)] pub struct FileSpec<'a> { @@ -229,19 +229,11 @@ impl Hash for DMLError { } impl DMLError { - pub fn to_diagnostic(&self) -> Diagnostic { - Diagnostic::new( - dls_to_range(self.span.range), - self.severity, None, None, - self.description.clone(), - Some( - self.related.iter().map( - |(span, desc)|DiagnosticRelatedInformation { - location: dls_to_location(span), - message: desc.clone(), - }).collect()), - None - ) + pub fn with_source(self, source: &'static str) -> SourcedDMLError { + SourcedDMLError { + error: self, + source, + } } } @@ -260,10 +252,6 @@ impl LocalDMLError { related: vec![], } } - pub fn to_diagnostic(&self) -> Diagnostic { - Diagnostic::new_simple(dls_to_range(self.range), - self.description.clone()) - } pub fn warning_with_file>(self, file: F) -> DMLError { DMLError { span: ZeroSpan::from_range(self.range, file),