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( pub fn get_variadic(
self, self,
scope: &Scope, scope: &Scope,

View File

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