if conditions are evaluated lazily
This commit is contained in:
parent
365325729a
commit
632d649fdb
@ -22,12 +22,12 @@ pub(crate) struct If {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Branch {
|
pub(crate) struct Branch {
|
||||||
pub cond: Spanned<Value>,
|
pub cond: Vec<Token>,
|
||||||
pub toks: Vec<Token>,
|
pub toks: Vec<Token>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Branch {
|
impl Branch {
|
||||||
pub fn new(cond: Spanned<Value>, toks: Vec<Token>) -> Branch {
|
pub fn new(cond: Vec<Token>, toks: Vec<Token>) -> Branch {
|
||||||
Branch { cond, toks }
|
Branch { cond, toks }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,8 +35,6 @@ impl Branch {
|
|||||||
impl If {
|
impl If {
|
||||||
pub fn from_tokens<I: Iterator<Item = Token>>(
|
pub fn from_tokens<I: Iterator<Item = Token>>(
|
||||||
toks: &mut PeekMoreIterator<I>,
|
toks: &mut PeekMoreIterator<I>,
|
||||||
scope: &Scope,
|
|
||||||
super_selector: &Selector,
|
|
||||||
span_before: Span,
|
span_before: Span,
|
||||||
) -> SassResult<If> {
|
) -> SassResult<If> {
|
||||||
devour_whitespace_or_comment(toks)?;
|
devour_whitespace_or_comment(toks)?;
|
||||||
@ -49,7 +47,6 @@ impl If {
|
|||||||
Some(t) => t.pos,
|
Some(t) => t.pos,
|
||||||
None => return Err(("Expected expression.", span_before).into()),
|
None => return Err(("Expected expression.", span_before).into()),
|
||||||
};
|
};
|
||||||
let init_cond = Value::from_vec(init_cond_toks, scope, super_selector, span_before)?;
|
|
||||||
devour_whitespace_or_comment(toks)?;
|
devour_whitespace_or_comment(toks)?;
|
||||||
let mut init_toks = read_until_closing_curly_brace(toks)?;
|
let mut init_toks = read_until_closing_curly_brace(toks)?;
|
||||||
if let Some(tok) = toks.next() {
|
if let Some(tok) = toks.next() {
|
||||||
@ -59,7 +56,7 @@ impl If {
|
|||||||
}
|
}
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
|
|
||||||
branches.push(Branch::new(init_cond, init_toks));
|
branches.push(Branch::new(init_cond_toks, init_toks));
|
||||||
|
|
||||||
let mut else_ = Vec::new();
|
let mut else_ = Vec::new();
|
||||||
|
|
||||||
@ -80,13 +77,8 @@ impl If {
|
|||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
match tok.kind.to_ascii_lowercase() {
|
match tok.kind.to_ascii_lowercase() {
|
||||||
'i' if toks.next().unwrap().kind.to_ascii_lowercase() == 'f' => {
|
'i' if toks.next().unwrap().kind.to_ascii_lowercase() == 'f' => {
|
||||||
let pos = toks.next().unwrap().pos;
|
toks.next();
|
||||||
let cond = Value::from_vec(
|
let cond = read_until_open_curly_brace(toks)?;
|
||||||
read_until_open_curly_brace(toks)?,
|
|
||||||
scope,
|
|
||||||
super_selector,
|
|
||||||
pos,
|
|
||||||
)?;
|
|
||||||
toks.next();
|
toks.next();
|
||||||
devour_whitespace(toks);
|
devour_whitespace(toks);
|
||||||
branches.push(Branch::new(cond, read_until_closing_curly_brace(toks)?));
|
branches.push(Branch::new(cond, read_until_closing_curly_brace(toks)?));
|
||||||
@ -121,7 +113,9 @@ impl If {
|
|||||||
let mut toks = Vec::new();
|
let mut toks = Vec::new();
|
||||||
let mut found_true = false;
|
let mut found_true = false;
|
||||||
for branch in self.branches {
|
for branch in self.branches {
|
||||||
if branch.cond.node.is_true(branch.cond.span)? {
|
let span_before = branch.cond.first().unwrap().pos;
|
||||||
|
let cond = Value::from_vec(branch.cond, scope, super_selector, span_before)?;
|
||||||
|
if cond.node.is_true(cond.span)? {
|
||||||
toks = branch.toks;
|
toks = branch.toks;
|
||||||
found_true = true;
|
found_true = true;
|
||||||
break;
|
break;
|
||||||
|
@ -219,7 +219,7 @@ impl AtRule {
|
|||||||
span: kind_span,
|
span: kind_span,
|
||||||
},
|
},
|
||||||
AtRuleKind::If => Spanned {
|
AtRuleKind::If => Spanned {
|
||||||
node: AtRule::If(If::from_tokens(toks, scope, super_selector, kind_span)?),
|
node: AtRule::If(If::from_tokens(toks, kind_span)?),
|
||||||
span: kind_span,
|
span: kind_span,
|
||||||
},
|
},
|
||||||
AtRuleKind::For => Spanned {
|
AtRuleKind::For => Spanned {
|
||||||
|
@ -125,9 +125,16 @@ error!(
|
|||||||
"@if foo {", "Error: expected \"}\"."
|
"@if foo {", "Error: expected \"}\"."
|
||||||
);
|
);
|
||||||
error!(
|
error!(
|
||||||
condition_is_evaluated_eagerly,
|
first_condition_error,
|
||||||
"@if 1 + 1 =s {\n}", "Error: expected \"=\"."
|
"@if 1 + 1 =s {\n}", "Error: expected \"=\"."
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
conditions_evaluated_lazily,
|
||||||
|
"$p: null;
|
||||||
|
@if $p==null {}
|
||||||
|
@else if not comparable($p, 0) {}",
|
||||||
|
""
|
||||||
|
);
|
||||||
error!(
|
error!(
|
||||||
nothing_after_escape,
|
nothing_after_escape,
|
||||||
"@if \\", "Error: Expected expression."
|
"@if \\", "Error: Expected expression."
|
||||||
|
Loading…
x
Reference in New Issue
Block a user