use new predicate parsing for bracketed lists
This commit is contained in:
parent
b2e7270681
commit
df1456f9b1
@ -15,8 +15,7 @@ use crate::{
|
|||||||
error::SassResult,
|
error::SassResult,
|
||||||
unit::Unit,
|
unit::Unit,
|
||||||
utils::{
|
utils::{
|
||||||
devour_whitespace, eat_whole_number, read_until_closing_paren,
|
devour_whitespace, eat_whole_number, read_until_closing_paren, IsWhitespace, ParsedNumber,
|
||||||
read_until_closing_square_brace, IsWhitespace, ParsedNumber,
|
|
||||||
},
|
},
|
||||||
value::{Number, SassFunction, SassMap, Value},
|
value::{Number, SassFunction, SassMap, Value},
|
||||||
Token,
|
Token,
|
||||||
@ -30,7 +29,6 @@ use super::super::Parser;
|
|||||||
enum IntermediateValue {
|
enum IntermediateValue {
|
||||||
Value(HigherIntermediateValue),
|
Value(HigherIntermediateValue),
|
||||||
Op(Op),
|
Op(Op),
|
||||||
Bracketed(Vec<Token>),
|
|
||||||
Paren(Vec<Token>),
|
Paren(Vec<Token>),
|
||||||
Comma,
|
Comma,
|
||||||
Whitespace,
|
Whitespace,
|
||||||
@ -127,22 +125,6 @@ impl<'a> Parser<'a> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
IntermediateValue::Bracketed(t) => {
|
|
||||||
last_was_whitespace = false;
|
|
||||||
space_separated.push(
|
|
||||||
HigherIntermediateValue::Literal(
|
|
||||||
match iter.parser.parse_value_from_vec(t, in_paren)?.node {
|
|
||||||
Value::List(v, sep, Brackets::None) => {
|
|
||||||
Value::List(v, sep, Brackets::Bracketed)
|
|
||||||
}
|
|
||||||
v => {
|
|
||||||
Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.span(val.span),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
IntermediateValue::Paren(t) => {
|
IntermediateValue::Paren(t) => {
|
||||||
last_was_whitespace = false;
|
last_was_whitespace = false;
|
||||||
space_separated.push(iter.parse_paren(Spanned {
|
space_separated.push(iter.parse_paren(Spanned {
|
||||||
@ -608,28 +590,42 @@ impl<'a> Parser<'a> {
|
|||||||
.span(span_start.merge(span))
|
.span(span_start.merge(span))
|
||||||
}
|
}
|
||||||
'[' => {
|
'[' => {
|
||||||
let mut span = self.toks.next().unwrap().pos();
|
let mut span = self.span_before;
|
||||||
|
self.toks.next();
|
||||||
self.whitespace_or_comment();
|
self.whitespace_or_comment();
|
||||||
let mut inner = match read_until_closing_square_brace(self.toks) {
|
|
||||||
Ok(v) => v,
|
if let Some(Token { kind: ']', pos }) = self.toks.peek() {
|
||||||
Err(e) => return Some(Err(e)),
|
span = span.merge(*pos);
|
||||||
};
|
self.toks.next();
|
||||||
if let Some(last_tok) = inner.pop() {
|
|
||||||
if last_tok.kind != ']' {
|
|
||||||
return Some(Err(("expected \"]\".", span).into()));
|
|
||||||
}
|
|
||||||
span = span.merge(last_tok.pos());
|
|
||||||
}
|
|
||||||
if inner.is_empty() {
|
|
||||||
IntermediateValue::Value(HigherIntermediateValue::Literal(Value::List(
|
IntermediateValue::Value(HigherIntermediateValue::Literal(Value::List(
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
ListSeparator::Space,
|
ListSeparator::Space,
|
||||||
Brackets::Bracketed,
|
Brackets::Bracketed,
|
||||||
)))
|
)))
|
||||||
|
.span(span)
|
||||||
} else {
|
} else {
|
||||||
IntermediateValue::Bracketed(inner)
|
// todo: we don't know if we're `in_paren` here
|
||||||
|
let inner = match self.parse_value(false, &|toks| {
|
||||||
|
matches!(toks.peek(), Some(Token { kind: ']', .. }))
|
||||||
|
}) {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(e) => return Some(Err(e)),
|
||||||
|
};
|
||||||
|
|
||||||
|
span = span.merge(inner.span);
|
||||||
|
|
||||||
|
if !matches!(self.toks.next(), Some(Token { kind: ']', .. })) {
|
||||||
|
return Some(Err(("expected \"]\".", span).into()));
|
||||||
|
}
|
||||||
|
|
||||||
|
IntermediateValue::Value(HigherIntermediateValue::Literal(match inner.node {
|
||||||
|
Value::List(els, sep, Brackets::None) => {
|
||||||
|
Value::List(els, sep, Brackets::Bracketed)
|
||||||
|
}
|
||||||
|
v => Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed),
|
||||||
|
}))
|
||||||
|
.span(span)
|
||||||
}
|
}
|
||||||
.span(span)
|
|
||||||
}
|
}
|
||||||
'$' => {
|
'$' => {
|
||||||
self.toks.next();
|
self.toks.next();
|
||||||
@ -1131,14 +1127,6 @@ impl<'a, 'b: 'a> IntermediateValueIterator<'a, 'b> {
|
|||||||
IntermediateValue::Comma => {
|
IntermediateValue::Comma => {
|
||||||
return Err(("Expected expression.", self.parser.span_before).into())
|
return Err(("Expected expression.", self.parser.span_before).into())
|
||||||
}
|
}
|
||||||
IntermediateValue::Bracketed(t) => {
|
|
||||||
let v = self.parser.parse_value_from_vec(t, in_paren)?;
|
|
||||||
HigherIntermediateValue::Literal(match v.node {
|
|
||||||
Value::List(v, sep, Brackets::None) => Value::List(v, sep, Brackets::Bracketed),
|
|
||||||
v => Value::List(vec![v], ListSeparator::Space, Brackets::Bracketed),
|
|
||||||
})
|
|
||||||
.span(v.span)
|
|
||||||
}
|
|
||||||
IntermediateValue::Paren(t) => {
|
IntermediateValue::Paren(t) => {
|
||||||
let val = self.parse_paren(Spanned {
|
let val = self.parse_paren(Spanned {
|
||||||
node: t,
|
node: t,
|
||||||
|
@ -235,39 +235,3 @@ pub(crate) fn read_until_closing_paren(
|
|||||||
}
|
}
|
||||||
Ok(t)
|
Ok(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn read_until_closing_square_brace(
|
|
||||||
toks: &mut PeekMoreIterator<IntoIter<Token>>,
|
|
||||||
) -> SassResult<Vec<Token>> {
|
|
||||||
let mut t = Vec::new();
|
|
||||||
let mut scope = 0;
|
|
||||||
while let Some(tok) = toks.next() {
|
|
||||||
// TODO: comments
|
|
||||||
match tok.kind {
|
|
||||||
']' => {
|
|
||||||
if scope < 1 {
|
|
||||||
t.push(tok);
|
|
||||||
return Ok(t);
|
|
||||||
} else {
|
|
||||||
scope -= 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
'[' => scope += 1,
|
|
||||||
'"' | '\'' => {
|
|
||||||
t.push(tok);
|
|
||||||
t.extend(read_until_closing_quote(toks, tok.kind)?);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
'\\' => {
|
|
||||||
t.push(tok);
|
|
||||||
t.push(match toks.next() {
|
|
||||||
Some(tok) => tok,
|
|
||||||
None => continue,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
t.push(tok)
|
|
||||||
}
|
|
||||||
Ok(t)
|
|
||||||
}
|
|
||||||
|
@ -251,5 +251,5 @@ error!(
|
|||||||
);
|
);
|
||||||
error!(
|
error!(
|
||||||
nothing_after_escape_inside_brackets,
|
nothing_after_escape_inside_brackets,
|
||||||
"a { color: [\\", "Error: expected \"]\"."
|
"a { color: [\\", "Error: Expected expression."
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user