More progress on integrating ariadne's error reporting
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user