more robustly parse !optional in selectors

This commit is contained in:
Connor Skees 2020-08-07 13:40:22 -04:00
parent 36a55e582c
commit 38a37a3997
4 changed files with 26 additions and 10 deletions

View File

@ -7,7 +7,7 @@ use crate::{
use super::Parser;
impl<'a> Parser<'a> {
pub fn scan_identifier(&mut self, ident: &str) -> SassResult<bool> {
pub fn scan_identifier(&mut self, ident: &'static str) -> SassResult<bool> {
let peeked_identifier =
match peek_ident_no_interpolation(self.toks, false, self.span_before) {
Ok(v) => v.node,

View File

@ -17,10 +17,7 @@ use crate::{
ComplexSelectorComponent, ExtendRule, ExtendedSelector, Extender, Selector, SelectorParser,
},
style::Style,
utils::{
peek_ident_no_interpolation, read_until_closing_curly_brace,
read_until_semicolon_or_closing_curly_brace,
},
utils::{read_until_closing_curly_brace, read_until_semicolon_or_closing_curly_brace},
value::Value,
Options, {Cow, Token},
};
@ -134,6 +131,16 @@ impl<'a> Parser<'a> {
false
}
pub fn expect_identifier(&mut self, ident: &'static str) -> SassResult<()> {
let this_ident = self.parse_identifier_no_interpolation(false)?;
self.span_before = this_ident.span;
if this_ident.node == ident {
return Ok(());
}
Err((format!("Expected \"{}\".", ident), self.span_before).into())
}
fn parse_stmt(&mut self) -> SassResult<Vec<Stmt>> {
let mut stmts = Vec::new();
while let Some(Token { kind, pos }) = self.toks.peek() {
@ -420,13 +427,11 @@ impl<'a> Parser<'a> {
}
}
'!' => {
if peek_ident_no_interpolation(self.toks, false, self.span_before)?.node
== "optional"
{
self.toks.truncate_iterator_to_cursor();
if from_fn {
self.expect_identifier("optional")?;
optional = true;
} else {
string.push('!');
return Err(("expected \"{\".", tok.pos).into());
}
}
c => string.push(c),

View File

@ -1882,6 +1882,13 @@ test!(
}",
":has(a >) b, :has(a >) :has(a >) :has(a >) b, :has(a >) :has(a >) :has(a >) b {\n color: red;\n}\n"
);
error!(
extend_optional_keyword_not_complete,
"a {
@extend a !opt;
}",
"Error: Expected \"optional\"."
);
// todo: extend_loop (massive test)
// todo: extend tests in folders

View File

@ -712,3 +712,7 @@ error!(
toplevel_parent_selector_after_element,
"a&{}", "Error: \"&\" may only used at the beginning of a compound selector."
);
error!(
denies_optional_in_selector,
"a !optional {}", "Error: expected \"{\"."
);