improve scoping with regard to function variables existing

This commit is contained in:
ConnorSkees 2020-05-13 01:32:29 -04:00
parent 425c36be86
commit 0cbdc67f06
3 changed files with 46 additions and 19 deletions

View File

@ -127,6 +127,19 @@ impl CallArgs {
}
}
pub fn get(
&mut self,
position: usize,
name: String,
scope: &Scope,
super_selector: &Selector,
) -> Option<SassResult<Spanned<Value>>> {
match self.get_named(name, scope, super_selector) {
Some(v) => return Some(v),
None => return self.get_positional(position, scope, super_selector),
}
}
pub fn get_variadic(
self,
scope: &Scope,

View File

@ -69,11 +69,11 @@ impl Function {
super_selector: &Selector,
) -> SassResult<()> {
let mut scope = scope.clone();
for (idx, arg) in self.args.0.iter().enumerate() {
for (idx, arg) in self.args.0.iter_mut().enumerate() {
if arg.is_variadic {
let span = args.span();
let arg_list = Value::ArgList(args.get_variadic(&scope, super_selector)?);
scope.insert_var(
self.scope.insert_var(
&arg.name,
Spanned {
node: arg_list,
@ -82,27 +82,24 @@ impl Function {
)?;
break;
}
let val = match args.get_positional(idx, &scope, super_selector) {
let val = match args.get(idx, arg.name.clone(), &scope, super_selector) {
Some(v) => v?,
None => match args.get_named(arg.name.clone(), &scope, super_selector) {
Some(v) => v?,
None => match &arg.default {
Some(v) => Value::from_tokens(
&mut v.iter().cloned().peekmore(),
&scope,
super_selector,
)?,
None => {
return Err(
(format!("Missing argument ${}.", &arg.name), args.span()).into()
)
}
},
None => match arg.default.as_mut() {
Some(v) => Value::from_tokens(
&mut std::mem::take(v).into_iter().peekmore(),
&scope,
super_selector,
)?,
None => {
return Err(
(format!("Missing argument ${}.", &arg.name), args.span()).into()
)
}
},
};
scope.insert_var(&arg.name, val)?;
scope.insert_var(&arg.name, val.clone())?;
self.scope.insert_var(&arg.name, val)?;
}
self.scope.extend(scope);
Ok(())
}

View File

@ -23,3 +23,20 @@ test!(
"$y: a;\n@mixin foo {\n $y: b !global;\n}\na {\n @include foo;\n color: $y;\n}\n",
"a {\n color: b;\n}\n"
);
test!(
local_variable_exists_in_fn_mixin_scope,
"@function exists-fn($name) {
@return variable-exists($name);
}
@mixin exists-mixin($name) {
color: variable-exists($name);
}
a {
$x: foo;
@include exists-mixin(x);
color: exists-fn(x);
}",
"a {\n color: false;\n color: false;\n}\n"
);