From c4cfb9112ef965adfcc4149cf82160ae47aa4fbf Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sat, 23 May 2020 13:39:47 -0400 Subject: [PATCH] eagerly evaluate \@if conditions --- src/atrule/if_rule.rs | 16 +++++++++------- src/atrule/mod.rs | 2 +- tests/if.rs | 10 ++++++++++ 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/atrule/if_rule.rs b/src/atrule/if_rule.rs index c712fd1..285f5db 100644 --- a/src/atrule/if_rule.rs +++ b/src/atrule/if_rule.rs @@ -22,12 +22,12 @@ pub(crate) struct If { #[derive(Debug, Clone)] pub(crate) struct Branch { - pub cond: Vec, + pub cond: Spanned, pub toks: Vec, } impl Branch { - pub fn new(cond: Vec, toks: Vec) -> Branch { + pub fn new(cond: Spanned, toks: Vec) -> Branch { Branch { cond, toks } } } @@ -35,14 +35,17 @@ impl Branch { impl If { pub fn from_tokens>( toks: &mut PeekMoreIterator, + scope: &Scope, + super_selector: &Selector, span_before: Span, ) -> SassResult { devour_whitespace_or_comment(toks)?; let mut branches = Vec::new(); - let init_cond = read_until_open_curly_brace(toks); - if toks.next().is_none() { + let init_toks = read_until_open_curly_brace(toks); + if init_toks.is_empty() || toks.next().is_none() { return Err(("Expected expression.", span_before).into()); } + let init_cond = Value::from_vec(init_toks, scope, super_selector)?; devour_whitespace_or_comment(toks)?; let mut init_toks = read_until_closing_curly_brace(toks); if let Some(tok) = toks.next() { @@ -76,7 +79,7 @@ impl If { match tok.kind.to_ascii_lowercase() { 'i' if toks.next().unwrap().kind.to_ascii_lowercase() == 'f' => { toks.next(); - let cond = read_until_open_curly_brace(toks); + let cond = Value::from_vec(read_until_open_curly_brace(toks), scope, super_selector)?; toks.next(); devour_whitespace(toks); branches.push(Branch::new(cond, read_until_closing_curly_brace(toks))); @@ -111,8 +114,7 @@ impl If { let mut toks = Vec::new(); let mut found_true = false; for branch in self.branches { - let val = Value::from_vec(branch.cond, scope, super_selector)?; - if val.node.is_true(val.span)? { + if branch.cond.node.is_true(branch.cond.span)? { toks = branch.toks; found_true = true; break; diff --git a/src/atrule/mod.rs b/src/atrule/mod.rs index afb5c4c..4434557 100644 --- a/src/atrule/mod.rs +++ b/src/atrule/mod.rs @@ -216,7 +216,7 @@ impl AtRule { span: kind_span, }, AtRuleKind::If => Spanned { - node: AtRule::If(If::from_tokens(toks, kind_span)?), + node: AtRule::If(If::from_tokens(toks, scope, super_selector, kind_span)?), span: kind_span, }, AtRuleKind::For => Spanned { diff --git a/tests/if.rs b/tests/if.rs index 56ec776..c9006fd 100644 --- a/tests/if.rs +++ b/tests/if.rs @@ -113,8 +113,18 @@ error!( "@if", "Error: Expected expression." ); +error!( + no_condition, + "@if{}", + "Error: Expected expression." +); error!( nothing_after_open_curly, "@if foo {", "Error: expected \"}\"." ); +error!( + condition_is_evaluated_eagerly, + "@if 1 + 1 =s {\n}", + "Error: expected \"=\"." +);