More progress on integrating ariadne's error reporting

This commit is contained in:
2026-03-01 02:20:58 -05:00
parent ef0f66efaa
commit 4a0cefee32
19 changed files with 297 additions and 295 deletions

View File

@@ -1,5 +1,5 @@
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::{HashMap, VecDeque};
use std::fmt::Display;
use ariadne::Color;
use ariadne::{Report, ReportKind};
@@ -13,7 +13,9 @@ use crate::{
pub type ShResult<T> = Result<T, ShErr>;
pub struct ColorRng;
pub struct ColorRng {
last_color: Option<Color>,
}
impl ColorRng {
fn get_colors() -> &'static [Color] {
@@ -51,7 +53,7 @@ impl Iterator for ColorRng {
}
thread_local! {
static COLOR_RNG: RefCell<ColorRng> = const { RefCell::new(ColorRng) };
static COLOR_RNG: RefCell<ColorRng> = const { RefCell::new(ColorRng { last_color: None }) };
}
pub fn next_color() -> Color {
@@ -144,8 +146,18 @@ impl ShErr {
pub fn simple(kind: ShErrKind, msg: impl Into<String>) -> Self {
Self { kind, src_span: None, labels: vec![], sources: vec![], notes: vec![msg.into()] }
}
pub fn full(kind: ShErrKind, msg: impl Into<String>, span: Span) -> Self {
Self { kind, src_span: Some(span), labels: vec![], sources: vec![], notes: vec![msg.into()] }
pub fn at(kind: ShErrKind, span: Span, msg: impl Into<String>) -> Self {
let color = next_color();
let src = span.span_source().clone();
let msg: String = msg.into();
Self::new(kind, span.clone())
.with_label(src, ariadne::Label::new(span).with_color(color).with_message(msg))
}
pub fn labeled(self, span: Span, msg: impl Into<String>) -> Self {
let color = next_color();
let src = span.span_source().clone();
let msg: String = msg.into();
self.with_label(src, ariadne::Label::new(span).with_color(color).with_message(msg))
}
pub fn blame(self, span: Span) -> Self {
let ShErr { kind, src_span: _, labels, sources, notes } = self;
@@ -172,7 +184,7 @@ impl ShErr {
labels.push(label);
Self { kind, src_span, labels, sources, notes }
}
pub fn with_context(self, ctx: Vec<(SpanSource, ariadne::Label<Span>)>) -> Self {
pub fn with_context(self, ctx: VecDeque<(SpanSource, ariadne::Label<Span>)>) -> Self {
let ShErr { kind, src_span, mut labels, mut sources, notes } = self;
for (src, label) in ctx {
sources.push(src);

View File

@@ -1,7 +1,9 @@
use std::collections::VecDeque;
use ariadne::Span as AriadneSpan;
use crate::parse::lex::{Span, Tk, TkRule};
use crate::parse::{Redir, RedirType};
use crate::parse::{Node, Redir, RedirType};
use crate::prelude::*;
pub trait VecDequeExt<T> {
@@ -27,6 +29,10 @@ pub trait RedirVecUtils<Redir> {
fn split_by_channel(self) -> (Vec<Redir>, Vec<Redir>);
}
pub trait NodeVecUtils<Node> {
fn get_span(&self) -> Option<Span>;
}
impl<T> VecDequeExt<T> for VecDeque<T> {
fn to_vec(self) -> Vec<T> {
self.into_iter().collect::<Vec<T>>()
@@ -124,3 +130,17 @@ impl RedirVecUtils<Redir> for Vec<Redir> {
(input, output)
}
}
impl NodeVecUtils<Node> for Vec<Node> {
fn get_span(&self) -> Option<Span> {
if let Some(first_nd) = self.first()
&& let Some(last_nd) = self.last() {
let first_start = first_nd.get_span().range().start;
let last_end = last_nd.get_span().range().end;
if first_start <= last_end {
return Some(Span::new(first_start..last_end, first_nd.get_span().source().content()));
}
}
None
}
}