Properly scope variables inside for loops

This commit is contained in:
ConnorSkees 2020-03-01 08:20:59 -05:00
parent 14eb173c56
commit 35163c4a36
7 changed files with 19 additions and 16 deletions

View File

@ -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,
)?);
}

View File

@ -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,

View File

@ -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();

View File

@ -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,

View File

@ -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);

View File

@ -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)),

View File

@ -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"
);