diff --git a/src/builtin/modules/mod.rs b/src/builtin/modules/mod.rs index dd9757a..71465ad 100644 --- a/src/builtin/modules/mod.rs +++ b/src/builtin/modules/mod.rs @@ -25,6 +25,9 @@ mod string; pub(crate) struct Module { pub scope: Scope, + /// A module can itself import other modules + pub modules: Modules, + /// Whether or not this module is builtin /// e.g. `"sass:math"` is_builtin: bool, @@ -103,12 +106,17 @@ impl Modules { .into()), } } + + pub fn merge(&mut self, other: Self) { + self.0.extend(other.0); + } } impl Module { pub fn new_builtin() -> Self { Module { scope: Scope::default(), + modules: Modules::default(), is_builtin: true, } } @@ -238,8 +246,12 @@ impl Module { ) } - pub const fn new_from_scope(scope: Scope, is_builtin: bool) -> Self { - Module { scope, is_builtin } + pub const fn new_from_scope(scope: Scope, modules: Modules, is_builtin: bool) -> Self { + Module { + scope, + modules, + is_builtin, + } } } diff --git a/src/parse/module.rs b/src/parse/module.rs index 2cd57fc..ccf41d2 100644 --- a/src/parse/module.rs +++ b/src/parse/module.rs @@ -124,6 +124,8 @@ impl<'a, 'b> Parser<'a, 'b> { .map .add_file(name.to_owned(), String::from_utf8(fs::read(&import)?)?); + let mut modules = Modules::default(); + let stmts = Parser { toks: &mut Lexer::new_from_file(&file), map: self.map, @@ -139,7 +141,7 @@ impl<'a, 'b> Parser<'a, 'b> { extender: self.extender, content_scopes: self.content_scopes, options: self.options, - modules: &mut Modules::default(), + modules: &mut modules, module_config: config, } .parse()?; @@ -152,7 +154,7 @@ impl<'a, 'b> Parser<'a, 'b> { .into()); } - (Module::new_from_scope(global_scope, false), stmts) + (Module::new_from_scope(global_scope, modules, false), stmts) } else { return Err(("Can't find stylesheet to import.", self.span_before).into()); } @@ -226,7 +228,8 @@ impl<'a, 'b> Parser<'a, 'b> { let module_name = match module_alias.as_deref() { Some("*") => { - self.global_scope.merge_module(module); + self.modules.merge(module.modules); + self.global_scope.merge_module_scope(module.scope); continue; } Some(..) => module_alias.unwrap(), diff --git a/src/scope.rs b/src/scope.rs index 78b0dda..a31f8a4 100644 --- a/src/scope.rs +++ b/src/scope.rs @@ -4,7 +4,7 @@ use codemap::Spanned; use crate::{ atrule::mixin::Mixin, - builtin::{modules::Module, GLOBAL_FUNCTIONS}, + builtin::GLOBAL_FUNCTIONS, common::Identifier, error::SassResult, value::{SassFunction, Value}, @@ -87,8 +87,8 @@ impl Scope { self.functions.extend(other.functions); } - pub fn merge_module(&mut self, other: Module) { - self.merge(other.scope); + pub fn merge_module_scope(&mut self, other: Scope) { + self.merge(other); } pub fn default_var_exists(&self, s: Identifier) -> bool { diff --git a/tests/use.rs b/tests/use.rs index a02bde9..c9a86fd 100644 --- a/tests/use.rs +++ b/tests/use.rs @@ -330,6 +330,23 @@ fn use_cannot_see_modules_imported_by_other_modules() { assert_err!("Error: There is no module with the namespace \"a\".", input); } +#[test] +fn use_can_see_modules_imported_by_other_modules_when_aliased_as_star() { + let input = r#" + @use "use_can_see_modules_imported_by_other_modules_when_aliased_as_star__a" as *; + a { color: math.$e; } + "#; + + tempfile!( + "use_can_see_modules_imported_by_other_modules_when_aliased_as_star__a.scss", + "@use \"sass:math\";" + ); + + assert_eq!( + "a {\n color: 2.7182818285;\n}\n", + &grass::from_string(input.to_string(), &grass::Options::default()).expect(input) + ); +} #[test] fn use_modules_imported_by_other_modules_does_not_cause_conflict() {