consolidate arg evaluation for mixins and functions
This commit is contained in:
parent
a88f07da54
commit
8b907d4b67
@ -5,6 +5,7 @@ use codemap::{Span, Spanned};
|
|||||||
use crate::{
|
use crate::{
|
||||||
args::{CallArg, CallArgs, FuncArg, FuncArgs},
|
args::{CallArg, CallArgs, FuncArg, FuncArgs},
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
|
scope::Scope,
|
||||||
utils::{read_until_closing_paren, read_until_closing_quote, read_until_closing_square_brace},
|
utils::{read_until_closing_paren, read_until_closing_quote, read_until_closing_square_brace},
|
||||||
value::Value,
|
value::Value,
|
||||||
Token,
|
Token,
|
||||||
@ -298,4 +299,45 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
Ok(vals)
|
Ok(vals)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(super) fn eval_args(
|
||||||
|
&mut self,
|
||||||
|
mut fn_args: FuncArgs,
|
||||||
|
mut args: CallArgs,
|
||||||
|
scope: &mut Scope,
|
||||||
|
) -> SassResult<()> {
|
||||||
|
self.scopes.push(self.scopes.last().clone());
|
||||||
|
for (idx, arg) in fn_args.0.iter_mut().enumerate() {
|
||||||
|
if arg.is_variadic {
|
||||||
|
let span = args.span();
|
||||||
|
// todo: does this get the most recent scope?
|
||||||
|
let arg_list = Value::ArgList(self.variadic_args(args)?);
|
||||||
|
scope.insert_var(
|
||||||
|
arg.name.clone(),
|
||||||
|
Spanned {
|
||||||
|
node: arg_list,
|
||||||
|
span,
|
||||||
|
},
|
||||||
|
)?;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
let val = match args.get(idx, arg.name.clone()) {
|
||||||
|
Some(v) => self.parse_value_from_vec(v)?,
|
||||||
|
None => match arg.default.as_mut() {
|
||||||
|
Some(v) => self.parse_value_from_vec(mem::take(v))?,
|
||||||
|
None => {
|
||||||
|
return Err(
|
||||||
|
(format!("Missing argument ${}.", &arg.name), args.span()).into()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
self.scopes
|
||||||
|
.last_mut()
|
||||||
|
.insert_var(arg.name.clone(), val.clone())?;
|
||||||
|
scope.insert_var(mem::take(&mut arg.name), val)?;
|
||||||
|
}
|
||||||
|
self.scopes.pop();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::mem;
|
|
||||||
|
|
||||||
use codemap::Spanned;
|
use codemap::Spanned;
|
||||||
use peekmore::PeekMore;
|
use peekmore::PeekMore;
|
||||||
|
|
||||||
@ -91,14 +89,21 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(Box::new(v.node))
|
Ok(Box::new(v.node))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn eval_function(&mut self, mut function: Function, args: CallArgs) -> SassResult<Value> {
|
pub fn eval_function(&mut self, function: Function, args: CallArgs) -> SassResult<Value> {
|
||||||
self.eval_fn_args(&mut function, args)?;
|
let Function {
|
||||||
|
mut scope,
|
||||||
|
body,
|
||||||
|
args: fn_args,
|
||||||
|
..
|
||||||
|
} = function;
|
||||||
|
|
||||||
|
self.eval_args(fn_args, args, &mut scope)?;
|
||||||
|
|
||||||
let mut return_value = Parser {
|
let mut return_value = Parser {
|
||||||
toks: &mut function.body.into_iter().peekmore(),
|
toks: &mut body.into_iter().peekmore(),
|
||||||
map: self.map,
|
map: self.map,
|
||||||
path: self.path,
|
path: self.path,
|
||||||
scopes: &mut NeverEmptyVec::new(function.scope),
|
scopes: &mut NeverEmptyVec::new(scope),
|
||||||
global_scope: self.global_scope,
|
global_scope: self.global_scope,
|
||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
@ -121,39 +126,4 @@ impl<'a> Parser<'a> {
|
|||||||
_ => todo!("should be unreachable"),
|
_ => todo!("should be unreachable"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_fn_args(&mut self, function: &mut Function, mut args: CallArgs) -> SassResult<()> {
|
|
||||||
self.scopes.push(self.scopes.last().clone());
|
|
||||||
for (idx, arg) in function.args.0.iter_mut().enumerate() {
|
|
||||||
if arg.is_variadic {
|
|
||||||
let span = args.span();
|
|
||||||
let arg_list = Value::ArgList(self.variadic_args(args)?);
|
|
||||||
function.scope.insert_var(
|
|
||||||
arg.name.clone(),
|
|
||||||
Spanned {
|
|
||||||
node: arg_list,
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let val = match args.get(idx, arg.name.clone()) {
|
|
||||||
Some(v) => self.parse_value_from_vec(v)?,
|
|
||||||
None => match arg.default.as_mut() {
|
|
||||||
Some(v) => self.parse_value_from_vec(mem::take(v))?,
|
|
||||||
None => {
|
|
||||||
return Err(
|
|
||||||
(format!("Missing argument ${}.", &arg.name), args.span()).into()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
self.scopes
|
|
||||||
.last_mut()
|
|
||||||
.insert_var(arg.name.clone(), val.clone())?;
|
|
||||||
function.scope.insert_var(mem::take(&mut arg.name), val)?;
|
|
||||||
}
|
|
||||||
self.scopes.pop();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
use std::mem;
|
|
||||||
|
|
||||||
use codemap::Spanned;
|
use codemap::Spanned;
|
||||||
|
|
||||||
use peekmore::PeekMore;
|
use peekmore::PeekMore;
|
||||||
@ -8,9 +6,7 @@ use crate::{
|
|||||||
args::{CallArgs, FuncArgs},
|
args::{CallArgs, FuncArgs},
|
||||||
atrule::{Content, Mixin},
|
atrule::{Content, Mixin},
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
scope::Scope,
|
|
||||||
utils::read_until_closing_curly_brace,
|
utils::read_until_closing_curly_brace,
|
||||||
value::Value,
|
|
||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -185,45 +181,4 @@ impl<'a> Parser<'a> {
|
|||||||
.into())
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eval_args(
|
|
||||||
&mut self,
|
|
||||||
mut fn_args: FuncArgs,
|
|
||||||
mut args: CallArgs,
|
|
||||||
scope: &mut Scope,
|
|
||||||
) -> SassResult<()> {
|
|
||||||
self.scopes.push(self.scopes.last().clone());
|
|
||||||
for (idx, arg) in fn_args.0.iter_mut().enumerate() {
|
|
||||||
if arg.is_variadic {
|
|
||||||
let span = args.span();
|
|
||||||
// todo: does this get the most recent scope?
|
|
||||||
let arg_list = Value::ArgList(self.variadic_args(args)?);
|
|
||||||
scope.insert_var(
|
|
||||||
arg.name.clone(),
|
|
||||||
Spanned {
|
|
||||||
node: arg_list,
|
|
||||||
span,
|
|
||||||
},
|
|
||||||
)?;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let val = match args.get(idx, arg.name.clone()) {
|
|
||||||
Some(v) => self.parse_value_from_vec(v)?,
|
|
||||||
None => match arg.default.as_mut() {
|
|
||||||
Some(v) => self.parse_value_from_vec(mem::take(v))?,
|
|
||||||
None => {
|
|
||||||
return Err(
|
|
||||||
(format!("Missing argument ${}.", &arg.name), args.span()).into()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
self.scopes
|
|
||||||
.last_mut()
|
|
||||||
.insert_var(arg.name.clone(), val.clone())?;
|
|
||||||
scope.insert_var(mem::take(&mut arg.name), val)?;
|
|
||||||
}
|
|
||||||
self.scopes.pop();
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user