@content tokens can access local scope

This commit is contained in:
Connor Skees 2020-07-02 15:43:11 -04:00
parent 1b033c3643
commit bf0665bbcd
4 changed files with 28 additions and 6 deletions

View File

@ -28,13 +28,15 @@ impl Mixin {
pub(crate) struct Content { pub(crate) struct Content {
pub content: Option<Vec<Token>>, pub content: Option<Vec<Token>>,
pub content_args: Option<FuncArgs>, pub content_args: Option<FuncArgs>,
pub scope: Scope,
} }
impl Content { impl Content {
pub const fn new() -> Self { pub fn new() -> Self {
Self { Self {
content: None, content: None,
content_args: None, content_args: None,
scope: Scope::new(),
} }
} }
} }

View File

@ -102,7 +102,6 @@ use peekmore::PeekMore;
pub use crate::error::{SassError as Error, SassResult as Result}; pub use crate::error::{SassError as Error, SassResult as Result};
pub(crate) use crate::token::Token; pub(crate) use crate::token::Token;
use crate::{ use crate::{
atrule::Content,
lexer::Lexer, lexer::Lexer,
output::Css, output::Css,
parse::{common::NeverEmptyVec, Parser}, parse::{common::NeverEmptyVec, Parser},
@ -160,7 +159,7 @@ pub fn from_path(p: &str) -> Result<String> {
global_scope: &mut Scope::new(), global_scope: &mut Scope::new(),
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
span_before: empty_span, span_before: empty_span,
content: &mut vec![Content::new()], content: &mut Vec::new(),
in_mixin: false, in_mixin: false,
in_function: false, in_function: false,
in_control_flow: false, in_control_flow: false,
@ -206,7 +205,7 @@ pub fn from_string(p: String) -> Result<String> {
global_scope: &mut Scope::new(), global_scope: &mut Scope::new(),
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
span_before: empty_span, span_before: empty_span,
content: &mut vec![Content::new()], content: &mut Vec::new(),
in_mixin: false, in_mixin: false,
in_function: false, in_function: false,
in_control_flow: false, in_control_flow: false,
@ -242,7 +241,7 @@ pub fn from_string(p: String) -> std::result::Result<String, JsValue> {
global_scope: &mut Scope::new(), global_scope: &mut Scope::new(),
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)), super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
span_before: empty_span, span_before: empty_span,
content: &mut vec![Content::new()], content: &mut Vec::new(),
in_mixin: false, in_mixin: false,
in_function: false, in_function: false,
in_control_flow: false, in_control_flow: false,

View File

@ -116,6 +116,7 @@ impl<'a> Parser<'a> {
self.content.push(Content { self.content.push(Content {
content, content,
content_args, content_args,
scope: self.scopes.last().clone(),
}); });
let body = Parser { let body = Parser {
@ -143,7 +144,12 @@ impl<'a> Parser<'a> {
pub(super) fn parse_content_rule(&mut self) -> SassResult<Vec<Stmt>> { pub(super) fn parse_content_rule(&mut self) -> SassResult<Vec<Stmt>> {
if self.in_mixin { 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() { if let Some(Token { kind: '(', .. }) = self.toks.peek() {
self.toks.next(); self.toks.next();
let args = self.parse_call_args()?; let args = self.parse_call_args()?;

View File

@ -323,6 +323,21 @@ test!(
}", }",
"a {\n color: red;\n}\n" "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!( error!(
content_using_too_many_args, content_using_too_many_args,
"@mixin foo { "@mixin foo {