revert "make predicate optional for callers"

This reverts commit fda7f340cea60a90031aa8edffd8ab3a06d05992.

This commit made tests fail that it shouldn't have. The performance wins
from this change were negligible, so it is easiest to just revert it and
potentially come back to this change later
This commit is contained in:
Connor Skees 2020-08-08 14:36:59 -04:00
parent fda7f340ce
commit fb785cf71c
8 changed files with 107 additions and 134 deletions

View File

@ -184,31 +184,28 @@ impl<'a> Parser<'a> {
self.whitespace_or_comment();
let value = self.parse_value(
true,
Some(&|c| match c.peek() {
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
Some(Token { kind: '.', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
c.reset_cursor();
true
} else {
c.reset_cursor();
false
}
let value = self.parse_value(true, &|c| match c.peek() {
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
Some(Token { kind: '.', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
c.reset_cursor();
true
} else {
c.reset_cursor();
false
}
Some(Token { kind: '=', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '=', .. })) {
c.reset_cursor();
false
} else {
c.reset_cursor();
true
}
}
Some(Token { kind: '=', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '=', .. })) {
c.reset_cursor();
false
} else {
c.reset_cursor();
true
}
Some(..) | None => false,
}),
);
}
Some(..) | None => false,
});
match self.toks.peek() {
Some(Token { kind: ')', .. }) => {
@ -296,22 +293,19 @@ impl<'a> Parser<'a> {
self.toks.next();
let left = value?;
let right = self.parse_value(
true,
Some(&|c| match c.peek() {
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
Some(Token { kind: '.', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
c.reset_cursor();
true
} else {
c.reset_cursor();
false
}
let right = self.parse_value(true, &|c| match c.peek() {
Some(Token { kind: ')', .. }) | Some(Token { kind: ',', .. }) => true,
Some(Token { kind: '.', .. }) => {
if matches!(c.peek_next(), Some(Token { kind: '.', .. })) {
c.reset_cursor();
true
} else {
c.reset_cursor();
false
}
Some(..) | None => false,
}),
)?;
}
Some(..) | None => false,
})?;
let value_span = left.span.merge(right.span);
span = span.merge(value_span);

View File

@ -21,7 +21,7 @@ impl<'a> Parser<'a> {
let mut found_true = false;
let mut body = Vec::new();
let init_cond = self.parse_value(true, None)?.node;
let init_cond = self.parse_value(true, &|_| false)?.node;
self.expect_char('{')?;
@ -83,7 +83,7 @@ impl<'a> Parser<'a> {
self.throw_away_until_open_curly_brace()?;
false
} else {
let v = self.parse_value(true, None)?.node.is_true();
let v = self.parse_value(true, &|_| false)?.node.is_true();
self.expect_char('{')?;
v
};
@ -171,28 +171,25 @@ impl<'a> Parser<'a> {
}
self.whitespace_or_comment();
let from_val = self.parse_value(
false,
Some(&|toks| match toks.peek() {
Some(Token { kind: 't', pos })
| Some(Token { kind: 'T', pos })
| Some(Token { kind: '\\', pos }) => {
let span = *pos;
let mut ident = match peek_ident_no_interpolation(toks, false, span) {
Ok(s) => s,
Err(..) => return false,
};
ident.node.make_ascii_lowercase();
let v = match ident.node.to_ascii_lowercase().as_str() {
"to" | "through" => true,
_ => false,
};
toks.reset_cursor();
v
}
Some(..) | None => false,
}),
)?;
let from_val = self.parse_value(false, &|toks| match toks.peek() {
Some(Token { kind: 't', pos })
| Some(Token { kind: 'T', pos })
| Some(Token { kind: '\\', pos }) => {
let span = *pos;
let mut ident = match peek_ident_no_interpolation(toks, false, span) {
Ok(s) => s,
Err(..) => return false,
};
ident.node.make_ascii_lowercase();
let v = match ident.node.to_ascii_lowercase().as_str() {
"to" | "through" => true,
_ => false,
};
toks.reset_cursor();
v
}
Some(..) | None => false,
})?;
let through = if self.scan_identifier("through")? {
1
@ -219,7 +216,7 @@ impl<'a> Parser<'a> {
}
};
let to_val = self.parse_value(true, None)?;
let to_val = self.parse_value(true, &|_| false)?;
let to = match to_val.node {
Value::Dimension(Some(n), ..) => match n.to_i32() {
Some(std::i32::MAX) | Some(std::i32::MIN) | None => {

View File

@ -144,7 +144,7 @@ impl<'a> Parser<'a> {
let Spanned {
node: file_name_as_value,
span,
} = self.parse_value(true, None)?;
} = self.parse_value(true, &|_| false)?;
match file_name_as_value {
Value::String(s, QuoteKind::Quoted) => {

View File

@ -28,25 +28,22 @@ impl<'a> Parser<'a> {
}
pub fn expression_until_comparison(&mut self) -> SassResult<Cow<'static, str>> {
let value = self.parse_value(
false,
Some(&|toks| match toks.peek() {
Some(Token { kind: '>', .. })
| Some(Token { kind: '<', .. })
| Some(Token { kind: ':', .. })
| Some(Token { kind: ')', .. }) => true,
Some(Token { kind: '=', .. }) => {
if matches!(toks.peek_next(), Some(Token { kind: '=', .. })) {
toks.reset_cursor();
true
} else {
toks.reset_cursor();
false
}
let value = self.parse_value(false, &|toks| match toks.peek() {
Some(Token { kind: '>', .. })
| Some(Token { kind: '<', .. })
| Some(Token { kind: ':', .. })
| Some(Token { kind: ')', .. }) => true,
Some(Token { kind: '=', .. }) => {
if matches!(toks.peek_next(), Some(Token { kind: '=', .. })) {
toks.reset_cursor();
true
} else {
toks.reset_cursor();
false
}
_ => false,
}),
)?;
}
_ => false,
})?;
value.node.unquote().to_css_string(value.span)
}
@ -85,13 +82,10 @@ impl<'a> Parser<'a> {
buf.push(':');
buf.push(' ');
let value = self.parse_value(
false,
Some(&|toks| match toks.peek() {
Some(Token { kind: ')', .. }) => true,
_ => false,
}),
)?;
let value = self.parse_value(false, &|toks| match toks.peek() {
Some(Token { kind: ')', .. }) => true,
_ => false,
})?;
self.expect_char(')')?;
buf.push_str(&value.node.to_css_string(value.span)?);

View File

@ -191,7 +191,7 @@ impl<'a> Parser<'a> {
let Spanned {
node: message,
span,
} = self.parse_value(false, None)?;
} = self.parse_value(false, &|_| false)?;
return Err((
message.inspect(span)?.to_string(),
@ -203,7 +203,7 @@ impl<'a> Parser<'a> {
let Spanned {
node: message,
span,
} = self.parse_value(false, None)?;
} = self.parse_value(false, &|_| false)?;
span.merge(kind_string.span);
if let Some(Token { kind: ';', pos }) = self.toks.peek() {
kind_string.span.merge(*pos);
@ -218,7 +218,7 @@ impl<'a> Parser<'a> {
let Spanned {
node: message,
span,
} = self.parse_value(false, None)?;
} = self.parse_value(false, &|_| false)?;
span.merge(kind_string.span);
if let Some(Token { kind: ';', pos }) = self.toks.peek() {
kind_string.span.merge(*pos);
@ -521,7 +521,7 @@ impl<'a> Parser<'a> {
}
pub fn parse_interpolation(&mut self) -> SassResult<Spanned<Value>> {
let val = self.parse_value(true, None)?;
let val = self.parse_value(true, &|_| false)?;
self.span_before = val.span;

View File

@ -68,13 +68,10 @@ impl<'a> Parser<'a> {
self.expect_char(':')?;
self.whitespace_or_comment();
let value = self.parse_value(
false,
Some(&|toks| match toks.peek() {
Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. }) => true,
_ => false,
}),
)?;
let value = self.parse_value(false, &|toks| match toks.peek() {
Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. }) => true,
_ => false,
})?;
config.insert(name.map_node(|n| n.into()), value)?;

View File

@ -192,7 +192,7 @@ impl<'a> Parser<'a> {
}
fn parse_style_value(&mut self) -> SassResult<Spanned<Value>> {
self.parse_value(false, None)
self.parse_value(false, &|_| false)
}
pub(super) fn parse_style_group(

View File

@ -53,7 +53,7 @@ impl<'a> Parser<'a> {
pub(crate) fn parse_value(
&mut self,
in_paren: bool,
predicate: Option<&dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
) -> SassResult<Spanned<Value>> {
self.whitespace();
@ -65,16 +65,14 @@ impl<'a> Parser<'a> {
Some(Token { pos, .. }) => *pos,
};
if let Some(predicate) = predicate {
if predicate(self.toks) {
return Err(("Expected expression.", span).into());
}
if predicate(self.toks) {
return Err(("Expected expression.", span).into());
}
let mut last_was_whitespace = false;
let mut space_separated = Vec::new();
let mut comma_separated = Vec::new();
let mut iter = IntermediateValueIterator::new(self, predicate);
let mut iter = IntermediateValueIterator::new(self, &predicate);
while let Some(val) = iter.next() {
let val = val?;
match val.node {
@ -192,7 +190,7 @@ impl<'a> Parser<'a> {
modules: self.modules,
module_config: self.module_config,
}
.parse_value(in_paren, None)
.parse_value(in_paren, &|_| false)
}
#[allow(clippy::eval_order_dependence)]
@ -236,7 +234,7 @@ impl<'a> Parser<'a> {
fn parse_ident_value(
&mut self,
predicate: Option<&dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
) -> SassResult<Spanned<IntermediateValue>> {
let Spanned { node: mut s, span } = self.parse_identifier()?;
@ -317,11 +315,9 @@ impl<'a> Parser<'a> {
.span(span));
}
Some(Token { kind: '.', .. }) => {
if let Some(predicate) = predicate {
if !predicate(self.toks) {
self.toks.next();
return self.parse_module_item(&s, span);
}
if !predicate(self.toks) {
self.toks.next();
return self.parse_module_item(&s, span);
}
}
_ => {}
@ -360,12 +356,12 @@ impl<'a> Parser<'a> {
fn parse_number(
&mut self,
predicate: Option<&dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
) -> SassResult<Spanned<ParsedNumber>> {
let mut span = self.toks.peek().unwrap().pos;
let mut whole = eat_whole_number(self.toks);
if self.toks.peek().is_none() || predicate.map_or(false, |p| p(self.toks)) {
if self.toks.peek().is_none() || predicate(self.toks) {
return Ok(Spanned {
node: ParsedNumber::new(whole, 0, String::new(), true),
span,
@ -445,7 +441,7 @@ impl<'a> Parser<'a> {
let mut map = SassMap::new();
let key = self.parse_value(
true,
Some(&|c| matches!(c.peek(), Some(Token { kind: ':', .. }) | Some(Token { kind: ')', .. }))),
&|c| matches!(c.peek(), Some(Token { kind: ':', .. }) | Some(Token { kind: ')', .. })),
)?;
match self.toks.next() {
@ -461,7 +457,7 @@ impl<'a> Parser<'a> {
let val = self.parse_value(
true,
Some(&|c| matches!(c.peek(), Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. }))),
&|c| matches!(c.peek(), Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. })),
)?;
map.insert(key.node, val.node);
@ -495,16 +491,14 @@ impl<'a> Parser<'a> {
}
loop {
let key = self.parse_value(
true,
Some(&|c| matches!(c.peek(), Some(Token { kind: ':', .. }))),
)?;
let key =
self.parse_value(true, &|c| matches!(c.peek(), Some(Token { kind: ':', .. })))?;
self.expect_char(':')?;
self.whitespace_or_comment();
let val =
self.parse_value(true, Some(&|c| matches!(c.peek(), Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. }))))?;
self.parse_value(true, &|c| matches!(c.peek(), Some(Token { kind: ',', .. }) | Some(Token { kind: ')', .. })))?;
span = span.merge(val.span);
@ -533,12 +527,10 @@ impl<'a> Parser<'a> {
fn parse_intermediate_value(
&mut self,
predicate: Option<&dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
) -> Option<SassResult<Spanned<IntermediateValue>>> {
if let Some(predicate) = predicate {
if predicate(self.toks) {
return None;
}
if predicate(self.toks) {
return None;
}
let (kind, span) = match self.toks.peek() {
Some(v) => (v.kind, v.pos()),
@ -713,10 +705,9 @@ impl<'a> Parser<'a> {
.span(span)
} else {
// todo: we don't know if we're `in_paren` here
let inner = match self.parse_value(
false,
Some(&|toks| matches!(toks.peek(), Some(Token { kind: ']', .. }))),
) {
let inner = match self.parse_value(false, &|toks| {
matches!(toks.peek(), Some(Token { kind: ']', .. }))
}) {
Ok(v) => v,
Err(e) => return Some(Err(e)),
};
@ -923,7 +914,7 @@ impl<'a> Parser<'a> {
struct IntermediateValueIterator<'a, 'b: 'a> {
parser: &'a mut Parser<'b>,
peek: Option<SassResult<Spanned<IntermediateValue>>>,
predicate: Option<&'a dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &'a dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
}
impl<'a, 'b: 'a> Iterator for IntermediateValueIterator<'a, 'b> {
@ -940,7 +931,7 @@ impl<'a, 'b: 'a> Iterator for IntermediateValueIterator<'a, 'b> {
impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
pub fn new(
parser: &'a mut Parser<'b>,
predicate: Option<&'a dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool>,
predicate: &'a dyn Fn(&mut PeekMoreIterator<IntoIter<Token>>) -> bool,
) -> Self {
Self {
parser,