Include spans in var_refs of simplexpr

This commit is contained in:
elkowar 2021-08-17 11:53:45 +02:00
parent c20b172662
commit 7abf38cbfc
No known key found for this signature in database
GPG key ID: E321AD71B1D1F27F
5 changed files with 39 additions and 23 deletions

View file

@ -15,7 +15,7 @@ pub struct StateChangeHandler {
impl StateChangeHandler {
fn used_variables(&self) -> impl Iterator<Item = &VarName> {
self.unresolved_values.iter().flat_map(|(_, value)| value.var_refs())
self.unresolved_values.iter().flat_map(|(_, value)| value.var_refs()).map(|(_, value)| value)
}
/// Run the StateChangeHandler.

View file

@ -80,7 +80,7 @@ impl Generic {
/// returns all the variables that are referenced in this widget
pub fn referenced_vars(&self) -> impl Iterator<Item = &VarName> {
self.attrs.iter().flat_map(|(_, value)| value.var_refs())
self.attrs.iter().flat_map(|(_, value)| value.var_refs()).map(|(_, value)| value)
}
}

View file

@ -5,7 +5,7 @@ use crate::{
dynval::{ConversionError, DynVal},
};
use eww_shared_util::{Span, Spanned, VarName};
use std::collections::{HashMap, HashSet};
use std::collections::HashMap;
#[derive(Debug, thiserror::Error)]
pub enum EvalError {
@ -102,12 +102,12 @@ impl SimplExpr {
})
}
pub fn var_refs(&self) -> HashSet<&VarName> {
pub fn var_refs(&self) -> Vec<(Span, &VarName)> {
use SimplExpr::*;
match self {
Literal(..) => HashSet::new(),
Literal(..) => Vec::new(),
VarRef(span, name) => vec![(*span, name)],
Concat(_, elems) => elems.iter().flat_map(|x| x.var_refs().into_iter()).collect(),
VarRef(_, name) => maplit::hashset! { name },
BinOp(_, box a, _, box b) | JsonAccess(_, box a, box b) => {
let mut refs = a.var_refs();
refs.extend(b.var_refs().iter());
@ -141,7 +141,7 @@ impl SimplExpr {
SimplExpr::Concat(span, elems) => {
let mut output = String::new();
for elem in elems {
let result = elem.eval(values)?;
let result = dbg!(elem.eval(values))?;
output.push_str(&result.0);
}
Ok(DynVal(output, *span))

View file

@ -10,11 +10,22 @@ pub fn b<T>(x: T) -> Box<T> {
pub fn parse_stringlit(
span: Span,
segs: Vec<Sp<StrLitSegment>>,
mut segs: Vec<Sp<StrLitSegment>>,
) -> Result<SimplExpr, lalrpop_util::ParseError<usize, Token, LexicalError>> {
let file_id = span.2;
let parser = crate::simplexpr_parser::ExprParser::new();
if segs.len() == 1 {
let (lo, seg, hi) = segs.remove(0);
let span = Span(lo, hi, file_id);
match seg {
StrLitSegment::Literal(lit) => Ok(SimplExpr::Literal(DynVal(lit, span))),
StrLitSegment::Interp(toks) => {
let token_stream = toks.into_iter().map(|x| Ok(x));
parser.parse(file_id, token_stream)
}
}
} else {
let elems = segs
.into_iter()
.filter_map(|(lo, segment, hi)| {
@ -31,3 +42,4 @@ pub fn parse_stringlit(
.collect::<Result<Vec<SimplExpr>, _>>()?;
Ok(SimplExpr::Concat(span, elems))
}
}

View file

@ -87,7 +87,11 @@ pub fn validate_variables_in_widget_use(
let values = widget.attrs.attrs.values();
let unknown_var = values.filter_map(|value| value.value.as_simplexpr().ok()).find_map(|expr: SimplExpr| {
let span = expr.span();
expr.var_refs().iter().map(move |&x| (span, x.clone())).find(|(span, var_ref)| !variables.contains(var_ref))
expr.var_refs()
.iter()
.cloned()
.map(|(span, var_ref)| (span, var_ref.clone()))
.find(|(_, var_ref)| !variables.contains(var_ref))
});
if let Some((span, var)) = unknown_var {
return Err(ValidationError::UnknownVariable { span, name: var.clone(), in_definition: is_in_definition });