replace codespan-reporting with miette 3.0

This commit is contained in:
Kat Marchán
2021-09-20 14:37:26 -07:00
parent cbe85cbeaf
commit a1d6cefdf8
14 changed files with 514 additions and 578 deletions

View File

@ -2,7 +2,7 @@ use crate::{ast::Call, value::Value, BlockId, Example, ShellError, Signature};
use super::EvaluationContext;
pub trait Command {
pub trait Command: Send + Sync {
fn name(&self) -> &str;
fn signature(&self) -> Signature {

View File

@ -1,7 +1,7 @@
use super::Command;
use crate::{ast::Block, BlockId, DeclId, Span, Type, VarId};
use core::panic;
use std::{collections::HashMap, ops::Range, slice::Iter};
use std::{collections::HashMap, slice::Iter};
pub struct EngineState {
files: Vec<(String, usize, usize)>,
@ -549,95 +549,42 @@ impl<'a> StateWorkingSet<'a> {
}
}
impl<'a> codespan_reporting::files::Files<'a> for StateWorkingSet<'a> {
type FileId = usize;
type Name = String;
type Source = String;
fn name(&'a self, id: Self::FileId) -> Result<Self::Name, codespan_reporting::files::Error> {
Ok(self.get_filename(id))
}
fn source(
&'a self,
id: Self::FileId,
) -> Result<Self::Source, codespan_reporting::files::Error> {
Ok(self.get_file_source(id))
}
fn line_index(
&'a self,
id: Self::FileId,
byte_index: usize,
) -> Result<usize, codespan_reporting::files::Error> {
let source = self.get_file_source(id);
let mut count = 0;
for byte in source.bytes().enumerate() {
if byte.0 == byte_index {
// println!("count: {} for file: {} index: {}", count, id, byte_index);
return Ok(count);
}
if byte.1 == b'\n' {
count += 1;
impl<'a> miette::SourceCode for &StateWorkingSet<'a> {
fn read_span<'b>(
&'b self,
span: &miette::SourceSpan,
context_lines_before: usize,
context_lines_after: usize,
) -> Result<Box<dyn miette::SpanContents + 'b>, miette::MietteError> {
for (filename, start, end) in self.files() {
if span.offset() >= *start && span.offset() + span.len() <= *end {
let our_span = Span {
start: *start,
end: *end,
};
// We need to move to a local span because we're only reading
// the specific file contents via self.get_span_contents.
let local_span = (span.offset() - *start, span.len()).into();
let span_contents = self.get_span_contents(our_span);
let span_contents = span_contents.read_span(
&local_span,
context_lines_before,
context_lines_after,
)?;
let content_span = span_contents.span();
// Back to "global" indexing
let retranslated = (content_span.offset() + start, content_span.len()).into();
return Ok(Box::new(miette::MietteSpanContents::new_named(
filename.clone(),
span_contents.data(),
retranslated,
span_contents.line(),
span_contents.column(),
span_contents.line_count(),
)));
}
}
// println!("count: {} for file: {} index: {}", count, id, byte_index);
Ok(count)
}
fn line_range(
&'a self,
id: Self::FileId,
line_index: usize,
) -> Result<Range<usize>, codespan_reporting::files::Error> {
let source = self.get_file_source(id);
let mut count = 0;
let mut start = Some(0);
let mut end = None;
for byte in source.bytes().enumerate() {
#[allow(clippy::comparison_chain)]
if count > line_index {
let start = start.expect("internal error: couldn't find line");
let end = end.expect("internal error: couldn't find line");
// println!(
// "Span: {}..{} for fileid: {} index: {}",
// start, end, id, line_index
// );
return Ok(start..end);
} else if count == line_index {
end = Some(byte.0 + 1);
}
#[allow(clippy::comparison_chain)]
if byte.1 == b'\n' {
count += 1;
if count > line_index {
break;
} else if count == line_index {
start = Some(byte.0 + 1);
}
}
}
match (start, end) {
(Some(start), Some(end)) => {
// println!(
// "Span: {}..{} for fileid: {} index: {}",
// start, end, id, line_index
// );
Ok(start..end)
}
_ => Err(codespan_reporting::files::Error::FileMissing),
}
Err(miette::MietteError::OutOfBounds)
}
}

View File

@ -1,25 +1,72 @@
use miette::Diagnostic;
use thiserror::Error;
use crate::{ast::Operator, Span, Type};
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Error, Diagnostic)]
pub enum ShellError {
#[error("Type mismatch during operation.")]
#[diagnostic(code(nu::shell::type_mismatch), url(docsrs))]
OperatorMismatch {
#[label = "type mismatch for operator"]
op_span: Span,
lhs_ty: Type,
#[label("{lhs_ty}")]
lhs_span: Span,
rhs_ty: Type,
#[label("{rhs_ty}")]
rhs_span: Span,
},
UnsupportedOperator(Operator, Span),
UnknownOperator(String, Span),
ExternalNotSupported(Span),
#[error("Unsupported operator: {0}.")]
#[diagnostic(code(nu::shell::unsupported_operator), url(docsrs))]
UnsupportedOperator(Operator, #[label = "unsupported operator"] Span),
#[error("Unsupported operator: {0}.")]
#[diagnostic(code(nu::shell::unknown_operator), url(docsrs))]
UnknownOperator(String, #[label = "unsupported operator"] Span),
#[error("External commands not yet supported")]
#[diagnostic(code(nu::shell::external_commands), url(docsrs))]
ExternalNotSupported(#[label = "external not supported"] Span),
#[error("Internal error: {0}.")]
#[diagnostic(code(nu::shell::internal_error), url(docsrs))]
InternalError(String),
VariableNotFoundAtRuntime(Span),
CantConvert(String, Span),
DivisionByZero(Span),
CannotCreateRange(Span),
AccessBeyondEnd(usize, Span),
AccessBeyondEndOfStream(Span),
IncompatiblePathAccess(String, Span),
CantFindColumn(Span),
ExternalCommand(String, Span),
#[error("Variable not found")]
#[diagnostic(code(nu::shell::variable_not_found), url(docsrs))]
VariableNotFoundAtRuntime(#[label = "variable not found"] Span),
#[error("Can't convert to {0}.")]
#[diagnostic(code(nu::shell::cant_convert), url(docsrs))]
CantConvert(String, #[label("can't convert to {0}")] Span),
#[error("Division by zero.")]
#[diagnostic(code(nu::shell::division_by_zero), url(docsrs))]
DivisionByZero(#[label("division by zero")] Span),
#[error("Can't convert range to countable values")]
#[diagnostic(code(nu::shell::range_to_countable), url(docsrs))]
CannotCreateRange(#[label = "can't convert to countable values"] Span),
#[error("Row number too large (max: {0}).")]
#[diagnostic(code(nu::shell::access_beyond_end), url(docsrs))]
AccessBeyondEnd(usize, #[label = "too large"] Span),
#[error("Row number too large.")]
#[diagnostic(code(nu::shell::access_beyond_end_of_stream), url(docsrs))]
AccessBeyondEndOfStream(#[label = "too large"] Span),
#[error("Data cannot be accessed with a cell path")]
#[diagnostic(code(nu::shell::incompatible_path_access), url(docsrs))]
IncompatiblePathAccess(String, #[label("{0} doesn't support cell paths")] Span),
#[error("Cannot find column")]
#[diagnostic(code(nu::shell::column_not_found), url(docsrs))]
CantFindColumn(#[label = "cannot find column"] Span),
#[error("External command")]
#[diagnostic(code(nu::shell::external_command), url(docsrs))]
ExternalCommand(String, #[label("{0}")] Span),
}

View File

@ -1,9 +1,17 @@
use miette::SourceSpan;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Span {
pub start: usize,
pub end: usize,
}
impl From<Span> for SourceSpan {
fn from(s: Span) -> Self {
Self::new(s.start.into(), (s.end - s.start).into())
}
}
impl Span {
pub fn new(start: usize, end: usize) -> Span {
Span { start, end }