Parse styles not ending in semicolons

This commit is contained in:
ConnorSkees 2020-01-20 18:09:25 -05:00
parent 6242ff8417
commit a7ca888942

View File

@ -244,7 +244,7 @@ impl StyleSheet {
/// Used mainly in debugging, but can at times be useful /// Used mainly in debugging, but can at times be useful
#[inline] #[inline]
#[allow(dead_code)] #[allow(dead_code)]
fn pretty_print<W: Write>(&self, buf: W) -> SassResult<()> { pub fn pretty_print<W: Write>(&self, buf: W) -> SassResult<()> {
PrettyPrinter::new(buf).pretty_print(self) PrettyPrinter::new(buf).pretty_print(self)
} }
@ -409,10 +409,10 @@ impl<'a> StyleSheetParser<'a> {
fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> { fn eat_rules(&mut self, super_selector: &Selector, scope: &mut Scope) -> Vec<Stmt> {
let mut stmts = Vec::new(); let mut stmts = Vec::new();
while let Some(tok) = eat_expr(&mut self.lexer, scope, super_selector) while let Some(expr) = eat_expr(&mut self.lexer, scope, super_selector)
.unwrap_or_else(|error| self.error(error.0, &error.1)) .unwrap_or_else(|error| self.error(error.0, &error.1))
{ {
match tok { match expr {
Expr::Style(s) => stmts.push(Stmt::Style(s)), Expr::Style(s) => stmts.push(Stmt::Style(s)),
Expr::MixinDecl(name, mixin) => { Expr::MixinDecl(name, mixin) => {
scope.mixins.insert(name, mixin); scope.mixins.insert(name, mixin);
@ -499,7 +499,7 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
let mut values = Vec::with_capacity(5); let mut values = Vec::with_capacity(5);
while let Some(tok) = toks.peek() { while let Some(tok) = toks.peek() {
match &tok.kind { match &tok.kind {
TokenKind::Symbol(Symbol::SemiColon) | TokenKind::Symbol(Symbol::CloseCurlyBrace) => { TokenKind::Symbol(Symbol::SemiColon) => {
toks.next(); toks.next();
devour_whitespace(toks); devour_whitespace(toks);
return Ok(Some(Expr::Style(match Style::from_tokens(values, scope) { return Ok(Some(Expr::Style(match Style::from_tokens(values, scope) {
@ -507,6 +507,17 @@ pub(crate) fn eat_expr<I: Iterator<Item = Token>>(
Err(_) => return Ok(None), Err(_) => return Ok(None),
}))); })));
} }
TokenKind::Symbol(Symbol::CloseCurlyBrace) => {
if values.is_empty() {
toks.next();
devour_whitespace(toks);
return Ok(None);
}
return Ok(Some(Expr::Style(match Style::from_tokens(values, scope) {
Ok(x) => x,
Err(_) => return Ok(None),
})));
}
TokenKind::Symbol(Symbol::OpenCurlyBrace) => { TokenKind::Symbol(Symbol::OpenCurlyBrace) => {
toks.next(); toks.next();
devour_whitespace(toks); devour_whitespace(toks);
@ -972,6 +983,11 @@ mod test_styles {
two_rulesets, two_rulesets,
"a {\n color: red;\n}\nc {\n color: white;\n}\n" "a {\n color: red;\n}\nc {\n color: white;\n}\n"
); );
test!(
two_rulesets_first_no_semicolon,
"a {\n color: red\n}\nc {\n color: white;\n}\n",
"a {\n color: red;\n}\nc {\n color: white;\n}\n"
);
test!( test!(
two_inner_outer_rulesets, two_inner_outer_rulesets,
"a {\n b {\n color: red;\n}\n c {\n color: white;\n}\n}\na {\n b {\n color: red;\n}\n c {\n color: white;\n}\n}\n", "a {\n b {\n color: red;\n}\n c {\n color: white;\n}\n}\na {\n b {\n color: red;\n}\n c {\n color: white;\n}\n}\n",