Some more error message improvements

This commit is contained in:
elkowar 2021-08-14 11:58:04 +02:00
parent c0581e7769
commit f7f718b94a
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
7 changed files with 54 additions and 32 deletions

View file

@ -46,7 +46,7 @@ pub fn initialize_server(paths: EwwPaths, action: Option<DaemonCommand>) -> Resu
gtk::init()?; gtk::init()?;
log::info!("Initializing script var handler"); log::debug!("Initializing script var handler");
let script_var_handler = script_var_handler::init(ui_send.clone()); let script_var_handler = script_var_handler::init(ui_send.clone());
let mut app = app::App { let mut app = app::App {
@ -107,7 +107,7 @@ fn init_async_part(paths: EwwPaths, ui_send: UnboundedSender<app::DaemonCommand>
tokio::spawn(async move { tokio::spawn(async move {
// Wait for application exit event // Wait for application exit event
let _ = crate::application_lifecycle::recv_exit().await; let _ = crate::application_lifecycle::recv_exit().await;
log::info!("Forward task received exit event"); log::debug!("Forward task received exit event");
// Then forward that to the application // Then forward that to the application
let _ = ui_send.send(app::DaemonCommand::KillServer); let _ = ui_send.send(app::DaemonCommand::KillServer);
}) })

View file

@ -29,7 +29,7 @@ impl FromAstElementContent for WidgetDefinition {
let (name_span, name) = iter.expect_symbol().note(EXPECTED_WIDGET_DEF_FORMAT)?; let (name_span, name) = iter.expect_symbol().note(EXPECTED_WIDGET_DEF_FORMAT)?;
let (args_span, expected_args) = iter let (args_span, expected_args) = iter
.expect_array() .expect_array()
.wrong_expr_type_to(|_| FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end())) .wrong_expr_type_to(|_, _| Some(FormFormatError::WidgetDefArglistMissing(name_span.point_span_at_end())))
.note(EXPECTED_WIDGET_DEF_FORMAT)?; .note(EXPECTED_WIDGET_DEF_FORMAT)?;
let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::<AstResult<_>>()?; let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::<AstResult<_>>()?;
let widget = iter.expect_any().note(EXPECTED_WIDGET_DEF_FORMAT).and_then(WidgetUse::from_ast)?; let widget = iter.expect_any().note(EXPECTED_WIDGET_DEF_FORMAT).and_then(WidgetUse::from_ast)?;

View file

@ -4,7 +4,7 @@ use simplexpr::SimplExpr;
use crate::{ use crate::{
config::attributes::AttrEntry, config::attributes::AttrEntry,
error::AstResult, error::{AstError, AstResult},
parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst}, parser::{ast::Ast, ast_iterator::AstIterator, from_ast::FromAst},
}; };
use eww_shared_util::{AttrName, Span, VarName}; use eww_shared_util::{AttrName, Span, VarName};
@ -34,7 +34,19 @@ impl FromAst for WidgetUse {
fn from_ast(e: Ast) -> AstResult<Self> { fn from_ast(e: Ast) -> AstResult<Self> {
let span = e.span(); let span = e.span();
if let Ok(value) = e.clone().as_simplexpr() { if let Ok(value) = e.clone().as_simplexpr() {
Ok(Self { Ok(label_from_simplexpr(value, span))
} else {
let mut iter = e.try_ast_iter()?;
let (name_span, name) = iter.expect_symbol()?;
let attrs = iter.expect_key_values()?;
let children = iter.map(WidgetUse::from_ast).collect::<AstResult<Vec<_>>>()?;
Ok(Self { name, attrs, children, span, name_span })
}
}
}
fn label_from_simplexpr(value: SimplExpr, span: Span) -> WidgetUse {
WidgetUse {
name: "label".to_string(), name: "label".to_string(),
name_span: span.point_span(), name_span: span.point_span(),
attrs: Attributes::new( attrs: Attributes::new(
@ -48,13 +60,5 @@ impl FromAst for WidgetUse {
), ),
children: Vec::new(), children: Vec::new(),
span, span,
})
} else {
let mut iter = e.try_ast_iter()?;
let (name_span, name) = iter.expect_symbol()?;
let attrs = iter.expect_key_values()?;
let children = iter.map(WidgetUse::from_ast).collect::<AstResult<Vec<_>>>()?;
Ok(Self { name, attrs, children, span, name_span })
}
} }
} }

View file

@ -34,6 +34,9 @@ pub enum AstError {
#[error("Expected element {1}, but read {2}")] #[error("Expected element {1}, but read {2}")]
MismatchedElementName(Span, String, String), MismatchedElementName(Span, String, String),
#[error("Keyword `{1}` is missing a value")]
DanglingKeyword(Span, String),
#[error("Included file not found {}", .0.path)] #[error("Included file not found {}", .0.path)]
IncludedFileNotFound(Include), IncludedFileNotFound(Include),
@ -81,9 +84,11 @@ impl AstError {
AstError::ParseError { file_id, source: err } AstError::ParseError { file_id, source: err }
} }
pub fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstError { pub fn wrong_expr_type_to<T: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<T>) -> AstError {
match self { match self {
AstError::WrongExprType(span, ..) => AstError::FormFormatError(f(span.point_span())), AstError::WrongExprType(span, expected, got) => {
f(span.point_span(), got).map(|x| x.into()).unwrap_or_else(|| AstError::WrongExprType(span, expected, got))
}
AstError::ErrorNote(s, err) => AstError::ErrorNote(s, Box::new(err.wrong_expr_type_to(f))), AstError::ErrorNote(s, err) => AstError::ErrorNote(s, Box::new(err.wrong_expr_type_to(f))),
other => other, other => other,
} }
@ -98,6 +103,7 @@ impl Spanned for AstError {
AstError::WrongExprType(span, ..) => *span, AstError::WrongExprType(span, ..) => *span,
AstError::NotAValue(span, ..) => *span, AstError::NotAValue(span, ..) => *span,
AstError::MismatchedElementName(span, ..) => *span, AstError::MismatchedElementName(span, ..) => *span,
AstError::DanglingKeyword(span, _) => *span,
AstError::AttrError(err) => err.span(), AstError::AttrError(err) => err.span(),
AstError::Other(span, ..) => *span, AstError::Other(span, ..) => *span,
AstError::ConversionError(err) => err.value.span(), AstError::ConversionError(err) => err.value.span(),
@ -138,8 +144,9 @@ pub trait AstResultExt<T> {
fn context_label(self, label_span: Span, context: &str) -> AstResult<T>; fn context_label(self, label_span: Span, context: &str) -> AstResult<T>;
fn note(self, note: &str) -> AstResult<T>; fn note(self, note: &str) -> AstResult<T>;
/// Map any [AstError::WrongExprType]s error to a [FormFormatError] /// Map any [AstError::WrongExprType]s error to any other Into<AstError> (such as a [FormFormatError])
fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult<T>; /// If the provided closure returns `None`, the error will be kept unmodified
fn wrong_expr_type_to<E: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<E>) -> AstResult<T>;
} }
impl<T> AstResultExt<T> for AstResult<T> { impl<T> AstResultExt<T> for AstResult<T> {
@ -151,7 +158,7 @@ impl<T> AstResultExt<T> for AstResult<T> {
self.map_err(|e| e.note(note)) self.map_err(|e| e.note(note))
} }
fn wrong_expr_type_to(self, f: impl FnOnce(Span) -> FormFormatError) -> AstResult<T> { fn wrong_expr_type_to<E: Into<AstError>>(self, f: impl FnOnce(Span, AstType) -> Option<E>) -> AstResult<T> {
self.map_err(|err| err.wrong_expr_type_to(f)) self.map_err(|err| err.wrong_expr_type_to(f))
} }
} }

View file

@ -89,7 +89,7 @@ impl ToDiagnostic for AstError {
AstError::WrongExprType(span, expected, actual) => gen_diagnostic! { AstError::WrongExprType(span, expected, actual) => gen_diagnostic! {
msg = "Wrong type of expression", msg = "Wrong type of expression",
label = span => format!("Expected a `{}` here", expected), label = span => format!("Expected a `{}` here", expected),
note = format!("Expected: {}\nGot: {}", expected, actual), note = format!("Expected: {}\n Got: {}", expected, actual),
}, },
AstError::NotAValue(span, actual) => gen_diagnostic! { AstError::NotAValue(span, actual) => gen_diagnostic! {
msg = format!("Expected value, but got `{}`", actual), msg = format!("Expected value, but got `{}`", actual),
@ -101,7 +101,7 @@ impl ToDiagnostic for AstError {
AstError::MismatchedElementName(span, expected, got) => gen_diagnostic! { AstError::MismatchedElementName(span, expected, got) => gen_diagnostic! {
msg = format!("Expected element `{}`, but found `{}`", expected, got), msg = format!("Expected element `{}`, but found `{}`", expected, got),
label = span => format!("Expected `{}` here", expected), label = span => format!("Expected `{}` here", expected),
note = format!("Expected: {}\nGot: {}", expected, got), note = format!("Expected: {}\n Got: {}", expected, got),
}, },
AstError::ErrorContext { label_span, context, main_err } => { AstError::ErrorContext { label_span, context, main_err } => {
main_err.to_diagnostic().with_label(span_to_secondary_label(*label_span).with_message(context)) main_err.to_diagnostic().with_label(span_to_secondary_label(*label_span).with_message(context))
@ -120,6 +120,10 @@ impl ToDiagnostic for AstError {
label = extra_nodes_span => "these elements must not be here", label = extra_nodes_span => "these elements must not be here",
note = "Consider wrapping the elements in some container element", note = "Consider wrapping the elements in some container element",
}, },
AstError::DanglingKeyword(span, keyword) => gen_diagnostic! {
msg = self,
label = span => "No value provided for this",
},
AstError::ErrorNote(note, source) => source.to_diagnostic().with_notes(vec![note.to_string()]), AstError::ErrorNote(note, source) => source.to_diagnostic().with_notes(vec![note.to_string()]),
AstError::ValidationError(source) => source.to_diagnostic(), AstError::ValidationError(source) => source.to_diagnostic(),
AstError::NoMoreElementsExpected(span) => gen_diagnostic!(self, span), AstError::NoMoreElementsExpected(span) => gen_diagnostic!(self, span),

View file

@ -27,7 +27,10 @@ pub enum AstType {
impl Display for AstType { impl Display for AstType {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self) match self {
AstType::IntoPrimitive => write!(f, "primitive"),
_ => write!(f, "{:?}", self),
}
} }
} }

View file

@ -77,7 +77,7 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
} }
pub fn expect_key_values(&mut self) -> AstResult<Attributes> { pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
parse_key_values(self) parse_key_values(self, true)
} }
pub fn put_back(&mut self, ast: Ast) { pub fn put_back(&mut self, ast: Ast) {
@ -98,7 +98,7 @@ impl<I: Iterator<Item = Ast>> Iterator for AstIterator<I> {
} }
/// Parse consecutive `:keyword value` pairs from an expression iterator into an [Attributes]. /// Parse consecutive `:keyword value` pairs from an expression iterator into an [Attributes].
fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>) -> AstResult<Attributes> { fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>, fail_on_dangling_kw: bool) -> AstResult<Attributes> {
let mut data = HashMap::new(); let mut data = HashMap::new();
let mut attrs_span = iter.remaining_span.point_span(); let mut attrs_span = iter.remaining_span.point_span();
loop { loop {
@ -110,10 +110,14 @@ fn parse_key_values(iter: &mut AstIterator<impl Iterator<Item = Ast>>) -> AstRes
data.insert(AttrName(kw), attr_value); data.insert(AttrName(kw), attr_value);
} }
None => { None => {
if fail_on_dangling_kw {
return Err(AstError::DanglingKeyword(key_span, kw));
} else {
iter.iter.put_back(Ast::Keyword(key_span, kw)); iter.iter.put_back(Ast::Keyword(key_span, kw));
attrs_span.1 = iter.remaining_span.0; attrs_span.1 = iter.remaining_span.0;
return Ok(Attributes::new(attrs_span, data)); return Ok(Attributes::new(attrs_span, data));
} }
}
}, },
next => { next => {
if let Some(expr) = next { if let Some(expr) = next {