Add Spanned trait and use it
This commit is contained in:
parent
16ebf7683a
commit
680ab9d633
22 changed files with 117 additions and 113 deletions
|
@ -13,7 +13,6 @@ homepage = "https://github.com/elkowar/eww"
|
|||
default = ["x11"]
|
||||
x11 = ["gdkx11", "x11rb"]
|
||||
wayland = ["gtk-layer-shell", "gtk-layer-shell-sys"]
|
||||
no-x11-wayland = []
|
||||
[dependencies.cairo-sys-rs]
|
||||
version = "0.10.0"
|
||||
|
||||
|
@ -70,9 +69,8 @@ notify = "5.0.0-pre.7"
|
|||
codespan-reporting = "0.11"
|
||||
|
||||
simplexpr = { path = "../simplexpr" }
|
||||
yuck = { path = "../yuck", default-features = false}
|
||||
eww_shared_util = { path = "../eww_shared_util" }
|
||||
|
||||
yuck = { path = "../yuck", default-features = false}
|
||||
|
||||
[dev-dependencies]
|
||||
pretty_assertions = "0.7.1"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
pub use platform::*;
|
||||
|
||||
#[cfg(feature = "no-x11-wayland")]
|
||||
#[cfg(not(any(feature = "x11", feature = "wayland")))]
|
||||
mod platform {
|
||||
use crate::config::EwwWindowDefinition;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::eww_state::EwwState;
|
||||
use anyhow::*;
|
||||
use dyn_clone;
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
use simplexpr::SimplExpr;
|
||||
use std::collections::HashMap;
|
||||
use yuck::{
|
||||
|
@ -11,7 +11,6 @@ use yuck::{
|
|||
|
||||
pub trait WidgetNode: std::fmt::Debug + dyn_clone::DynClone + Send + Sync {
|
||||
fn get_name(&self) -> &str;
|
||||
fn span(&self) -> Option<Span>;
|
||||
|
||||
/// Generate a [gtk::Widget] from a [element::WidgetUse].
|
||||
///
|
||||
|
@ -32,7 +31,7 @@ dyn_clone::clone_trait_object!(WidgetNode);
|
|||
#[derive(Debug, Clone)]
|
||||
pub struct UserDefined {
|
||||
name: String,
|
||||
span: Option<Span>,
|
||||
span: Span,
|
||||
content: Box<dyn WidgetNode>,
|
||||
}
|
||||
|
||||
|
@ -41,10 +40,6 @@ impl WidgetNode for UserDefined {
|
|||
&self.name
|
||||
}
|
||||
|
||||
fn span(&self) -> Option<Span> {
|
||||
self.span
|
||||
}
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
eww_state: &mut EwwState,
|
||||
|
@ -55,6 +50,12 @@ impl WidgetNode for UserDefined {
|
|||
}
|
||||
}
|
||||
|
||||
impl Spanned for UserDefined {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Generic {
|
||||
pub name: String,
|
||||
|
@ -88,10 +89,6 @@ impl WidgetNode for Generic {
|
|||
&self.name
|
||||
}
|
||||
|
||||
fn span(&self) -> Option<Span> {
|
||||
Some(self.span)
|
||||
}
|
||||
|
||||
fn render(
|
||||
&self,
|
||||
eww_state: &mut EwwState,
|
||||
|
@ -103,6 +100,11 @@ impl WidgetNode for Generic {
|
|||
})?)
|
||||
}
|
||||
}
|
||||
impl Spanned for Generic {
|
||||
fn span(&self) -> Span {
|
||||
self.span
|
||||
}
|
||||
}
|
||||
|
||||
pub fn generate_generic_widget_node(
|
||||
defs: &HashMap<String, WidgetDefinition>,
|
||||
|
@ -122,7 +124,7 @@ pub fn generate_generic_widget_node(
|
|||
.collect::<AstResult<HashMap<VarName, _>>>()?;
|
||||
|
||||
let content = generate_generic_widget_node(defs, &new_local_env, def.widget.clone())?;
|
||||
Ok(Box::new(UserDefined { name: w.name, span: Some(w.span), content }))
|
||||
Ok(Box::new(UserDefined { name: w.name, span: w.span, content }))
|
||||
} else {
|
||||
Ok(Box::new(Generic {
|
||||
name: w.name,
|
||||
|
|
|
@ -54,3 +54,7 @@ impl std::fmt::Debug for Span {
|
|||
write!(f, "{}..{}", self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Spanned {
|
||||
fn span(&self) -> Span;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::dynval::DynVal;
|
||||
use eww_shared_util::Span;
|
||||
use eww_shared_util::{Span, Spanned};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -69,8 +69,9 @@ impl SimplExpr {
|
|||
pub fn synth_literal<T: Into<DynVal>>(s: T) -> Self {
|
||||
Self::Literal(Span::DUMMY, s.into())
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
}
|
||||
impl Spanned for SimplExpr {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
SimplExpr::Literal(span, _) => *span,
|
||||
SimplExpr::VarRef(span, _) => *span,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use eww_shared_util::Span;
|
||||
use eww_shared_util::{Span, Spanned};
|
||||
use itertools::Itertools;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::{fmt, iter::FromIterator, str::FromStr};
|
||||
|
@ -17,8 +17,9 @@ impl ConversionError {
|
|||
fn new(value: DynVal, target_type: &'static str, source: impl std::error::Error + 'static + Sync + Send) -> Self {
|
||||
ConversionError { value, target_type, source: Some(Box::new(source)) }
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
}
|
||||
impl Spanned for ConversionError {
|
||||
fn span(&self) -> Span {
|
||||
self.value.1
|
||||
}
|
||||
}
|
||||
|
@ -111,15 +112,17 @@ impl From<&serde_json::Value> for DynVal {
|
|||
}
|
||||
}
|
||||
|
||||
impl Spanned for DynVal {
|
||||
fn span(&self) -> Span {
|
||||
self.1
|
||||
}
|
||||
}
|
||||
|
||||
impl DynVal {
|
||||
pub fn at(self, span: Span) -> Self {
|
||||
DynVal(self.0, span)
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
self.1
|
||||
}
|
||||
|
||||
pub fn from_string(s: String) -> Self {
|
||||
DynVal(s, Span::DUMMY)
|
||||
}
|
||||
|
|
|
@ -2,15 +2,15 @@ use crate::{
|
|||
dynval,
|
||||
parser::lexer::{self, LexicalError},
|
||||
};
|
||||
use eww_shared_util::Span;
|
||||
use eww_shared_util::{Span, Spanned};
|
||||
|
||||
pub type Result<T> = std::result::Result<T, Error>;
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum Error {
|
||||
#[error("Parse error: {source}")]
|
||||
#[error("Error parsing expression: {source}")]
|
||||
ParseError { file_id: usize, source: lalrpop_util::ParseError<usize, lexer::Token, lexer::LexicalError> },
|
||||
|
||||
#[error("Type error: {0}")]
|
||||
#[error(transparent)]
|
||||
ConversionError(#[from] dynval::ConversionError),
|
||||
|
||||
#[error("{1}")]
|
||||
|
@ -31,8 +31,10 @@ impl Error {
|
|||
pub fn at(self, span: Span) -> Self {
|
||||
Self::Spanned(span, Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
impl Spanned for Error {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
Self::ParseError { file_id, source } => get_parse_error_span(*file_id, source),
|
||||
Self::Spanned(span, _) => *span,
|
||||
|
|
|
@ -4,7 +4,7 @@ use crate::{
|
|||
ast::{BinOp, SimplExpr, UnaryOp},
|
||||
dynval::{ConversionError, DynVal},
|
||||
};
|
||||
use eww_shared_util::{Span, VarName};
|
||||
use eww_shared_util::{Span, Spanned, VarName};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
|
@ -18,7 +18,7 @@ pub enum EvalError {
|
|||
#[error("got unresolved variable `{0}`")]
|
||||
UnresolvedVariable(VarName),
|
||||
|
||||
#[error("Type error: {0}")]
|
||||
#[error(transparent)]
|
||||
ConversionError(#[from] ConversionError),
|
||||
|
||||
#[error("Incorrect number of arguments given to function: {0}")]
|
||||
|
@ -38,17 +38,19 @@ pub enum EvalError {
|
|||
}
|
||||
|
||||
impl EvalError {
|
||||
pub fn span(&self) -> Span {
|
||||
pub fn at(self, span: Span) -> Self {
|
||||
Self::Spanned(span, Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for EvalError {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
EvalError::Spanned(span, _) => *span,
|
||||
EvalError::ConversionError(err) => err.span(),
|
||||
_ => Span::DUMMY,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn at(self, span: Span) -> Self {
|
||||
Self::Spanned(span, Box::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl SimplExpr {
|
||||
|
@ -98,7 +100,6 @@ impl SimplExpr {
|
|||
pub fn resolve_refs(self, variables: &HashMap<VarName, DynVal>) -> Result<Self, EvalError> {
|
||||
use SimplExpr::*;
|
||||
match self {
|
||||
// Literal(x) => Ok(Literal(AttrValue::from_primitive(x.resolve_fully(&variables)?))),
|
||||
Literal(span, x) => Ok(Literal(span, x)),
|
||||
BinOp(span, box a, op, box b) => Ok(BinOp(span, box a.resolve_refs(variables)?, op, box b.resolve_refs(variables)?)),
|
||||
UnaryOp(span, op, box x) => Ok(UnaryOp(span, op, box x.resolve_refs(variables)?)),
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use eww_shared_util::{Span, Spanned};
|
||||
use logos::Logos;
|
||||
use regex::Regex;
|
||||
|
||||
|
@ -48,10 +49,15 @@ pub enum Token {
|
|||
Error,
|
||||
}
|
||||
|
||||
// TODO can i include the fileid here already?
|
||||
#[derive(Debug, Eq, PartialEq, Copy, Clone)]
|
||||
pub struct LexicalError(pub usize, pub usize, pub usize);
|
||||
|
||||
impl Spanned for LexicalError {
|
||||
fn span(&self) -> Span {
|
||||
Span(self.0, self.1, self.2)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for LexicalError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "Lexical error at {}..{}", self.0, self.1)
|
||||
|
|
|
@ -10,7 +10,6 @@ build = "build.rs"
|
|||
default = ["x11"]
|
||||
x11 = []
|
||||
wayland = []
|
||||
no-x11-wayland = []
|
||||
|
||||
[dependencies]
|
||||
lalrpop-util = "0.19.5"
|
||||
|
|
|
@ -13,7 +13,7 @@ use crate::{
|
|||
error::AstError,
|
||||
parser::{ast::Ast, from_ast::FromAst},
|
||||
};
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum AttrError {
|
||||
|
@ -27,8 +27,8 @@ pub enum AttrError {
|
|||
Other(Span, Box<dyn std::error::Error + Sync + Send + 'static>),
|
||||
}
|
||||
|
||||
impl AttrError {
|
||||
pub fn span(&self) -> Span {
|
||||
impl Spanned for AttrError {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
AttrError::MissingRequiredAttr(span, _) => *span,
|
||||
AttrError::EvaluationError(span, _) => *span,
|
||||
|
@ -90,7 +90,7 @@ impl Attributes {
|
|||
let ast: SimplExpr = self.ast_required(&key)?;
|
||||
Ok(ast
|
||||
.eval_no_vars()
|
||||
.map_err(|err| AttrError::EvaluationError(ast.span().into(), err))?
|
||||
.map_err(|err| AttrError::EvaluationError(ast.span(), err))?
|
||||
.read_as()
|
||||
.map_err(|e| AttrError::Other(ast.span().into(), Box::new(e)))?)
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ impl Attributes {
|
|||
};
|
||||
Ok(Some(
|
||||
ast.eval_no_vars()
|
||||
.map_err(|err| AttrError::EvaluationError(ast.span().into(), err))?
|
||||
.map_err(|err| AttrError::EvaluationError(ast.span(), err))?
|
||||
.read_as()
|
||||
.map_err(|e| AttrError::Other(ast.span().into(), Box::new(e)))?,
|
||||
))
|
||||
|
@ -115,9 +115,6 @@ impl Attributes {
|
|||
/// Consumes the attributes to return a list of unused attributes which may be used to emit a warning.
|
||||
/// TODO actually use this and implement warnings,... lol
|
||||
pub fn get_unused(self, definition_span: Span) -> UnusedAttrs {
|
||||
UnusedAttrs {
|
||||
definition_span,
|
||||
attrs: self.attrs.into_iter().map(|(k, v)| (v.key_span.to(v.value.span().into()), k)).collect(),
|
||||
}
|
||||
UnusedAttrs { definition_span, attrs: self.attrs.into_iter().map(|(k, v)| (v.key_span.to(v.value.span()), k)).collect() }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ mod backend {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "no-x11-wayland")]
|
||||
#[cfg(not(any(feature = "x11", feature = "wayland")))]
|
||||
mod backend {
|
||||
use super::*;
|
||||
#[derive(Debug, Clone, PartialEq, Eq, serde::Serialize)]
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ConfigParseError {}
|
|
@ -1,7 +1,6 @@
|
|||
pub mod attributes;
|
||||
pub mod backend_window_options;
|
||||
pub mod config;
|
||||
pub mod config_parse_error;
|
||||
pub mod file_provider;
|
||||
pub mod script_var_definition;
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -8,7 +8,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::{widget_definition::WidgetDefinition, widget_use::WidgetUse};
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ValidationError {
|
||||
|
@ -19,8 +19,8 @@ pub enum ValidationError {
|
|||
MissingAttr { widget_name: String, arg_name: AttrName, arg_list_span: Option<Span>, use_span: Span },
|
||||
}
|
||||
|
||||
impl ValidationError {
|
||||
pub fn span(&self) -> Span {
|
||||
impl Spanned for ValidationError {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
ValidationError::UnknownWidget(span, _) => *span,
|
||||
ValidationError::MissingAttr { use_span, .. } => *use_span,
|
||||
|
|
|
@ -7,7 +7,7 @@ use crate::{
|
|||
},
|
||||
};
|
||||
use codespan_reporting::{diagnostic, files};
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
use simplexpr::dynval;
|
||||
use thiserror::Error;
|
||||
|
||||
|
@ -66,7 +66,16 @@ impl AstError {
|
|||
AstError::ErrorContext { label_span, context: context.to_string(), main_err: Box::new(self) }
|
||||
}
|
||||
|
||||
pub fn span(&self) -> Span {
|
||||
pub fn from_parse_error(
|
||||
file_id: usize,
|
||||
err: lalrpop_util::ParseError<usize, lexer::Token, parse_error::ParseError>,
|
||||
) -> AstError {
|
||||
AstError::ParseError { file_id, source: err }
|
||||
}
|
||||
}
|
||||
|
||||
impl Spanned for AstError {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
AstError::UnknownToplevel(span, _) => *span,
|
||||
AstError::MissingNode(span) => *span,
|
||||
|
@ -80,30 +89,20 @@ impl AstError {
|
|||
AstError::TooManyNodes(span, ..) => *span,
|
||||
AstError::ErrorContext { label_span, .. } => *label_span,
|
||||
AstError::ValidationError(error) => error.span(),
|
||||
AstError::ParseError { file_id, source } => get_parse_error_span(*file_id, source, |err| err.span()),
|
||||
AstError::ParseError { file_id, source } => get_parse_error_span(*file_id, source),
|
||||
AstError::ErrorNote(_, err) => err.span(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_parse_error(
|
||||
file_id: usize,
|
||||
err: lalrpop_util::ParseError<usize, lexer::Token, parse_error::ParseError>,
|
||||
) -> AstError {
|
||||
AstError::ParseError { file_id, source: err }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_parse_error_span<T, E>(
|
||||
file_id: usize,
|
||||
err: &lalrpop_util::ParseError<usize, T, E>,
|
||||
handle_user: impl FnOnce(&E) -> Span,
|
||||
) -> Span {
|
||||
pub fn get_parse_error_span<T, E: Spanned>(file_id: usize, err: &lalrpop_util::ParseError<usize, T, E>) -> Span {
|
||||
use lalrpop_util::ParseError::*;
|
||||
match err {
|
||||
lalrpop_util::ParseError::InvalidToken { location } => Span(*location, *location, file_id),
|
||||
lalrpop_util::ParseError::UnrecognizedEOF { location, expected } => Span(*location, *location, file_id),
|
||||
lalrpop_util::ParseError::UnrecognizedToken { token, expected } => Span(token.0, token.2, file_id),
|
||||
lalrpop_util::ParseError::ExtraToken { token } => Span(token.0, token.2, file_id),
|
||||
lalrpop_util::ParseError::User { error } => handle_user(error),
|
||||
InvalidToken { location } => Span(*location, *location, file_id),
|
||||
UnrecognizedEOF { location, expected } => Span(*location, *location, file_id),
|
||||
UnrecognizedToken { token, expected } => Span(token.0, token.2, file_id),
|
||||
ExtraToken { token } => Span(token.0, token.2, file_id),
|
||||
User { error } => error.span(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::parser::parse_error;
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
|
||||
fn span_to_secondary_label(span: Span) -> Label<usize> {
|
||||
Label::secondary(span.2, span.0..span.1)
|
||||
|
@ -38,16 +38,12 @@ macro_rules! gen_diagnostic {
|
|||
}
|
||||
|
||||
pub trait DiagnosticExt: Sized {
|
||||
fn with_opt_label(self, label: Option<Label<usize>>) -> Self;
|
||||
fn with_label(self, label: Label<usize>) -> Self;
|
||||
}
|
||||
|
||||
impl DiagnosticExt for Diagnostic<usize> {
|
||||
fn with_opt_label(self, label: Option<Label<usize>>) -> Self {
|
||||
if let Some(label) = label {
|
||||
self.with_labels(vec![label])
|
||||
} else {
|
||||
self
|
||||
}
|
||||
fn with_label(self, label: Label<usize>) -> Self {
|
||||
self.with_labels(vec![label])
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -83,16 +79,14 @@ impl ToDiagnostic for AstError {
|
|||
note = format!("Got: {}", actual),
|
||||
},
|
||||
|
||||
AstError::ParseError { file_id, source } => {
|
||||
lalrpop_error_to_diagnostic(source, *file_id, |error| error.to_diagnostic())
|
||||
}
|
||||
AstError::ParseError { file_id, source } => lalrpop_error_to_diagnostic(source, *file_id),
|
||||
AstError::MismatchedElementName(span, expected, got) => gen_diagnostic! {
|
||||
msg = format!("Expected element `{}`, but found `{}`", expected, got),
|
||||
label = span => format!("Expected `{}` here", expected),
|
||||
note = format!("Expected: {}\nGot: {}", expected, got),
|
||||
},
|
||||
AstError::ErrorContext { label_span, context, main_err } => {
|
||||
main_err.to_diagnostic().with_opt_label(Some(span_to_secondary_label(*label_span).with_message(context)))
|
||||
main_err.to_diagnostic().with_label(span_to_secondary_label(*label_span).with_message(context))
|
||||
}
|
||||
|
||||
AstError::ConversionError(source) => source.to_diagnostic(),
|
||||
|
@ -118,7 +112,7 @@ impl ToDiagnostic for parse_error::ParseError {
|
|||
fn to_diagnostic(&self) -> Diagnostic<usize> {
|
||||
match self {
|
||||
parse_error::ParseError::SimplExpr(error) => error.to_diagnostic(),
|
||||
parse_error::ParseError::LexicalError(span) => lexical_error_diagnostic(*span),
|
||||
parse_error::ParseError::LexicalError(span) => generate_lexical_error_diagnostic(*span),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -142,45 +136,43 @@ impl ToDiagnostic for ValidationError {
|
|||
msg = self,
|
||||
label = span => "Used here",
|
||||
},
|
||||
ValidationError::MissingAttr { widget_name, arg_name, arg_list_span, use_span } => gen_diagnostic!(self)
|
||||
.with_opt_label(Some(span_to_secondary_label(*use_span).with_message("Argument missing here")))
|
||||
.with_opt_label(arg_list_span.map(|s| span_to_secondary_label(s).with_message("but is required here"))),
|
||||
ValidationError::MissingAttr { widget_name, arg_name, arg_list_span, use_span } => {
|
||||
let mut diag =
|
||||
gen_diagnostic!(self).with_label(span_to_secondary_label(*use_span).with_message("Argument missing here"));
|
||||
if let Some(arg_list_span) = arg_list_span {
|
||||
diag = diag.with_label(span_to_secondary_label(*arg_list_span).with_message("But is required here"));
|
||||
}
|
||||
diag
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn lalrpop_error_to_diagnostic<T: std::fmt::Display, E: std::fmt::Display>(
|
||||
fn lalrpop_error_to_diagnostic<T: std::fmt::Display, E: Spanned + ToDiagnostic>(
|
||||
error: &lalrpop_util::ParseError<usize, T, E>,
|
||||
file_id: usize,
|
||||
handle_user_error: impl FnOnce(&E) -> Diagnostic<usize>,
|
||||
) -> Diagnostic<usize> {
|
||||
use lalrpop_util::ParseError::*;
|
||||
// None is okay here, as the case that would be affected by it (User { error }) is manually handled here anyways
|
||||
let span = get_parse_error_span(file_id, error, |e| Span::DUMMY);
|
||||
match error {
|
||||
InvalidToken { location } => gen_diagnostic!("Invalid token", span),
|
||||
InvalidToken { location } => gen_diagnostic!("Invalid token", Span::point(*location, file_id)),
|
||||
UnrecognizedEOF { location, expected } => gen_diagnostic! {
|
||||
msg = "Input ended unexpectedly. Check if you have any unclosed delimiters",
|
||||
label = span
|
||||
label = Span::point(*location, file_id),
|
||||
},
|
||||
UnrecognizedToken { token, expected } => gen_diagnostic! {
|
||||
msg = format!("Unexpected token `{}` encountered", token.1),
|
||||
label = span => "Token unexpected",
|
||||
label = Span(token.0, token.2, file_id) => "Token unexpected",
|
||||
},
|
||||
ExtraToken { token } => gen_diagnostic!(format!("Extra token encountered: `{}`", token.1)),
|
||||
User { error } => handle_user_error(error),
|
||||
User { error } => error.to_diagnostic(),
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDiagnostic for simplexpr::error::Error {
|
||||
// TODO this needs a lot of improvement
|
||||
fn to_diagnostic(&self) -> Diagnostic<usize> {
|
||||
use simplexpr::error::Error::*;
|
||||
match self {
|
||||
ParseError { source, file_id } => {
|
||||
let span = get_parse_error_span(*file_id, source, |e| Span(e.0, e.1, *file_id));
|
||||
lalrpop_error_to_diagnostic(source, *file_id, move |error| lexical_error_diagnostic(span))
|
||||
}
|
||||
ParseError { source, file_id } => lalrpop_error_to_diagnostic(source, *file_id),
|
||||
ConversionError(error) => error.to_diagnostic(),
|
||||
Eval(error) => error.to_diagnostic(),
|
||||
Other(error) => gen_diagnostic!(error),
|
||||
|
@ -189,8 +181,13 @@ impl ToDiagnostic for simplexpr::error::Error {
|
|||
}
|
||||
}
|
||||
|
||||
impl ToDiagnostic for simplexpr::parser::lexer::LexicalError {
|
||||
fn to_diagnostic(&self) -> Diagnostic<usize> {
|
||||
generate_lexical_error_diagnostic(self.span())
|
||||
}
|
||||
}
|
||||
|
||||
impl ToDiagnostic for simplexpr::eval::EvalError {
|
||||
// TODO this needs a lot of improvement
|
||||
fn to_diagnostic(&self) -> Diagnostic<usize> {
|
||||
gen_diagnostic!(self, self.span())
|
||||
}
|
||||
|
@ -206,8 +203,7 @@ impl ToDiagnostic for dynval::ConversionError {
|
|||
}
|
||||
}
|
||||
|
||||
/// Generate a simple diagnostic indicating a lexical error
|
||||
fn lexical_error_diagnostic(span: Span) -> Diagnostic<usize> {
|
||||
fn generate_lexical_error_diagnostic(span: Span) -> Diagnostic<usize> {
|
||||
gen_diagnostic! {
|
||||
msg = "Invalid token",
|
||||
label = span => "Invalid token"
|
||||
|
|
|
@ -6,5 +6,4 @@ pub mod config;
|
|||
pub mod error;
|
||||
pub mod format_diagnostic;
|
||||
pub mod parser;
|
||||
mod util;
|
||||
pub mod value;
|
||||
|
|
|
@ -2,7 +2,7 @@ use super::{
|
|||
ast::{Ast, AstType},
|
||||
ast_iterator::AstIterator,
|
||||
};
|
||||
use crate::{error::*, parser, util};
|
||||
use crate::{error::*, parser};
|
||||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use itertools::Itertools;
|
||||
use simplexpr::{ast::SimplExpr, dynval::DynVal};
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use eww_shared_util::{AttrName, Span, VarName};
|
||||
use eww_shared_util::{AttrName, Span, Spanned, VarName};
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ParseError {
|
||||
|
@ -8,8 +8,8 @@ pub enum ParseError {
|
|||
LexicalError(Span),
|
||||
}
|
||||
|
||||
impl ParseError {
|
||||
pub fn span(&self) -> Span {
|
||||
impl Spanned for ParseError {
|
||||
fn span(&self) -> Span {
|
||||
match self {
|
||||
ParseError::SimplExpr(err) => err.span(),
|
||||
ParseError::LexicalError(span) => *span,
|
||||
|
|
Loading…
Add table
Reference in a new issue