diff --git a/libs/@local/hql/diagnostics/src/diagnostic.rs b/libs/@local/hql/diagnostics/src/diagnostic.rs index 20a13bf7366..519c1b260f8 100644 --- a/libs/@local/hql/diagnostics/src/diagnostic.rs +++ b/libs/@local/hql/diagnostics/src/diagnostic.rs @@ -4,7 +4,7 @@ use core::{ }; use ariadne::ColorGenerator; -use error_stack::{Report, Result, TryReportIteratorExt, TryReportTupleExt}; +use error_stack::{Result, TryReportIteratorExt}; use hql_span::{Span, SpanId, storage::SpanStorage, tree::SpanNode}; use crate::{ @@ -16,7 +16,7 @@ use crate::{ note::Note, rob::RefOrBox, severity::Severity, - span::{AbsoluteDiagnosticSpan, TransformSpan, absolute_span}, + span::{AbsoluteDiagnosticSpan, TransformSpan}, }; #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -26,7 +26,6 @@ pub struct Diagnostic<'a, S> { pub severity: RefOrBox<'a, Severity<'a>>, pub message: Option>, - pub span: Option, pub labels: Vec>, pub note: Option, @@ -43,7 +42,6 @@ impl<'a, S> Diagnostic<'a, S> { category: category.into(), severity: severity.into(), message: None, - span: None, labels: Vec::new(), note: None, help: None, @@ -64,29 +62,18 @@ impl<'a> Diagnostic<'a, SpanId> { where S: Span + Clone, { - let span = self - .span - .map(|id| { - storage - .resolve(id) - .ok_or_else(|| Report::new(ResolveError::UnknownSpan { id })) - }) - .transpose(); - let labels: Result, _> = self .labels .into_iter() .map(|label| label.resolve(storage)) .try_collect_reports(); - let (span, labels) = (span, labels).try_collect()?; - Ok(Diagnostic { category: self.category, severity: self.severity, message: self.message, - span, - labels, + + labels: labels?, note: self.note, help: self.help, }) @@ -98,13 +85,18 @@ impl Diagnostic<'_, SpanNode> { &self, mut config: ReportConfig>, ) -> ariadne::Report { - let start = self.span.as_ref().map_or(0, |span| { - u32::from(absolute_span(span, &mut config.transform_span).start()) - }); + // According to the examples, the first range supplied should be the one that is absolute. + // See: https://github.com/zesterer/ariadne/blob/74c2a7f8881e95629f9fb8d70140c133972d81d3/examples/simple.rs#L14 + let span = self + .labels + .first() + .map_or_else(AbsoluteDiagnosticSpan::full, |label| { + label.absolute_span(&mut config.transform_span) + }); let mut generator = ColorGenerator::new(); - let mut builder = ariadne::Report::build(self.severity.as_ref().kind(), (), start as usize) + let mut builder = ariadne::Report::build(self.severity.as_ref().kind(), span) .with_code(self.category.as_ref().canonical_id()); builder.set_message( diff --git a/libs/@local/hql/diagnostics/src/label.rs b/libs/@local/hql/diagnostics/src/label.rs index 6ac14994628..864db8c90ae 100644 --- a/libs/@local/hql/diagnostics/src/label.rs +++ b/libs/@local/hql/diagnostics/src/label.rs @@ -90,14 +90,21 @@ impl Label { } impl Label> { + pub(crate) fn absolute_span( + &self, + transform: &mut impl TransformSpan, + ) -> AbsoluteDiagnosticSpan { + AbsoluteDiagnosticSpan::new(&self.span, transform) + } + pub(crate) fn ariadne( &self, enable_color: bool, generator: &mut ColorGenerator, transform: &mut impl TransformSpan, ) -> ariadne::Label { - let mut label = ariadne::Label::new(AbsoluteDiagnosticSpan::new(&self.span, transform)) - .with_message(&self.message); + let mut label = + ariadne::Label::new(self.absolute_span(transform)).with_message(&self.message); let color = self .color diff --git a/libs/@local/hql/diagnostics/src/span.rs b/libs/@local/hql/diagnostics/src/span.rs index b8afcc2af8e..e3ce8708921 100644 --- a/libs/@local/hql/diagnostics/src/span.rs +++ b/libs/@local/hql/diagnostics/src/span.rs @@ -54,6 +54,12 @@ impl AbsoluteDiagnosticSpan { Self { range } } + + pub(crate) const fn full() -> Self { + Self { + range: TextRange::new(TextSize::new(0), TextSize::new(u32::MAX)), + } + } } impl ariadne::Span for AbsoluteDiagnosticSpan {