diff --git a/src/output/style.rs b/src/output/style.rs index caa46e260..9ca06baf2 100644 --- a/src/output/style.rs +++ b/src/output/style.rs @@ -800,21 +800,40 @@ impl Format { } } +use crate::sass::UseAs; fn do_use( scope: &mut dyn Scope, name: &SassString, - as_name: &Option, + as_name: &UseAs, ) -> Result<(), Error> { - let (name, _q) = name.evaluate(scope)?; - let as_name = if let Some(as_name) = as_name { - Some(as_name.evaluate(scope)?.0) + use crate::functions::get_global_module; + let name = name.evaluate(scope)?.0; + if let Some(module) = get_global_module(&name) { + match as_name { + UseAs::KeepName => { + let name = name + .rfind(':') + .map(|i| &name[i + 1..]) + .unwrap_or(&name); + scope.define_module(name, module); + } + UseAs::Star => { + for (name, function) in module { + scope.define_function(name, function.clone()); + } + } + UseAs::Name(name) => { + let name = name.evaluate(scope)?.0; + scope.define_module(&name, module); + } + } + Ok(()) } else { - None - }; - scope.do_use(&name, as_name.as_ref().map(|n| n.as_ref())); - Ok(()) + Err(Error::S(format!("Module {:?} not found", name).into())) + } } + struct CssWriter { imports: Vec, contents: Vec, diff --git a/src/parser/mod.rs b/src/parser/mod.rs index 056f507ad..41331415b 100644 --- a/src/parser/mod.rs +++ b/src/parser/mod.rs @@ -33,7 +33,7 @@ use self::value::{ use crate::functions::SassFunction; #[cfg(test)] use crate::sass::{CallArgs, FormalArgs}; -use crate::sass::{Item, Value}; +use crate::sass::{Item, UseAs, Value}; use crate::selectors::Selectors; use crate::value::ListSeparator; #[cfg(test)] @@ -306,13 +306,16 @@ fn use2(input: Span) -> IResult { ), opt(delimited( terminated(tag("as"), opt_spacelike), - sass_string, + alt(( + map(sass_string, UseAs::Name), + value(UseAs::Star, tag("*")), + )), opt_spacelike, )), ), tag(";"), ), - |(s, n)| Item::Use(s, n), + |(s, n)| Item::Use(s, n.unwrap_or(UseAs::KeepName)), )(input) } diff --git a/src/sass/item.rs b/src/sass/item.rs index 87962fbb6..f6b285e42 100644 --- a/src/sass/item.rs +++ b/src/sass/item.rs @@ -56,7 +56,7 @@ pub enum Item { }, While(Value, Vec), - Use(SassString, Option), + Use(SassString, UseAs), Rule(Selectors, Vec), NamespaceRule(SassString, Value, Vec), Property(SassString, Value), @@ -64,3 +64,10 @@ pub enum Item { Warn(Value), None, } + +#[derive(Clone, Debug, PartialEq, Eq, PartialOrd)] +pub enum UseAs { + KeepName, + Star, + Name(SassString), +} diff --git a/src/sass/mod.rs b/src/sass/mod.rs index 38c9130ca..8af9409bc 100644 --- a/src/sass/mod.rs +++ b/src/sass/mod.rs @@ -6,6 +6,6 @@ mod value; pub use self::call_args::CallArgs; pub use self::formal_args::FormalArgs; -pub use self::item::Item; +pub use self::item::{Item, UseAs}; pub use self::string::{SassString, StringPart}; pub use self::value::Value; diff --git a/src/sass/string.rs b/src/sass/string.rs index d3a9b8dea..d76ca8d7f 100644 --- a/src/sass/string.rs +++ b/src/sass/string.rs @@ -188,8 +188,8 @@ impl From<&str> for StringPart { } } -impl<'a> From<&'a str> for SassString { - fn from(s: &'a str) -> Self { +impl From<&str> for SassString { + fn from(s: &str) -> Self { SassString { parts: vec![StringPart::from(s)], quotes: Quotes::None, diff --git a/src/variablescope.rs b/src/variablescope.rs index 6b9232797..a35f9a31d 100644 --- a/src/variablescope.rs +++ b/src/variablescope.rs @@ -176,17 +176,6 @@ pub trait Scope { } Ok(None) } - fn do_use(&mut self, name: &str, as_name: Option<&str>) { - use crate::functions::get_global_module; - let as_name = as_name - .or_else(|| name.rfind(':').map(|i| &name[i + 1..])) - .unwrap_or(name); - if let Some(module) = get_global_module(name) { - self.define_module(as_name, module); - } else { - eprintln!("WARNING: module {:?} not found", name); - } - } fn define_module(&self, name: &str, module: &'static Module); fn get_module(&self, name: &str) -> Option<&Module>; fn get_selectors(&self) -> &Selectors; diff --git a/tests/spec/core_functions/meta/load_css/mod.rs b/tests/spec/core_functions/meta/load_css/mod.rs index 9d3574f2d..97b733b28 100644 --- a/tests/spec/core_functions/meta/load_css/mod.rs +++ b/tests/spec/core_functions/meta/load_css/mod.rs @@ -389,7 +389,7 @@ mod twice { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn different_extend() { assert_eq!( rsass( diff --git a/tests/spec/core_functions/meta/mod.rs b/tests/spec/core_functions/meta/mod.rs index 2150de246..8b28fd74b 100644 --- a/tests/spec/core_functions/meta/mod.rs +++ b/tests/spec/core_functions/meta/mod.rs @@ -771,7 +771,7 @@ mod global_variable_exists { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn chosen_prefix() { assert_eq!( rsass( @@ -787,7 +787,7 @@ mod global_variable_exists { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn defined() { assert_eq!( rsass( @@ -947,7 +947,7 @@ mod global_variable_exists { } } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn named() { assert_eq!( rsass( @@ -2271,7 +2271,7 @@ mod mixin_exists { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn chosen_prefix() { assert_eq!( rsass( @@ -2287,7 +2287,7 @@ mod mixin_exists { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn defined() { assert_eq!( rsass( @@ -2447,7 +2447,7 @@ mod mixin_exists { } } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn named() { assert_eq!( rsass( @@ -2606,7 +2606,7 @@ mod module_functions { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn empty() { assert_eq!( rsass( @@ -2796,7 +2796,7 @@ mod module_variables { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn test_as() { assert_eq!( rsass( @@ -2831,7 +2831,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn dash_sensitive() { assert_eq!( rsass( @@ -2849,7 +2849,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn empty() { assert_eq!( rsass( @@ -2885,7 +2885,7 @@ mod module_variables { // Ignoring "test_type", error tests are not supported yet. } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn multiple() { assert_eq!( rsass( @@ -2903,7 +2903,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn named() { assert_eq!( rsass( @@ -2924,7 +2924,7 @@ mod module_variables { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn test_as() { assert_eq!( rsass( @@ -2942,7 +2942,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn bare() { assert_eq!( rsass( @@ -2960,7 +2960,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn hide() { assert_eq!( rsass( @@ -2978,7 +2978,7 @@ mod module_variables { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn show() { assert_eq!( rsass( @@ -2997,7 +2997,7 @@ mod module_variables { } } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn through_import() { assert_eq!( rsass( diff --git a/tests/spec/core_functions/modules/mod.rs b/tests/spec/core_functions/modules/mod.rs index a91c86090..0dac51f7c 100644 --- a/tests/spec/core_functions/modules/mod.rs +++ b/tests/spec/core_functions/modules/mod.rs @@ -358,7 +358,7 @@ mod general { #[allow(unused)] use super::rsass; #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn test_as() { assert_eq!( rsass( @@ -374,7 +374,7 @@ mod general { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn bare() { assert_eq!( rsass( @@ -398,7 +398,7 @@ mod general { // Ignoring "show", error tests are not supported yet. } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn hide() { assert_eq!( rsass( @@ -414,7 +414,7 @@ mod general { ); } #[test] - #[ignore] // wrong result + #[ignore] // unexepected error fn show() { assert_eq!( rsass( @@ -431,7 +431,6 @@ mod general { } } #[test] - #[ignore] // unexepected error fn global() { assert_eq!( rsass(