remove dependency on bitflags
This commit is contained in:
parent
eec454c2d0
commit
92aa149f8a
@ -60,7 +60,6 @@ codemap = "0.1.3"
|
||||
peekmore = "0.5.2"
|
||||
wasm-bindgen = { version = "0.2.63", optional = true }
|
||||
beef = "0.4.4"
|
||||
bitflags = "1.2.1"
|
||||
# criterion is not a dev-dependency because it makes tests take too
|
||||
# long to compile, and you cannot make dev-dependencies optional
|
||||
criterion = { version = "0.3.2", optional = true }
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
args::CallArgs,
|
||||
common::QuoteKind,
|
||||
error::SassResult,
|
||||
parse::{Flags, Parser},
|
||||
parse::Parser,
|
||||
unit::Unit,
|
||||
value::{SassFunction, Value},
|
||||
};
|
||||
@ -232,7 +232,7 @@ fn call(mut args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
fn content_exists(args: CallArgs, parser: &mut Parser<'_>) -> SassResult<Value> {
|
||||
args.max_args(0)?;
|
||||
if !parser.flags.contains(Flags::IN_MIXIN) {
|
||||
if !parser.flags.in_mixin() {
|
||||
return Err((
|
||||
"content-exists() may only be called within a mixin.",
|
||||
parser.span_before,
|
||||
|
11
src/lib.rs
11
src/lib.rs
@ -94,7 +94,10 @@ pub(crate) use crate::token::Token;
|
||||
use crate::{
|
||||
lexer::Lexer,
|
||||
output::Css,
|
||||
parse::{common::NeverEmptyVec, Flags, Parser},
|
||||
parse::{
|
||||
common::{ContextFlags, NeverEmptyVec},
|
||||
Parser,
|
||||
},
|
||||
scope::Scope,
|
||||
selector::{Extender, Selector},
|
||||
};
|
||||
@ -149,7 +152,7 @@ pub fn from_path(p: &str) -> Result<String> {
|
||||
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
|
||||
span_before: empty_span,
|
||||
content: &mut Vec::new(),
|
||||
flags: Flags::empty(),
|
||||
flags: ContextFlags::empty(),
|
||||
at_root: true,
|
||||
at_root_has_selector: false,
|
||||
extender: &mut Extender::new(empty_span),
|
||||
@ -191,7 +194,7 @@ pub fn from_string(p: String) -> Result<String> {
|
||||
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
|
||||
span_before: empty_span,
|
||||
content: &mut Vec::new(),
|
||||
flags: Flags::empty(),
|
||||
flags: ContextFlags::empty(),
|
||||
at_root: true,
|
||||
at_root_has_selector: false,
|
||||
extender: &mut Extender::new(empty_span),
|
||||
@ -224,7 +227,7 @@ pub fn from_string(p: String) -> std::result::Result<String, JsValue> {
|
||||
super_selectors: &mut NeverEmptyVec::new(Selector::new(empty_span)),
|
||||
span_before: empty_span,
|
||||
content: &mut Vec::new(),
|
||||
flags: Flags::empty(),
|
||||
flags: ContextFlags::empty(),
|
||||
at_root: true,
|
||||
at_root_has_selector: false,
|
||||
extender: &mut Extender::new(empty_span),
|
||||
|
@ -1,4 +1,7 @@
|
||||
use std::slice::IterMut;
|
||||
use std::{
|
||||
ops::{BitAnd, BitOr},
|
||||
slice::IterMut,
|
||||
};
|
||||
|
||||
use codemap::Spanned;
|
||||
|
||||
@ -75,3 +78,50 @@ impl Branch {
|
||||
Branch { cond, toks }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) struct ContextFlags(u8);
|
||||
|
||||
pub(crate) struct ContextFlag(u8);
|
||||
|
||||
impl ContextFlags {
|
||||
pub const IN_MIXIN: ContextFlag = ContextFlag(1);
|
||||
pub const IN_FUNCTION: ContextFlag = ContextFlag(1 << 1);
|
||||
pub const IN_CONTROL_FLOW: ContextFlag = ContextFlag(1 << 2);
|
||||
pub const IN_KEYFRAMES: ContextFlag = ContextFlag(1 << 3);
|
||||
|
||||
pub const fn empty() -> Self {
|
||||
Self(0)
|
||||
}
|
||||
|
||||
pub fn in_mixin(self) -> bool {
|
||||
(self.0 & Self::IN_MIXIN) != 0
|
||||
}
|
||||
|
||||
pub fn in_function(self) -> bool {
|
||||
(self.0 & Self::IN_FUNCTION) != 0
|
||||
}
|
||||
|
||||
pub fn in_control_flow(self) -> bool {
|
||||
(self.0 & Self::IN_CONTROL_FLOW) != 0
|
||||
}
|
||||
|
||||
pub fn in_keyframes(self) -> bool {
|
||||
(self.0 & Self::IN_KEYFRAMES) != 0
|
||||
}
|
||||
}
|
||||
|
||||
impl BitAnd<ContextFlag> for u8 {
|
||||
type Output = Self;
|
||||
#[inline]
|
||||
fn bitand(self, rhs: ContextFlag) -> Self::Output {
|
||||
self & rhs.0
|
||||
}
|
||||
}
|
||||
|
||||
impl BitOr<ContextFlag> for ContextFlags {
|
||||
type Output = Self;
|
||||
fn bitor(self, rhs: ContextFlag) -> Self::Output {
|
||||
Self(self.0 | rhs.0)
|
||||
}
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
Token,
|
||||
};
|
||||
|
||||
use super::{Flags, NeverEmptyVec, Parser, Stmt};
|
||||
use super::{common::ContextFlags, NeverEmptyVec, Parser, Stmt};
|
||||
|
||||
/// Names that functions are not allowed to have
|
||||
const FORBIDDEN_IDENTIFIERS: [&str; 7] =
|
||||
@ -22,11 +22,11 @@ impl<'a> Parser<'a> {
|
||||
self.whitespace_or_comment();
|
||||
let Spanned { node: name, span } = self.parse_identifier()?;
|
||||
|
||||
if self.flags.contains(Flags::IN_MIXIN) {
|
||||
if self.flags.in_mixin() {
|
||||
return Err(("Mixins may not contain function declarations.", span).into());
|
||||
}
|
||||
|
||||
if self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||
if self.flags.in_control_flow() {
|
||||
return Err(("Functions may not be declared in control directives.", span).into());
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_FUNCTION,
|
||||
flags: self.flags | ContextFlags::IN_FUNCTION,
|
||||
at_root: false,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
Token,
|
||||
};
|
||||
|
||||
use super::{Flags, Parser};
|
||||
use super::{common::ContextFlags, Parser};
|
||||
|
||||
impl fmt::Display for KeyframesSelector {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
@ -189,7 +189,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_KEYFRAMES,
|
||||
flags: self.flags | ContextFlags::IN_KEYFRAMES,
|
||||
at_root: false,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
|
@ -10,7 +10,7 @@ use crate::{
|
||||
Token,
|
||||
};
|
||||
|
||||
use super::{Flags, NeverEmptyVec, Parser, Stmt};
|
||||
use super::{common::ContextFlags, NeverEmptyVec, Parser, Stmt};
|
||||
|
||||
impl<'a> Parser<'a> {
|
||||
pub(super) fn parse_mixin(&mut self) -> SassResult<()> {
|
||||
@ -127,7 +127,7 @@ impl<'a> Parser<'a> {
|
||||
global_scope: self.global_scope,
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
flags: self.flags | Flags::IN_MIXIN,
|
||||
flags: self.flags | ContextFlags::IN_MIXIN,
|
||||
content: self.content,
|
||||
at_root: false,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
@ -141,7 +141,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
pub(super) fn parse_content_rule(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
if self.flags.contains(Flags::IN_MIXIN) {
|
||||
if self.flags.in_mixin() {
|
||||
let mut scope = self
|
||||
.content
|
||||
.last()
|
||||
|
@ -26,7 +26,7 @@ use crate::{
|
||||
{Cow, Token},
|
||||
};
|
||||
|
||||
use common::{Branch, NeverEmptyVec, SelectorOrStyle};
|
||||
use common::{Branch, ContextFlags, NeverEmptyVec, SelectorOrStyle};
|
||||
|
||||
pub(crate) use value::{HigherIntermediateValue, ValueVisitor};
|
||||
|
||||
@ -66,17 +66,6 @@ pub(crate) enum Stmt {
|
||||
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
|
||||
/// much simpler to work with if it isn't generic. The performance
|
||||
/// hit (if there is one) is not important for now.
|
||||
@ -90,7 +79,7 @@ pub(crate) struct Parser<'a> {
|
||||
pub super_selectors: &'a mut NeverEmptyVec<Selector>,
|
||||
pub span_before: Span,
|
||||
pub content: &'a mut Vec<Content>,
|
||||
pub flags: Flags,
|
||||
pub flags: ContextFlags,
|
||||
/// Whether this parser is at the root of the document
|
||||
/// E.g. not inside a style, mixin, or function
|
||||
pub at_root: bool,
|
||||
@ -105,7 +94,7 @@ impl<'a> Parser<'a> {
|
||||
let mut stmts = Vec::new();
|
||||
while self.toks.peek().is_some() {
|
||||
stmts.append(&mut self.parse_stmt()?);
|
||||
if self.flags.contains(Flags::IN_FUNCTION) && !stmts.is_empty() {
|
||||
if self.flags.in_function() && !stmts.is_empty() {
|
||||
return Ok(stmts);
|
||||
}
|
||||
self.at_root = true;
|
||||
@ -116,7 +105,7 @@ impl<'a> Parser<'a> {
|
||||
fn parse_stmt(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
let mut stmts = Vec::new();
|
||||
while let Some(Token { kind, pos }) = self.toks.peek() {
|
||||
if self.flags.contains(Flags::IN_FUNCTION) && !stmts.is_empty() {
|
||||
if self.flags.in_function() && !stmts.is_empty() {
|
||||
return Ok(stmts);
|
||||
}
|
||||
self.span_before = *pos;
|
||||
@ -132,7 +121,7 @@ impl<'a> Parser<'a> {
|
||||
AtRuleKind::Include => stmts.append(&mut self.parse_include()?),
|
||||
AtRuleKind::Function => self.parse_function()?,
|
||||
AtRuleKind::Return => {
|
||||
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||
if self.flags.in_function() {
|
||||
return Ok(vec![Stmt::Return(self.parse_return()?)]);
|
||||
} else {
|
||||
return Err((
|
||||
@ -242,7 +231,7 @@ impl<'a> Parser<'a> {
|
||||
// dart-sass seems to special-case the error message here?
|
||||
'!' | '{' => return Err(("expected \"}\".", *pos).into()),
|
||||
_ => {
|
||||
if self.flags.contains(Flags::IN_KEYFRAMES) {
|
||||
if self.flags.in_keyframes() {
|
||||
match self.is_selector_or_style()? {
|
||||
SelectorOrStyle::Style(property, value) => {
|
||||
if let Some(value) = value {
|
||||
@ -611,7 +600,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -631,7 +620,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -762,7 +751,7 @@ impl<'a> Parser<'a> {
|
||||
span: var.span,
|
||||
},
|
||||
);
|
||||
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||
if self.flags.in_function() {
|
||||
let these_stmts = Parser {
|
||||
toks: &mut body.clone().into_iter().peekmore(),
|
||||
map: self.map,
|
||||
@ -772,7 +761,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -792,7 +781,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -830,7 +819,7 @@ impl<'a> Parser<'a> {
|
||||
let mut val = self.parse_value_from_vec(cond.clone())?;
|
||||
self.scopes.push(self.scopes.last().clone());
|
||||
while val.node.is_true() {
|
||||
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||
if self.flags.in_function() {
|
||||
let these_stmts = Parser {
|
||||
toks: &mut body.clone().into_iter().peekmore(),
|
||||
map: self.map,
|
||||
@ -840,7 +829,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -860,7 +849,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -958,7 +947,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
if self.flags.contains(Flags::IN_FUNCTION) {
|
||||
if self.flags.in_function() {
|
||||
let these_stmts = Parser {
|
||||
toks: &mut body.clone().into_iter().peekmore(),
|
||||
map: self.map,
|
||||
@ -968,7 +957,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
@ -988,7 +977,7 @@ impl<'a> Parser<'a> {
|
||||
super_selectors: self.super_selectors,
|
||||
span_before: self.span_before,
|
||||
content: self.content,
|
||||
flags: self.flags | Flags::IN_CONTROL_FLOW,
|
||||
flags: self.flags | ContextFlags::IN_CONTROL_FLOW,
|
||||
at_root: self.at_root,
|
||||
at_root_has_selector: self.at_root_has_selector,
|
||||
extender: self.extender,
|
||||
|
@ -11,7 +11,7 @@ use crate::{
|
||||
Token,
|
||||
};
|
||||
|
||||
use super::{Flags, Parser};
|
||||
use super::Parser;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct VariableValue {
|
||||
@ -46,7 +46,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
if value.default {
|
||||
if self.at_root && !self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||
if self.at_root && !self.flags.in_control_flow() {
|
||||
if !self.global_scope.var_exists_no_global(&ident) {
|
||||
self.global_scope.insert_var(ident, value.value);
|
||||
}
|
||||
@ -60,7 +60,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
} else if self.at_root {
|
||||
if self.flags.contains(Flags::IN_CONTROL_FLOW) {
|
||||
if self.flags.in_control_flow() {
|
||||
if self.global_scope.var_exists_no_global(&ident) {
|
||||
self.global_scope.insert_var(ident, value.value);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user