Improve error messages for unread elements in nodes and fix span handling in ast iterator

This commit is contained in:
elkowar 2021-07-28 19:58:51 +02:00
parent 8fea52bda9
commit 6f1118bda4
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
12 changed files with 74 additions and 50 deletions

View file

@ -98,6 +98,7 @@ mod backend {
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
let mut attrs = iter.expect_key_values()?;
iter.expect_done().map_err(|e| e.note("Check if you are missing a colon in front of a key"))?;
Ok(StrutDefinition { side: attrs.primitive_required("side")?, dist: attrs.primitive_required("distance")? })
}
}

View file

@ -38,6 +38,7 @@ impl FromAstElementContent for Include {
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
let (path_span, path) = iter.expect_literal()?;
iter.expect_done()?;
Ok(Include { path: path.to_string(), path_span })
}
}

View file

@ -62,6 +62,7 @@ impl FromAstElementContent for PollScriptVar {
let mut attrs = iter.expect_key_values()?;
let interval = attrs.primitive_required::<DynVal, _>("interval")?.as_duration()?;
let (script_span, script) = iter.expect_literal()?;
iter.expect_done()?;
Ok(Self { name: VarName(name), command: VarSource::Shell(script_span, script.to_string()), interval })
}
}
@ -80,6 +81,7 @@ impl FromAstElementContent for ListenScriptVar {
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
let (_, name) = iter.expect_symbol()?;
let (command_span, script) = iter.expect_literal()?;
iter.expect_done()?;
Ok(Self { name: VarName(name), command: script.to_string(), command_span })
}
}

View file

@ -27,6 +27,7 @@ impl FromAstElementContent for VarDefinition {
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
let (_, name) = iter.expect_symbol()?;
let (_, initial_value) = iter.expect_literal()?;
iter.expect_done()?;
Ok(Self { name: VarName(name), initial_value, span })
}
}

View file

@ -32,8 +32,7 @@ impl FromAstElementContent for WidgetDefinition {
let (args_span, expected_args) = iter.expect_array()?;
let expected_args = expected_args.into_iter().map(|x| x.as_symbol().map(AttrName)).collect::<AstResult<_>>()?;
let widget = iter.expect_any().and_then(WidgetUse::from_ast)?;
// TODO verify that this was the last element in the list
// iter.expect_done()?;
iter.expect_done()?;
Ok(Self { name, expected_args, widget, span, args_span })
}
}

View file

@ -39,7 +39,8 @@ impl FromAstElementContent for WindowDefinition {
let stacking = attrs.primitive_optional("stacking")?.unwrap_or(WindowStacking::Foreground);
let geometry = attrs.ast_optional("geometry")?;
let backend_options = BackendWindowOptions::from_attrs(&mut attrs)?;
let widget = iter.expect_any()?;
let widget = iter.expect_any().and_then(WidgetUse::from_ast)?;
iter.expect_done()?;
Ok(Self { name, monitor_number, resizable, widget, stacking, geometry, backend_options })
}
}

View file

@ -123,6 +123,7 @@ impl FromAstElementContent for WindowGeometry {
fn from_tail<I: Iterator<Item = Ast>>(span: Span, mut iter: AstIterator<I>) -> AstResult<Self> {
let mut attrs = iter.expect_key_values()?;
iter.expect_done().map_err(|e| e.note("Check if you are missing a colon in front of a key"))?;
Ok(WindowGeometry {
anchor_point: attrs.primitive_optional("anchor")?.unwrap_or_default(),
size: Coords {

View file

@ -21,6 +21,8 @@ pub enum AstError {
MissingNode(Span),
#[error("Too many elements, must be exactly {1}")]
TooManyNodes(Span, i32),
#[error("Did not expect any further elements here. Make sure your format is correct")]
NoMoreElementsExpected(Span),
#[error("Wrong type of expression: Expected {1} but got {2}")]
WrongExprType(Span, AstType, AstType),
@ -91,6 +93,7 @@ impl Spanned for AstError {
AstError::ValidationError(error) => error.span(),
AstError::ParseError { file_id, source } => get_parse_error_span(*file_id, source),
AstError::ErrorNote(_, err) => err.span(),
AstError::NoMoreElementsExpected(span) => *span,
}
}
}

View file

@ -117,6 +117,7 @@ impl ToDiagnostic for AstError {
},
AstError::ErrorNote(note, source) => source.to_diagnostic().with_notes(vec![note.to_string()]),
AstError::ValidationError(source) => source.to_diagnostic(),
AstError::NoMoreElementsExpected(span) => gen_diagnostic!(self, span),
}
}
}

View file

@ -24,15 +24,11 @@ macro_rules! return_or_put_back {
pub fn $name(&mut self) -> AstResult<$t> {
let expr_type = $expr_type;
match self.expect_any()? {
$p => {
let (span, value) = $ret;
self.remaining_span.1 = span.1;
Ok((span, value))
}
$p => Ok($ret),
other => {
let span = other.span();
let actual_type = other.expr_type();
self.iter.put_back(other);
self.put_back(other);
Err(AstError::WrongExprType(span, expr_type, actual_type))
}
}
@ -53,20 +49,37 @@ impl<I: Iterator<Item = Ast>> AstIterator<I> {
AstIterator { remaining_span: span, iter: itertools::put_back(iter) }
}
pub fn expect_any<T: FromAst>(&mut self) -> AstResult<T> {
self.iter.next().or_missing(self.remaining_span.point_span()).and_then(T::from_ast)
pub fn expect_any(&mut self) -> AstResult<Ast> {
self.next().or_missing(self.remaining_span.point_span())
}
pub fn expect_done(&mut self) -> AstResult<()> {
if let Some(next) = self.next() {
self.put_back(next);
Err(AstError::NoMoreElementsExpected(self.remaining_span))
} else {
Ok(())
}
}
pub fn expect_key_values(&mut self) -> AstResult<Attributes> {
parse_key_values(self)
}
pub fn put_back(&mut self, ast: Ast) {
self.remaining_span.0 = ast.span().0;
self.iter.put_back(ast)
}
}
impl<I: Iterator<Item = Ast>> Iterator for AstIterator<I> {
type Item = Ast;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
self.iter.next().map(|x| {
self.remaining_span.0 = x.span().1;
x
})
}
}

View file

@ -39,9 +39,9 @@ impl<T: FromAstElementContent> FromAst for T {
fn from_ast(e: Ast) -> AstResult<Self> {
let span = e.span();
let mut iter = e.try_ast_iter()?;
let (_, element_name) = iter.expect_symbol()?;
let (element_name_span, element_name) = iter.expect_symbol()?;
if Self::get_element_name() != element_name {
return Err(AstError::MismatchedElementName(span, Self::get_element_name().to_string(), element_name));
return Err(AstError::MismatchedElementName(element_name_span, Self::get_element_name().to_string(), element_name));
}
Self::from_tail(span, iter)
}

View file

@ -1,45 +1,44 @@
(defwidget bar []
(box :orientation "h" :hexpand true
(workspaces)
(music)
(sidestuff)))
(box :orientation "h" :hexpand true
(workspaces)
(music)
(sidestuff)))
(defwidget sidestuff []
(box :class "sidestuff" :orientation "h" :space-evenly false :halign "end"
(slider-vol)
(slider-ram)
(time)))
(box :class "sidestuff" :orientation "h" :space-evenly false :halign "end"
(slider-vol)
(slider-ram)
(time)))
(defwidget workspaces []
(box :class "workspaces" :orientation "h" :space-evenly true :halign "start"
(button :onclick "wmctrl -s 0" 1)
(button :onclick "wmctrl -s 1" 2)
(button :onclick "wmctrl -s 2" 3)
(button :onclick "wmctrl -s 3" 4)
(button :onclick "wmctrl -s 4" 5)
(button :onclick "wmctrl -s 5" 6)
(button :onclick "wmctrl -s 6" 7)
(button :onclick "wmctrl -s 7" 8)
(button :onclick "wmctrl -s 8" 9)))
(box :class "workspaces" :orientation "h" :space-evenly true :halign "start"
(button :onclick "wmctrl -s 0" 1)
(button :onclick "wmctrl -s 1" 2)
(button :onclick "wmctrl -s 2" 3)
(button :onclick "wmctrl -s 3" 4)
(button :onclick "wmctrl -s 4" 5)
(button :onclick "wmctrl -s 5" 6)
(button :onclick "wmctrl -s 6" 7)
(button :onclick "wmctrl -s 7" 8)
(button :onclick "wmctrl -s 8" 9)))
(defwidget music []
(box :class "music" :orientation "h" :space-evenly false :halign "center"
{ ' ' + music}))
(box :class "music" :orientation "h" :space-evenly false :halign "center"
{ ' ' + music}))
(defwidget slider-vol []
(box :class "slider-vol" :orientation "h" :space-evenly "false"
(box :class "label-vol" ""
(scale :min 0 :max 101 :value volume :onchange "amixer -D pulse sset Master {}%"))))
(box :class "slider-vol" :orientation "h" :space-evenly "false"
(box :class "label-vol" ""
(scale :min 0 :max 101 :value volume :onchange "amixer -D pulse sset Master {}%"))))
(defwidget slider-ram []
(box :orientation "h" :class "slider-ram" :space-evenly false
(box :class "label-ram" ""
(scale :min 0 :max 101 :active false :value EWW_RAM))))
(box :orientation "h" :class "slider-ram" :space-evenly false
(box :class "label-ram" ""
(scale :min 0 :max 101 :active false :value EWW_RAM))))
(defwidget time []
(box :class "time"
{hour + ":" + min + " " + month + " " + number_day + ", " + year_full}))
(box :class "time"
{hour + ":" + min + " " + month + " " + number_day + ", " + year_full}))
(defpoll music :interval "5s" "playerctl metadata --format '{{ artist }} - {{ title }}' || true")
@ -51,12 +50,14 @@
(defpoll hour :interval "1m" "date '+%H'")
(defpoll year_full :interval "15h" "date '+%Y'")
(deflisten battery-remaining "/sys/class/power_supply/BAT0/capacity")
(deflisten battery-remaining "tail -f /sys/class/power_supply/BAT0/capacity")
(defwindow bar
:screen 0
:focusable true
:windowtype "dock"
:geometry (geometry :x "0%" :y "0%" :width "100%" :height "4%")
:reserve (struts :side "top" :distance "4%")
(bar))
:screen 0
:focusable true
:windowtype "dock"
:geometry (geometry :x "0%" :y "0%" :width "100%" :height "4%")
:reserve (struts :side "top" :distance "4%")
(bar))
; asdf