Keep parser context with bitflags
This commit is contained in:
parent
85a5b005cb
commit
85ec26001a
@ -60,6 +60,7 @@ codemap = "0.1.3"
|
|||||||
peekmore = "0.5.2"
|
peekmore = "0.5.2"
|
||||||
wasm-bindgen = { version = "0.2.63", optional = true }
|
wasm-bindgen = { version = "0.2.63", optional = true }
|
||||||
beef = "0.4.4"
|
beef = "0.4.4"
|
||||||
|
bitflags = "1.2.1"
|
||||||
# criterion is not a dev-dependency because it makes tests take too
|
# criterion is not a dev-dependency because it makes tests take too
|
||||||
# long to compile, and you cannot make dev-dependencies optional
|
# long to compile, and you cannot make dev-dependencies optional
|
||||||
criterion = { version = "0.3.2", optional = true }
|
criterion = { version = "0.3.2", optional = true }
|
||||||
|
@ -6,7 +6,7 @@ use crate::{
|
|||||||
args::CallArgs,
|
args::CallArgs,
|
||||||
common::QuoteKind,
|
common::QuoteKind,
|
||||||
error::SassResult,
|
error::SassResult,
|
||||||
parse::Parser,
|
parse::{Flags, Parser},
|
||||||
unit::Unit,
|
unit::Unit,
|
||||||
value::{SassFunction, Value},
|
value::{SassFunction, Value},
|
||||||
};
|
};
|
||||||
@ -232,7 +232,7 @@ fn call(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
|||||||
#[allow(clippy::needless_pass_by_value)]
|
#[allow(clippy::needless_pass_by_value)]
|
||||||
fn content_exists(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
fn content_exists(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||||
args.max_args(0)?;
|
args.max_args(0)?;
|
||||||
if !parser.in_mixin {
|
if !parser.flags.contains(Flags::IN_MIXIN) {
|
||||||
return Err((
|
return Err((
|
||||||
"content-exists() may only be called within a mixin.",
|
"content-exists() may only be called within a mixin.",
|
||||||
parser.span_before,
|
parser.span_before,
|
||||||
|
17
src/lib.rs
17
src/lib.rs
@ -94,7 +94,7 @@ pub(crate) use crate::token::Token;
|
|||||||
use crate::{
|
use crate::{
|
||||||
lexer::Lexer,
|
lexer::Lexer,
|
||||||
output::Css,
|
output::Css,
|
||||||
parse::{common::NeverEmptyVec, Parser},
|
parse::{common::NeverEmptyVec, Flags, Parser},
|
||||||
scope::Scope,
|
scope::Scope,
|
||||||
selector::{Extender, Selector},
|
selector::{Extender, Selector},
|
||||||
};
|
};
|
||||||
@ -149,13 +149,10 @@ pub fn from_path(p: &str) -> Result<String> {
|
|||||||
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::new(),
|
content: &mut Vec::new(),
|
||||||
in_mixin: false,
|
flags: Flags::empty(),
|
||||||
in_function: false,
|
|
||||||
in_control_flow: false,
|
|
||||||
at_root: true,
|
at_root: true,
|
||||||
at_root_has_selector: false,
|
at_root_has_selector: false,
|
||||||
extender: &mut Extender::new(empty_span),
|
extender: &mut Extender::new(empty_span),
|
||||||
in_keyframes: false,
|
|
||||||
}
|
}
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| raw_to_parse_error(&map, *e))?;
|
.map_err(|e| raw_to_parse_error(&map, *e))?;
|
||||||
@ -194,13 +191,10 @@ pub fn from_string(p: String) -> Result<String> {
|
|||||||
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::new(),
|
content: &mut Vec::new(),
|
||||||
in_mixin: false,
|
flags: Flags::empty(),
|
||||||
in_function: false,
|
|
||||||
in_control_flow: false,
|
|
||||||
at_root: true,
|
at_root: true,
|
||||||
at_root_has_selector: false,
|
at_root_has_selector: false,
|
||||||
extender: &mut Extender::new(empty_span),
|
extender: &mut Extender::new(empty_span),
|
||||||
in_keyframes: false,
|
|
||||||
}
|
}
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| raw_to_parse_error(&map, *e))?;
|
.map_err(|e| raw_to_parse_error(&map, *e))?;
|
||||||
@ -230,13 +224,10 @@ pub fn from_string(p: String) -> std::result::Result<String, JsValue> {
|
|||||||
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::new(),
|
content: &mut Vec::new(),
|
||||||
in_mixin: false,
|
flags: Flags::empty(),
|
||||||
in_function: false,
|
|
||||||
in_control_flow: false,
|
|
||||||
at_root: true,
|
at_root: true,
|
||||||
at_root_has_selector: false,
|
at_root_has_selector: false,
|
||||||
extender: &mut Extender::new(empty_span),
|
extender: &mut Extender::new(empty_span),
|
||||||
in_keyframes: false,
|
|
||||||
}
|
}
|
||||||
.parse()
|
.parse()
|
||||||
.map_err(|e| raw_to_parse_error(&map, *e).to_string())?;
|
.map_err(|e| raw_to_parse_error(&map, *e).to_string())?;
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{NeverEmptyVec, Parser, Stmt};
|
use super::{Flags, NeverEmptyVec, Parser, Stmt};
|
||||||
|
|
||||||
/// Names that functions are not allowed to have
|
/// Names that functions are not allowed to have
|
||||||
const FORBIDDEN_IDENTIFIERS: [&str; 7] =
|
const FORBIDDEN_IDENTIFIERS: [&str; 7] =
|
||||||
@ -22,11 +22,11 @@ impl<'a> Parser<'a> {
|
|||||||
self.whitespace_or_comment();
|
self.whitespace_or_comment();
|
||||||
let Spanned { node: name, span } = self.parse_identifier()?;
|
let Spanned { node: name, span } = self.parse_identifier()?;
|
||||||
|
|
||||||
if self.in_mixin {
|
if self.flags.contains(Flags::IN_MIXIN) {
|
||||||
return Err(("Mixins may not contain function declarations.", span).into());
|
return Err(("Mixins may not contain function declarations.", span).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.in_control_flow {
|
if self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||||
return Err(("Functions may not be declared in control directives.", span).into());
|
return Err(("Functions may not be declared in control directives.", span).into());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,13 +88,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_FUNCTION,
|
||||||
in_function: true,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: false,
|
at_root: false,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|
||||||
|
@ -83,13 +83,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: file.span.subspan(0, 0),
|
span_before: file.span.subspan(0, 0),
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse();
|
.parse();
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Parser;
|
use super::{Flags, Parser};
|
||||||
|
|
||||||
impl fmt::Display for KeyframesSelector {
|
impl fmt::Display for KeyframesSelector {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
@ -160,13 +160,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
})
|
})
|
||||||
.parse_keyframes_selector()?;
|
.parse_keyframes_selector()?;
|
||||||
|
|
||||||
@ -192,11 +189,8 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_KEYFRAMES,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: false,
|
at_root: false,
|
||||||
in_keyframes: true,
|
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::{
|
|||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{NeverEmptyVec, Parser, Stmt};
|
use super::{Flags, NeverEmptyVec, Parser, Stmt};
|
||||||
|
|
||||||
impl<'a> Parser<'a> {
|
impl<'a> Parser<'a> {
|
||||||
pub(super) fn parse_mixin(&mut self) -> SassResult<()> {
|
pub(super) fn parse_mixin(&mut self) -> SassResult<()> {
|
||||||
@ -127,14 +127,11 @@ impl<'a> Parser<'a> {
|
|||||||
global_scope: self.global_scope,
|
global_scope: self.global_scope,
|
||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
in_mixin: true,
|
flags: self.flags | Flags::IN_MIXIN,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
content: self.content,
|
content: self.content,
|
||||||
at_root: false,
|
at_root: false,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|
||||||
@ -144,7 +141,7 @@ 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.flags.contains(Flags::IN_MIXIN) {
|
||||||
let mut scope = self
|
let mut scope = self
|
||||||
.content
|
.content
|
||||||
.last()
|
.last()
|
||||||
@ -175,14 +172,11 @@ impl<'a> Parser<'a> {
|
|||||||
global_scope: self.global_scope,
|
global_scope: self.global_scope,
|
||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
content: self.content,
|
content: self.content,
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?
|
.parse()?
|
||||||
} else {
|
} else {
|
||||||
|
@ -66,11 +66,21 @@ pub(crate) enum Stmt {
|
|||||||
KeyframesRuleSet(Box<KeyframesRuleSet>),
|
KeyframesRuleSet(Box<KeyframesRuleSet>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bitflags::bitflags! {
|
||||||
|
// todo: try to remove the flag IN_CONTROL_FLOW
|
||||||
|
/// Flags to indicate the context during parsing.
|
||||||
|
pub struct Flags: u8 {
|
||||||
|
const IN_MIXIN = 1;
|
||||||
|
const IN_FUNCTION = 1 << 1;
|
||||||
|
const IN_CONTROL_FLOW = 1 << 2;
|
||||||
|
const IN_KEYFRAMES = 1 << 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// We could use a generic for the toks, but it makes the API
|
/// We could use a generic for the toks, but it makes the API
|
||||||
/// much simpler to work with if it isn't generic. The performance
|
/// much simpler to work with if it isn't generic. The performance
|
||||||
/// hit (if there is one) is not important for now.
|
/// hit (if there is one) is not important for now.
|
||||||
// todo: refactor `in_mixin`, in_function`, and `at_root` into state machine enum
|
// todo: merge at_root and at_root_has_selector into an enum
|
||||||
#[allow(clippy::struct_excessive_bools)]
|
|
||||||
pub(crate) struct Parser<'a> {
|
pub(crate) struct Parser<'a> {
|
||||||
pub toks: &'a mut PeekMoreIterator<IntoIter<Token>>,
|
pub toks: &'a mut PeekMoreIterator<IntoIter<Token>>,
|
||||||
pub map: &'a mut CodeMap,
|
pub map: &'a mut CodeMap,
|
||||||
@ -80,10 +90,7 @@ pub(crate) struct Parser<'a> {
|
|||||||
pub super_selectors: &'a mut NeverEmptyVec<Selector>,
|
pub super_selectors: &'a mut NeverEmptyVec<Selector>,
|
||||||
pub span_before: Span,
|
pub span_before: Span,
|
||||||
pub content: &'a mut Vec<Content>,
|
pub content: &'a mut Vec<Content>,
|
||||||
pub in_mixin: bool,
|
pub flags: Flags,
|
||||||
pub in_function: bool,
|
|
||||||
pub in_control_flow: bool,
|
|
||||||
pub in_keyframes: bool,
|
|
||||||
/// Whether this parser is at the root of the document
|
/// Whether this parser is at the root of the document
|
||||||
/// E.g. not inside a style, mixin, or function
|
/// E.g. not inside a style, mixin, or function
|
||||||
pub at_root: bool,
|
pub at_root: bool,
|
||||||
@ -98,7 +105,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
while self.toks.peek().is_some() {
|
while self.toks.peek().is_some() {
|
||||||
stmts.append(&mut self.parse_stmt()?);
|
stmts.append(&mut self.parse_stmt()?);
|
||||||
if self.in_function && !stmts.is_empty() {
|
if self.flags.contains(Flags::IN_FUNCTION) && !stmts.is_empty() {
|
||||||
return Ok(stmts);
|
return Ok(stmts);
|
||||||
}
|
}
|
||||||
self.at_root = true;
|
self.at_root = true;
|
||||||
@ -109,7 +116,7 @@ impl<'a> Parser<'a> {
|
|||||||
fn parse_stmt(&mut self) -> SassResult<Vec<Stmt>> {
|
fn parse_stmt(&mut self) -> SassResult<Vec<Stmt>> {
|
||||||
let mut stmts = Vec::new();
|
let mut stmts = Vec::new();
|
||||||
while let Some(Token { kind, pos }) = self.toks.peek() {
|
while let Some(Token { kind, pos }) = self.toks.peek() {
|
||||||
if self.in_function && !stmts.is_empty() {
|
if self.flags.contains(Flags::IN_FUNCTION) && !stmts.is_empty() {
|
||||||
return Ok(stmts);
|
return Ok(stmts);
|
||||||
}
|
}
|
||||||
self.span_before = *pos;
|
self.span_before = *pos;
|
||||||
@ -125,7 +132,7 @@ impl<'a> Parser<'a> {
|
|||||||
AtRuleKind::Include => stmts.append(&mut self.parse_include()?),
|
AtRuleKind::Include => stmts.append(&mut self.parse_include()?),
|
||||||
AtRuleKind::Function => self.parse_function()?,
|
AtRuleKind::Function => self.parse_function()?,
|
||||||
AtRuleKind::Return => {
|
AtRuleKind::Return => {
|
||||||
if self.in_function {
|
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||||
return Ok(vec![Stmt::Return(self.parse_return()?)]);
|
return Ok(vec![Stmt::Return(self.parse_return()?)]);
|
||||||
} else {
|
} else {
|
||||||
return Err((
|
return Err((
|
||||||
@ -235,7 +242,7 @@ impl<'a> Parser<'a> {
|
|||||||
// dart-sass seems to special-case the error message here?
|
// dart-sass seems to special-case the error message here?
|
||||||
'!' | '{' => return Err(("expected \"}\".", *pos).into()),
|
'!' | '{' => return Err(("expected \"}\".", *pos).into()),
|
||||||
_ => {
|
_ => {
|
||||||
if self.in_keyframes {
|
if self.flags.contains(Flags::IN_KEYFRAMES) {
|
||||||
match self.is_selector_or_style()? {
|
match self.is_selector_or_style()? {
|
||||||
SelectorOrStyle::Style(property, value) => {
|
SelectorOrStyle::Style(property, value) => {
|
||||||
if let Some(value) = value {
|
if let Some(value) = value {
|
||||||
@ -375,13 +382,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
},
|
},
|
||||||
allows_parent,
|
allows_parent,
|
||||||
true,
|
true,
|
||||||
@ -607,13 +611,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse();
|
.parse();
|
||||||
}
|
}
|
||||||
@ -630,13 +631,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()
|
.parse()
|
||||||
}
|
}
|
||||||
@ -764,7 +762,7 @@ impl<'a> Parser<'a> {
|
|||||||
span: var.span,
|
span: var.span,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
if self.in_function {
|
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||||
let these_stmts = Parser {
|
let these_stmts = Parser {
|
||||||
toks: &mut body.clone().into_iter().peekmore(),
|
toks: &mut body.clone().into_iter().peekmore(),
|
||||||
map: self.map,
|
map: self.map,
|
||||||
@ -774,13 +772,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
if !these_stmts.is_empty() {
|
if !these_stmts.is_empty() {
|
||||||
@ -797,13 +792,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?,
|
.parse()?,
|
||||||
);
|
);
|
||||||
@ -838,7 +830,7 @@ impl<'a> Parser<'a> {
|
|||||||
let mut val = self.parse_value_from_vec(cond.clone())?;
|
let mut val = self.parse_value_from_vec(cond.clone())?;
|
||||||
self.scopes.push(self.scopes.last().clone());
|
self.scopes.push(self.scopes.last().clone());
|
||||||
while val.node.is_true() {
|
while val.node.is_true() {
|
||||||
if self.in_function {
|
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||||
let these_stmts = Parser {
|
let these_stmts = Parser {
|
||||||
toks: &mut body.clone().into_iter().peekmore(),
|
toks: &mut body.clone().into_iter().peekmore(),
|
||||||
map: self.map,
|
map: self.map,
|
||||||
@ -848,13 +840,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
if !these_stmts.is_empty() {
|
if !these_stmts.is_empty() {
|
||||||
@ -871,13 +860,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?,
|
.parse()?,
|
||||||
);
|
);
|
||||||
@ -972,7 +958,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.in_function {
|
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||||
let these_stmts = Parser {
|
let these_stmts = Parser {
|
||||||
toks: &mut body.clone().into_iter().peekmore(),
|
toks: &mut body.clone().into_iter().peekmore(),
|
||||||
map: self.map,
|
map: self.map,
|
||||||
@ -982,13 +968,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
if !these_stmts.is_empty() {
|
if !these_stmts.is_empty() {
|
||||||
@ -1005,13 +988,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: true,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?,
|
.parse()?,
|
||||||
);
|
);
|
||||||
@ -1102,13 +1082,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: false,
|
at_root: false,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse_stmt()?;
|
.parse_stmt()?;
|
||||||
|
|
||||||
@ -1171,13 +1148,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: &mut NeverEmptyVec::new(at_rule_selector.clone()),
|
super_selectors: &mut NeverEmptyVec::new(at_rule_selector.clone()),
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: true,
|
at_root: true,
|
||||||
at_root_has_selector,
|
at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?
|
.parse()?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -1213,13 +1187,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse_selector(false, true, String::new())?;
|
.parse_selector(false, true, String::new())?;
|
||||||
|
|
||||||
@ -1292,13 +1263,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: false,
|
at_root: false,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse()?;
|
.parse()?;
|
||||||
|
|
||||||
|
@ -188,13 +188,10 @@ impl<'a> Parser<'a> {
|
|||||||
super_selectors: self.super_selectors,
|
super_selectors: self.super_selectors,
|
||||||
span_before: self.span_before,
|
span_before: self.span_before,
|
||||||
content: self.content,
|
content: self.content,
|
||||||
in_mixin: self.in_mixin,
|
flags: self.flags,
|
||||||
in_function: self.in_function,
|
|
||||||
in_control_flow: self.in_control_flow,
|
|
||||||
at_root: self.at_root,
|
at_root: self.at_root,
|
||||||
at_root_has_selector: self.at_root_has_selector,
|
at_root_has_selector: self.at_root_has_selector,
|
||||||
extender: self.extender,
|
extender: self.extender,
|
||||||
in_keyframes: self.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse_value()
|
.parse_value()
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ use crate::{
|
|||||||
Token,
|
Token,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::Parser;
|
use super::{Flags, Parser};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct VariableValue {
|
struct VariableValue {
|
||||||
@ -46,7 +46,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if value.default {
|
if value.default {
|
||||||
if self.at_root && !self.in_control_flow {
|
if self.at_root && !self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||||
if !self.global_scope.var_exists_no_global(&ident) {
|
if !self.global_scope.var_exists_no_global(&ident) {
|
||||||
self.global_scope.insert_var(ident, value.value);
|
self.global_scope.insert_var(ident, value.value);
|
||||||
}
|
}
|
||||||
@ -60,7 +60,7 @@ impl<'a> Parser<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if self.at_root {
|
} else if self.at_root {
|
||||||
if self.in_control_flow {
|
if self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||||
if self.global_scope.var_exists_no_global(&ident) {
|
if self.global_scope.var_exists_no_global(&ident) {
|
||||||
self.global_scope.insert_var(ident, value.value);
|
self.global_scope.insert_var(ident, value.value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -335,13 +335,10 @@ impl Value {
|
|||||||
super_selectors: parser.super_selectors,
|
super_selectors: parser.super_selectors,
|
||||||
span_before: parser.span_before,
|
span_before: parser.span_before,
|
||||||
content: parser.content,
|
content: parser.content,
|
||||||
in_mixin: parser.in_mixin,
|
flags: parser.flags,
|
||||||
in_function: parser.in_function,
|
|
||||||
in_control_flow: parser.in_control_flow,
|
|
||||||
at_root: parser.at_root,
|
at_root: parser.at_root,
|
||||||
at_root_has_selector: parser.at_root_has_selector,
|
at_root_has_selector: parser.at_root_has_selector,
|
||||||
extender: parser.extender,
|
extender: parser.extender,
|
||||||
in_keyframes: parser.in_keyframes,
|
|
||||||
}
|
}
|
||||||
.parse_selector(allows_parent, true, String::new())
|
.parse_selector(allows_parent, true, String::new())
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user