Some more error message improvements
This commit is contained in:
parent
c0581e7769
commit
f7f718b94a
7 changed files with 54 additions and 32 deletions
|
@ -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);
|
||||||
})
|
})
|
||||||
|
|
|
@ -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)?;
|
||||||
|
|
|
@ -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 })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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),
|
||||||
|
|
|
@ -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),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Add table
Reference in a new issue