modules contain their own module scope
This commit is contained in:
parent
d101a36f0c
commit
a7999d2e5b
@ -25,6 +25,9 @@ mod string;
|
|||||||
pub(crate) struct Module {
|
pub(crate) struct Module {
|
||||||
pub scope: Scope,
|
pub scope: Scope,
|
||||||
|
|
||||||
|
/// A module can itself import other modules
|
||||||
|
pub modules: Modules,
|
||||||
|
|
||||||
/// Whether or not this module is builtin
|
/// Whether or not this module is builtin
|
||||||
/// e.g. `"sass:math"`
|
/// e.g. `"sass:math"`
|
||||||
is_builtin: bool,
|
is_builtin: bool,
|
||||||
@ -103,12 +106,17 @@ impl Modules {
|
|||||||
.into()),
|
.into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn merge(&mut self, other: Self) {
|
||||||
|
self.0.extend(other.0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Module {
|
impl Module {
|
||||||
pub fn new_builtin() -> Self {
|
pub fn new_builtin() -> Self {
|
||||||
Module {
|
Module {
|
||||||
scope: Scope::default(),
|
scope: Scope::default(),
|
||||||
|
modules: Modules::default(),
|
||||||
is_builtin: true,
|
is_builtin: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,8 +246,12 @@ impl Module {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn new_from_scope(scope: Scope, is_builtin: bool) -> Self {
|
pub const fn new_from_scope(scope: Scope, modules: Modules, is_builtin: bool) -> Self {
|
||||||
Module { scope, is_builtin }
|
Module {
|
||||||
|
scope,
|
||||||
|
modules,
|
||||||
|
is_builtin,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,6 +124,8 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||||||
.map
|
.map
|
||||||
.add_file(name.to_owned(), String::from_utf8(fs::read(&import)?)?);
|
.add_file(name.to_owned(), String::from_utf8(fs::read(&import)?)?);
|
||||||
|
|
||||||
|
let mut modules = Modules::default();
|
||||||
|
|
||||||
let stmts = Parser {
|
let stmts = Parser {
|
||||||
toks: &mut Lexer::new_from_file(&file),
|
toks: &mut Lexer::new_from_file(&file),
|
||||||
map: self.map,
|
map: self.map,
|
||||||
@ -139,7 +141,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
content_scopes: self.content_scopes,
|
content_scopes: self.content_scopes,
|
||||||
options: self.options,
|
options: self.options,
|
||||||
modules: &mut Modules::default(),
|
modules: &mut modules,
|
||||||
module_config: config,
|
module_config: config,
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
@ -152,7 +154,7 @@ impl<'a, 'b> Parser<'a, 'b> {
|
|||||||
.into());
|
.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
(Module::new_from_scope(global_scope, false), stmts)
|
(Module::new_from_scope(global_scope, modules, false), stmts)
|
||||||
} else {
|
} else {
|
||||||
return Err(("Can't find stylesheet to import.", self.span_before).into());
|
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() {
|
let module_name = match module_alias.as_deref() {
|
||||||
Some("*") => {
|
Some("*") => {
|
||||||
self.global_scope.merge_module(module);
|
self.modules.merge(module.modules);
|
||||||
|
self.global_scope.merge_module_scope(module.scope);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Some(..) => module_alias.unwrap(),
|
Some(..) => module_alias.unwrap(),
|
||||||
|
@ -4,7 +4,7 @@ use codemap::Spanned;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
atrule::mixin::Mixin,
|
atrule::mixin::Mixin,
|
||||||
builtin::{modules::Module, GLOBAL_FUNCTIONS},
|
builtin::GLOBAL_FUNCTIONS,
|
||||||
common::Identifier,
|
common::Identifier,
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
value::{SassFunction, Value},
|
value::{SassFunction, Value},
|
||||||
@ -87,8 +87,8 @@ impl Scope {
|
|||||||
self.functions.extend(other.functions);
|
self.functions.extend(other.functions);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn merge_module(&mut self, other: Module) {
|
pub fn merge_module_scope(&mut self, other: Scope) {
|
||||||
self.merge(other.scope);
|
self.merge(other);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn default_var_exists(&self, s: Identifier) -> bool {
|
pub fn default_var_exists(&self, s: Identifier) -> bool {
|
||||||
|
17
tests/use.rs
17
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);
|
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]
|
#[test]
|
||||||
fn use_modules_imported_by_other_modules_does_not_cause_conflict() {
|
fn use_modules_imported_by_other_modules_does_not_cause_conflict() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user