forked from extern/nushell
replace codespan-reporting with miette 3.0
This commit is contained in:
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
}
|
||||
|
@ -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 }
|
||||
|
Reference in New Issue
Block a user