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