Fix @forward statement altering the scope of the forwarded module (#85)

* avoid mutating forwarded module scope

* fix by adding scope to ForwardedModule instead

- add a test reproducing the issue

* fix verbose and no-color sass cli flags
This commit is contained in:
Kevin Wenner 2023-09-28 09:15:46 +04:00 committed by GitHub
parent 05bad843c6
commit f7f620e44d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 19 deletions

View File

@ -108,6 +108,8 @@ impl ShadowedModule {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub(crate) struct ForwardedModule { pub(crate) struct ForwardedModule {
scope: ModuleScope,
#[allow(dead_code)]
inner: Arc<RefCell<Module>>, inner: Arc<RefCell<Module>>,
#[allow(dead_code)] #[allow(dead_code)]
forward_rule: AstForwardRule, forward_rule: AstForwardRule,
@ -138,15 +140,16 @@ impl ForwardedModule {
rule.hidden_mixins_and_functions.as_ref(), rule.hidden_mixins_and_functions.as_ref(),
); );
(*module).borrow_mut().set_scope(ModuleScope { let scope = ModuleScope {
variables, variables,
mixins, mixins,
functions, functions,
}); };
ForwardedModule { ForwardedModule {
inner: module, inner: module,
forward_rule: rule, forward_rule: rule,
scope,
} }
} }
@ -362,17 +365,8 @@ impl Module {
match self { match self {
Self::Builtin { scope } Self::Builtin { scope }
| Self::Environment { scope, .. } | Self::Environment { scope, .. }
| Self::Forwarded(ForwardedModule { scope, .. })
| Self::Shadowed(ShadowedModule { scope, .. }) => scope.clone(), | Self::Shadowed(ShadowedModule { scope, .. }) => scope.clone(),
Self::Forwarded(forwarded) => (*forwarded.inner).borrow().scope(),
}
}
fn set_scope(&mut self, new_scope: ModuleScope) {
match self {
Self::Builtin { scope }
| Self::Environment { scope, .. }
| Self::Shadowed(ShadowedModule { scope, .. }) => *scope = new_scope,
Self::Forwarded(forwarded) => (*forwarded.inner).borrow_mut().set_scope(new_scope),
} }
} }
@ -402,10 +396,9 @@ impl Module {
Self::Builtin { .. } => { Self::Builtin { .. } => {
return Err(("Cannot modify built-in variable.", name.span).into()) return Err(("Cannot modify built-in variable.", name.span).into())
} }
Self::Environment { scope, .. } | Self::Shadowed(ShadowedModule { scope, .. }) => { Self::Environment { scope, .. }
scope.clone() | Self::Forwarded(ForwardedModule { scope, .. })
} | Self::Shadowed(ShadowedModule { scope, .. }) => scope.clone(),
Self::Forwarded(forwarded) => (*forwarded.inner).borrow_mut().scope(),
}; };
if scope.variables.insert(name.node, value).is_none() { if scope.variables.insert(name.node, value).is_none() {

View File

@ -72,9 +72,7 @@ pub use grass_compiler::{
/// Include CSS in your binary at compile time from a Sass source file /// Include CSS in your binary at compile time from a Sass source file
/// ///
/// ``` /// `static CSS: &str = grass::include!("../static/_index.scss");`
/// static CSS: &str = grass::include!("../static/_index.scss");
/// ```
/// ///
/// This requires the `"macro"` feature, which is not enabled by default. /// This requires the `"macro"` feature, which is not enabled by default.
/// ///

View File

@ -168,12 +168,14 @@ fn cli() -> Command {
.arg( .arg(
Arg::new("NO_COLOR") Arg::new("NO_COLOR")
.short('c') .short('c')
.action(ArgAction::SetTrue)
.long("no-color") .long("no-color")
.hide(true) .hide(true)
.help("Whether to use terminal colors for messages.") .help("Whether to use terminal colors for messages.")
) )
.arg( .arg(
Arg::new("VERBOSE") Arg::new("VERBOSE")
.action(ArgAction::SetTrue)
.long("verbose") .long("verbose")
.hide(true) .hide(true)
.help("Print all deprecation warnings even when they're repetitive.") .help("Print all deprecation warnings even when they're repetitive.")

View File

@ -501,6 +501,40 @@ fn import_forwarded_first_no_use() {
); );
} }
#[test]
fn forward_same_module_with_and_without_prefix() {
let mut fs = TestFs::new();
fs.add_file(
"_midstream.scss",
r#"
@forward "upstream";
@forward "upstream" as b-*;
"#,
);
fs.add_file(
"_upstream.scss",
r#"
@mixin a() {
c {
d: e
}
}
"#,
);
let input = r#"
@use "midstream";
@include midstream.a;
"#;
assert_eq!(
"c {\n d: e;\n}\n",
&grass::from_string(input.to_string(), &grass::Options::default().fs(&fs)).expect(input)
);
}
error!( error!(
after_style_rule, after_style_rule,
r#" r#"