From bf0665bbcdbd58f66439ee66b68f7271007fb4ba Mon Sep 17 00:00:00 2001 From: Connor Skees Date: Thu, 2 Jul 2020 15:43:11 -0400 Subject: [PATCH] `@content` tokens can access local scope --- src/atrule/mixin.rs | 4 +++- src/lib.rs | 7 +++---- src/parse/mixin.rs | 8 +++++++- tests/mixins.rs | 15 +++++++++++++++ 4 files changed, 28 insertions(+), 6 deletions(-) diff --git a/src/atrule/mixin.rs b/src/atrule/mixin.rs index d6be1c5..a9980e1 100644 --- a/src/atrule/mixin.rs +++ b/src/atrule/mixin.rs @@ -28,13 +28,15 @@ impl Mixin { pub(crate) struct Content { pub content: Option>, pub content_args: Option, + pub scope: Scope, } impl Content { - pub const fn new() -> Self { + pub fn new() -> Self { Self { content: None, content_args: None, + scope: Scope::new(), } } } diff --git a/src/lib.rs b/src/lib.rs index 12e435d..854d7b5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -102,7 +102,6 @@ use peekmore::PeekMore; pub use crate::error::{SassError as Error, SassResult as Result}; pub(crate) use crate::token::Token; use crate::{ - atrule::Content, lexer::Lexer, output::Css, parse::{common::NeverEmptyVec, Parser}, @@ -160,7 +159,7 @@ pub fn from_path(p: &str) -> Result { global_scope: &mut Scope::new(), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), span_before: empty_span, - content: &mut vec![Content::new()], + content: &mut Vec::new(), in_mixin: false, in_function: false, in_control_flow: false, @@ -206,7 +205,7 @@ pub fn from_string(p: String) -> Result { global_scope: &mut Scope::new(), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), span_before: empty_span, - content: &mut vec![Content::new()], + content: &mut Vec::new(), in_mixin: false, in_function: false, in_control_flow: false, @@ -242,7 +241,7 @@ pub fn from_string(p: String) -> std::result::Result { global_scope: &mut Scope::new(), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), span_before: empty_span, - content: &mut vec![Content::new()], + content: &mut Vec::new(), in_mixin: false, in_function: false, in_control_flow: false, diff --git a/src/parse/mixin.rs b/src/parse/mixin.rs index 45b420b..349d70d 100644 --- a/src/parse/mixin.rs +++ b/src/parse/mixin.rs @@ -116,6 +116,7 @@ impl<'a> Parser<'a> { self.content.push(Content { content, content_args, + scope: self.scopes.last().clone(), }); let body = Parser { @@ -143,7 +144,12 @@ impl<'a> Parser<'a> { pub(super) fn parse_content_rule(&mut self) -> SassResult> { if self.in_mixin { - let mut scope = self.scopes.last().clone(); + let mut scope = self + .content + .last() + .cloned() + .unwrap_or_else(Content::new) + .scope; if let Some(Token { kind: '(', .. }) = self.toks.peek() { self.toks.next(); let args = self.parse_call_args()?; diff --git a/tests/mixins.rs b/tests/mixins.rs index e68c3b0..6c76e13 100644 --- a/tests/mixins.rs +++ b/tests/mixins.rs @@ -323,6 +323,21 @@ test!( }", "a {\n color: red;\n}\n" ); +test!( + content_can_access_local_variables, + "@mixin foo { + @content; + } + + a { + $bar: red; + + @include foo { + color: $bar; + } + }", + "a {\n color: red;\n}\n" +); error!( content_using_too_many_args, "@mixin foo {