Properly scope variables inside for loops
This commit is contained in:
parent
14eb173c56
commit
35163c4a36
@ -37,7 +37,7 @@ impl AtRule {
|
||||
rule: &AtRuleKind,
|
||||
pos: Pos,
|
||||
toks: &mut Peekable<I>,
|
||||
scope: &Scope,
|
||||
scope: &mut Scope,
|
||||
super_selector: &Selector,
|
||||
) -> SassResult<AtRule> {
|
||||
devour_whitespace(toks);
|
||||
@ -71,7 +71,7 @@ impl AtRule {
|
||||
AtRule::Mixin(name, Box::new(mixin))
|
||||
}
|
||||
AtRuleKind::Function => {
|
||||
let (name, func) = Function::decl_from_tokens(toks, scope)?;
|
||||
let (name, func) = Function::decl_from_tokens(toks, scope.clone())?;
|
||||
AtRule::Function(name, Box::new(func))
|
||||
}
|
||||
AtRuleKind::Return => {
|
||||
@ -176,13 +176,12 @@ impl AtRule {
|
||||
|
||||
devour_whitespace_or_comment(toks);
|
||||
|
||||
let mut scope = scope.clone();
|
||||
if from < to {
|
||||
for i in from..(to + through) {
|
||||
scope.insert_var(&var, Value::Dimension(Number::from(i), Unit::None))?;
|
||||
stmts.extend(eat_stmts(
|
||||
&mut body.clone().into_iter().peekable(),
|
||||
&scope,
|
||||
scope,
|
||||
super_selector,
|
||||
)?);
|
||||
}
|
||||
@ -191,7 +190,7 @@ impl AtRule {
|
||||
scope.insert_var(&var, Value::Dimension(Number::from(i), Unit::None))?;
|
||||
stmts.extend(eat_stmts(
|
||||
&mut body.clone().into_iter().peekable(),
|
||||
&scope,
|
||||
scope,
|
||||
super_selector,
|
||||
)?);
|
||||
}
|
||||
|
@ -7,12 +7,11 @@ use crate::{eat_expr, Expr, RuleSet, Stmt, Token};
|
||||
|
||||
pub(crate) fn eat_stmts<I: Iterator<Item = Token>>(
|
||||
toks: &mut Peekable<I>,
|
||||
scope: &Scope,
|
||||
scope: &mut Scope,
|
||||
super_selector: &Selector,
|
||||
) -> SassResult<Vec<Stmt>> {
|
||||
let mut stmts = Vec::new();
|
||||
let mut scope = scope.clone();
|
||||
while let Some(expr) = eat_expr(toks, &scope, super_selector)? {
|
||||
while let Some(expr) = eat_expr(toks, scope, super_selector)? {
|
||||
match expr {
|
||||
Expr::AtRule(a) => stmts.push(Stmt::AtRule(a)),
|
||||
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||
@ -22,7 +21,7 @@ pub(crate) fn eat_stmts<I: Iterator<Item = Token>>(
|
||||
todo!()
|
||||
}
|
||||
Expr::Selector(selector) => {
|
||||
let rules = eat_stmts(toks, &scope, &super_selector.zip(&selector))?;
|
||||
let rules = eat_stmts(toks, scope, &super_selector.zip(&selector))?;
|
||||
stmts.push(Stmt::RuleSet(RuleSet {
|
||||
super_selector: super_selector.clone(),
|
||||
selector,
|
||||
|
@ -19,7 +19,7 @@ impl UnknownAtRule {
|
||||
pub fn from_tokens<I: Iterator<Item = Token>>(
|
||||
toks: &mut Peekable<I>,
|
||||
name: &str,
|
||||
scope: &Scope,
|
||||
scope: &mut Scope,
|
||||
super_selector: &Selector,
|
||||
) -> SassResult<UnknownAtRule> {
|
||||
let mut params = String::new();
|
||||
|
@ -23,7 +23,7 @@ impl Function {
|
||||
|
||||
pub fn decl_from_tokens<I: Iterator<Item = Token>>(
|
||||
toks: &mut Peekable<I>,
|
||||
scope: &Scope,
|
||||
mut scope: Scope,
|
||||
) -> SassResult<(String, Function)> {
|
||||
let Token { kind, .. } = toks
|
||||
.next()
|
||||
@ -38,7 +38,7 @@ impl Function {
|
||||
Some(Token {
|
||||
kind: TokenKind::Symbol(Symbol::OpenParen),
|
||||
..
|
||||
}) => eat_func_args(toks, scope)?,
|
||||
}) => eat_func_args(toks, &scope)?,
|
||||
_ => return Err("expected \"(\".".into()),
|
||||
};
|
||||
|
||||
@ -52,7 +52,7 @@ impl Function {
|
||||
rule,
|
||||
tok.pos,
|
||||
toks,
|
||||
scope,
|
||||
&mut scope,
|
||||
&Selector::new(),
|
||||
)?),
|
||||
TokenKind::Symbol(Symbol::CloseCurlyBrace) => nesting -= 1,
|
||||
|
@ -460,7 +460,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
pos,
|
||||
}) = self.lexer.next()
|
||||
{
|
||||
match AtRule::from_tokens(rule, pos, &mut self.lexer, &self.global_scope, &Selector::new())? {
|
||||
match AtRule::from_tokens(rule, pos, &mut self.lexer, &mut self.global_scope, &Selector::new())? {
|
||||
AtRule::Mixin(name, mixin) => {
|
||||
self.global_scope.insert_mixin(&name, *mixin);
|
||||
}
|
||||
@ -542,7 +542,7 @@ impl<'a> StyleSheetParser<'a> {
|
||||
|
||||
pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
|
||||
toks: &mut Peekable<I>,
|
||||
scope: &Scope,
|
||||
scope: &mut Scope,
|
||||
super_selector: &Selector,
|
||||
) -> SassResult<Option<Expr>> {
|
||||
let mut values = Vec::with_capacity(5);
|
||||
|
@ -92,7 +92,7 @@ impl Mixin {
|
||||
|
||||
fn eval(&mut self, super_selector: &Selector) -> SassResult<Vec<Stmt>> {
|
||||
let mut stmts = Vec::new();
|
||||
while let Some(expr) = eat_expr(&mut self.body, &self.scope, super_selector)? {
|
||||
while let Some(expr) = eat_expr(&mut self.body, &mut self.scope, super_selector)? {
|
||||
match expr {
|
||||
Expr::AtRule(a) => stmts.push(Stmt::AtRule(a)),
|
||||
Expr::Style(s) => stmts.push(Stmt::Style(s)),
|
||||
|
@ -38,3 +38,8 @@ test!(
|
||||
"a {\n @for $i from 1 to 3 {\n color: $i;\n }\n}\n",
|
||||
"a {\n color: 1;\n color: 2;\n}\n"
|
||||
);
|
||||
test!(
|
||||
scope,
|
||||
"a {\n $a: red;\n @for $i from 1 to 3 {\n $a: blue;\n }\n color: $a;\n}\n",
|
||||
"a {\n color: blue;\n}\n"
|
||||
);
|
||||
|
Loading…
x
Reference in New Issue
Block a user