handle escaped @ else

this commit makes the assumption that
https://github.com/sass/dart-sass/issues/1011 is unintended behavior
and may need to be reverted should dart-sass decide it is intended
This commit is contained in:
ConnorSkees 2020-05-22 21:34:15 -04:00
parent c31684f8c7
commit b081fe780b
3 changed files with 40 additions and 44 deletions

View File

@ -8,8 +8,8 @@ use crate::error::SassResult;
use crate::scope::Scope; use crate::scope::Scope;
use crate::selector::Selector; use crate::selector::Selector;
use crate::utils::{ use crate::utils::{
devour_whitespace, devour_whitespace_or_comment, eat_ident, read_until_closing_curly_brace, devour_whitespace, devour_whitespace_or_comment, peek_ident_no_interpolation,
read_until_open_curly_brace, read_until_closing_curly_brace, read_until_open_curly_brace,
}; };
use crate::value::Value; use crate::value::Value;
use crate::{Stmt, Token}; use crate::{Stmt, Token};
@ -50,49 +50,40 @@ impl If {
let mut else_ = Vec::new(); let mut else_ = Vec::new();
loop { loop {
if toks.peek().is_some() { match toks.peek() {
if toks.peek().unwrap().kind == '@' { Some(Token { kind: '@', .. }) => {
let first_char = toks.peek_forward(1).unwrap().kind; toks.peek_forward(1);
toks.peek_backward(1).unwrap(); let mut ident = peek_ident_no_interpolation(toks, false)?;
if first_char != 'e' && first_char != 'E' { ident.node.make_ascii_lowercase();
if ident.as_str() != "else" {
toks.reset_view();
break; break;
} }
} else { toks.take(4).for_each(drop);
break;
} }
let span_before = toks.next().unwrap().pos; Some(..) | None => break,
if eat_ident(toks, &Scope::new(), &Selector::new(), span_before)? }
.to_ascii_lowercase() devour_whitespace(toks);
== "else" if let Some(tok) = toks.next() {
{ devour_whitespace(toks);
devour_whitespace(toks); match tok.kind.to_ascii_lowercase() {
if let Some(tok) = toks.next() { 'i' if toks.next().unwrap().kind.to_ascii_lowercase() == 'f' => {
toks.next();
let cond = read_until_open_curly_brace(toks);
toks.next();
devour_whitespace(toks); devour_whitespace(toks);
match tok.kind.to_ascii_lowercase() { branches.push(Branch::new(cond, read_until_closing_curly_brace(toks)));
'i' if toks.next().unwrap().kind.to_ascii_lowercase() == 'f' => { toks.next();
toks.next(); devour_whitespace(toks);
let cond = read_until_open_curly_brace(toks); }
toks.next(); '{' => {
devour_whitespace(toks); else_ = read_until_closing_curly_brace(toks);
branches toks.next();
.push(Branch::new(cond, read_until_closing_curly_brace(toks)));
toks.next();
devour_whitespace(toks);
}
'{' => {
else_ = read_until_closing_curly_brace(toks);
toks.next();
break;
}
_ => {
return Err(("expected \"{\".", tok.pos()).into());
}
}
} else {
break; break;
} }
} else { _ => {
break; return Err(("expected \"{\".", tok.pos()).into());
}
} }
} else { } else {
break; break;

View File

@ -88,3 +88,13 @@ test!(
"@if/* pre 1 */true/* post 1 */{ a { color: red; } }", "@if/* pre 1 */true/* post 1 */{ a { color: red; } }",
"a {\n color: red;\n}\n" "a {\n color: red;\n}\n"
); );
test!(
escaped_if,
"@\\69 f true {\n a {\n color: red;\n }\n}\n",
"a {\n color: red;\n}\n"
);
test!(
escaped_else,
"@if false {}\n\n@\\65lse {\n a {\n color: red;\n }\n}\n",
"a {\n color: red;\n}\n"
);

View File

@ -68,11 +68,6 @@ test!(
"a {\n color: #{foo}\\-;\n}\n", "a {\n color: #{foo}\\-;\n}\n",
"a {\n color: foo-;\n}\n" "a {\n color: foo-;\n}\n"
); );
test!(
escape_recognized_as_at_rule,
"@\\69 f true {\n a {\n b: c;\n }\n}\n",
"a {\n b: c;\n}\n"
);
test!( test!(
escape_in_middle, escape_in_middle,
"a {\n color: b\\6cue;\n}\n", "a {\n color: b\\6cue;\n}\n",