allow multiline comments in more contexts
This commit is contained in:
parent
484409761d
commit
d5b2410a8c
@ -155,8 +155,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
pub(super) fn parse_for(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
// todo: whitespace or comment
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
// todo: test for error here
|
||||
self.expect_char('$')?;
|
||||
|
||||
@ -164,7 +163,7 @@ impl<'a> Parser<'a> {
|
||||
.parse_identifier_no_interpolation(false)?
|
||||
.map_node(|n| n.into());
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
self.span_before = match self.toks.peek() {
|
||||
Some(tok) => tok.pos,
|
||||
None => return Err(("Expected \"from\".", var.span).into()),
|
||||
@ -172,7 +171,7 @@ impl<'a> Parser<'a> {
|
||||
if self.parse_identifier()?.node.to_ascii_lowercase() != "from" {
|
||||
return Err(("Expected \"from\".", var.span).into());
|
||||
}
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
let mut from_toks = Vec::new();
|
||||
let mut through = 0;
|
||||
while let Some(tok) = self.toks.peek().cloned() {
|
||||
@ -234,7 +233,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
let from_val = self.parse_value_from_vec(from_toks, true)?;
|
||||
let from = match from_val.node {
|
||||
Value::Dimension(Some(n), ..) => match n.to_integer().to_isize() {
|
||||
@ -272,8 +271,6 @@ impl<'a> Parser<'a> {
|
||||
let body = read_until_closing_curly_brace(self.toks)?;
|
||||
self.toks.next();
|
||||
|
||||
self.whitespace();
|
||||
|
||||
let (mut x, mut y);
|
||||
// we can't use an inclusive range here
|
||||
#[allow(clippy::range_plus_one)]
|
||||
@ -348,7 +345,10 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
pub(super) fn parse_while(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
self.whitespace();
|
||||
// technically not necessary to eat whitespace here, but since we
|
||||
// operate on raw tokens rather than an AST, it potentially saves a lot of
|
||||
// time in re-parsing
|
||||
self.whitespace_or_comment();
|
||||
let cond = read_until_open_curly_brace(self.toks)?;
|
||||
|
||||
if cond.is_empty() {
|
||||
@ -364,8 +364,6 @@ impl<'a> Parser<'a> {
|
||||
None => return Err(("expected \"}\".", self.span_before).into()),
|
||||
});
|
||||
|
||||
self.whitespace();
|
||||
|
||||
let mut stmts = Vec::new();
|
||||
let mut val = self.parse_value_from_vec(cond.clone(), true)?;
|
||||
self.scopes.enter_new_scope();
|
||||
@ -424,16 +422,15 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
pub(super) fn parse_each(&mut self) -> SassResult<Vec<Stmt>> {
|
||||
self.whitespace();
|
||||
let mut vars: Vec<Spanned<Identifier>> = Vec::new();
|
||||
|
||||
self.whitespace_or_comment();
|
||||
loop {
|
||||
self.expect_char('$')?;
|
||||
|
||||
vars.push(self.parse_identifier()?.map_node(|i| i.into()));
|
||||
|
||||
// todo: whitespace or comment
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
if self
|
||||
.toks
|
||||
.peek()
|
||||
@ -442,7 +439,7 @@ impl<'a> Parser<'a> {
|
||||
== ','
|
||||
{
|
||||
self.toks.next();
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -451,7 +448,7 @@ impl<'a> Parser<'a> {
|
||||
if i.node.to_ascii_lowercase() != "in" {
|
||||
return Err(("Expected \"in\".", i.span).into());
|
||||
}
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
let iter_val_toks = read_until_open_curly_brace(self.toks)?;
|
||||
let iter = self
|
||||
.parse_value_from_vec(iter_val_toks, true)?
|
||||
|
@ -121,7 +121,7 @@ impl<'a> Parser<'a> {
|
||||
return Err(("This at-rule is not allowed here.", self.span_before).into());
|
||||
}
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
match self.toks.peek() {
|
||||
Some(Token { kind: '\'', .. })
|
||||
|
@ -35,6 +35,7 @@ impl<'a> Parser<'a> {
|
||||
false
|
||||
}
|
||||
|
||||
// todo: replace with predicate
|
||||
pub fn expression_until_comparison(&mut self) -> SassResult<Cow<'static, str>> {
|
||||
let mut toks = Vec::new();
|
||||
while let Some(tok) = self.toks.peek().cloned() {
|
||||
@ -71,7 +72,7 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn parse_media_query_list(&mut self) -> SassResult<String> {
|
||||
let mut buf = String::new();
|
||||
loop {
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
buf.push_str(&self.parse_single_media_query()?);
|
||||
if !self.scan_char(',') {
|
||||
break;
|
||||
@ -94,13 +95,13 @@ impl<'a> Parser<'a> {
|
||||
let mut buf = String::with_capacity(2);
|
||||
self.expect_char('(')?;
|
||||
buf.push('(');
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
buf.push_str(&self.expression_until_comparison()?);
|
||||
|
||||
if let Some(Token { kind: ':', .. }) = self.toks.peek() {
|
||||
self.toks.next();
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
buf.push(':');
|
||||
buf.push(' ');
|
||||
@ -112,7 +113,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
buf.push_str(&self.parse_value_as_string_from_vec(toks, true)?);
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
buf.push(')');
|
||||
return Ok(buf);
|
||||
} else {
|
||||
@ -127,14 +128,14 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
buf.push(' ');
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
buf.push_str(&self.expression_until_comparison()?);
|
||||
}
|
||||
}
|
||||
|
||||
self.expect_char(')')?;
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
buf.push(')');
|
||||
Ok(buf)
|
||||
}
|
||||
@ -145,7 +146,7 @@ impl<'a> Parser<'a> {
|
||||
if !matches!(self.toks.peek(), Some(Token { kind: '(', .. })) {
|
||||
buf.push_str(&self.parse_identifier()?);
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
if let Some(tok) = self.toks.peek() {
|
||||
if !is_name_start(tok.kind) {
|
||||
@ -156,7 +157,7 @@ impl<'a> Parser<'a> {
|
||||
buf.push(' ');
|
||||
let ident = self.parse_identifier()?;
|
||||
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
if ident.to_ascii_lowercase() == "and" {
|
||||
buf.push_str("and ");
|
||||
@ -164,7 +165,7 @@ impl<'a> Parser<'a> {
|
||||
buf.push_str(&ident);
|
||||
|
||||
if self.scan_identifier("and")? {
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
buf.push_str(" and ");
|
||||
} else {
|
||||
return Ok(buf);
|
||||
@ -173,9 +174,9 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
loop {
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
buf.push_str(&self.parse_media_feature()?);
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
if !self.scan_identifier("and")? {
|
||||
break;
|
||||
}
|
||||
|
@ -616,7 +616,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
let mut params = String::new();
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
if let Some(Token { kind: ';', .. }) | None = self.toks.peek() {
|
||||
self.toks.next();
|
||||
return Ok(Stmt::UnknownAtRule(Box::new(UnknownAtRule {
|
||||
|
@ -109,7 +109,7 @@ impl<'a> Parser<'a> {
|
||||
}
|
||||
|
||||
let mut property = self.parse_identifier()?.node;
|
||||
let whitespace_after_property = self.whitespace();
|
||||
let whitespace_after_property = self.whitespace_or_comment();
|
||||
|
||||
match self.toks.peek() {
|
||||
Some(Token { kind: ':', .. }) => {
|
||||
|
@ -28,7 +28,7 @@ impl<'a> Parser<'a> {
|
||||
pub(super) fn parse_variable_declaration(&mut self) -> SassResult<()> {
|
||||
assert!(matches!(self.toks.next(), Some(Token { kind: '$', .. })));
|
||||
let ident: Identifier = self.parse_identifier_no_interpolation(false)?.node.into();
|
||||
self.whitespace();
|
||||
self.whitespace_or_comment();
|
||||
|
||||
self.expect_char(':')?;
|
||||
|
||||
|
@ -77,6 +77,17 @@ test!(
|
||||
}",
|
||||
"a {\n color: a;\n color: b;\n color: 1;\n color: b;\n}\n"
|
||||
);
|
||||
// todo: newlines are not correct
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
" /**/ @each /**/ $a /**/ , /**/ $b /**/ in /**/ ( /**/ a /**/ , /**/ b /**/ ) /**/ { /**/
|
||||
a {
|
||||
color: $a;
|
||||
color: $b;
|
||||
}
|
||||
} /**/ ",
|
||||
"/**/\n/**/\na {\n color: a;\n}\n/**/\n\na {\n color: b;\n}\n/**/\n"
|
||||
);
|
||||
error!(
|
||||
list_of_single_map,
|
||||
"a {
|
||||
|
@ -113,3 +113,8 @@ test!(
|
||||
}",
|
||||
"a {\n color: 1;\n color: 2;\n color: 1;\n color: 2;\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
" /**/ @for /**/ $i /**/ from /**/ 0 /**/ to /**/ 2 /**/ {} /**/ ",
|
||||
"/**/\n/**/\n"
|
||||
);
|
||||
|
10
tests/if.rs
10
tests/if.rs
@ -163,6 +163,16 @@ test!(
|
||||
}",
|
||||
"a {\n a: \\}}}{{{#;\n b: \\}}}{{{#;\n c: \\}}}{{{#;\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
" /**/ @if /**/ false /**/ {} /**/
|
||||
/**/
|
||||
/**/ @else /**/ if /**/ false /**/ {} /**/
|
||||
/**/
|
||||
/**/ @else /**/ {} /**/
|
||||
/**/ ",
|
||||
"/**/\n/**/\n/**/\n"
|
||||
);
|
||||
error!(
|
||||
nothing_after_escape,
|
||||
"@if \\", "Error: Expected expression."
|
||||
|
@ -188,6 +188,11 @@ test!(
|
||||
"@import url(#{1+1}..);",
|
||||
"@import url(2..);\n"
|
||||
);
|
||||
test!(
|
||||
import_multiline_comments_everywhere,
|
||||
" /**/ @import /**/ url(foo) /**/ ;",
|
||||
"/**/\n@import url(foo);\n"
|
||||
);
|
||||
|
||||
// todo: test for calling paths, e.g. `grass b\index.scss`
|
||||
// todo: test for absolute paths (how?)
|
||||
|
@ -63,3 +63,12 @@ test!(
|
||||
}",
|
||||
"@media screen and (:) {\n a {\n color: red;\n }\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
"@media/**/foo/**/and/**/(/**/bar/**/)/**/{
|
||||
a {
|
||||
color: red;
|
||||
}
|
||||
}",
|
||||
"@media foo and (bar) {\n a {\n color: red;\n }\n}\n"
|
||||
);
|
||||
|
@ -170,3 +170,8 @@ test!(
|
||||
"a {\n color: unquote(\"foo \");\n}\n",
|
||||
"a {\n color: foo ;\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comment_after_style_property,
|
||||
"a {\n color /**/ : red;\n}\n",
|
||||
"a {\n color: red;\n}\n"
|
||||
);
|
||||
|
@ -29,3 +29,4 @@ test!(
|
||||
}",
|
||||
"@foo (a: b) {\n a {\n color: red;\n }\n}\na {\n color: green;\n}\n"
|
||||
);
|
||||
test!(contains_multiline_comment, "@foo /**/;\n", "@foo;\n");
|
||||
|
@ -149,6 +149,11 @@ test!(
|
||||
}",
|
||||
"a {\n color: red;\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
" /**/ $a /**/ : /**/ red /**/ ; /**/ ",
|
||||
"/**/\n/**/\n"
|
||||
);
|
||||
// https://github.com/Kixiron/lasso/issues/7
|
||||
test!(
|
||||
regression_test_for_lasso_0_3_0,
|
||||
|
@ -125,6 +125,11 @@ test!(
|
||||
}",
|
||||
"a {\n color: red;\n}\n\na {\n color: blue;\n}\n"
|
||||
);
|
||||
test!(
|
||||
multiline_comments_everywhere,
|
||||
" /**/ @while /**/ false /**/ {} /**/ ",
|
||||
"/**/\n/**/\n"
|
||||
);
|
||||
error!(
|
||||
missing_closing_curly_brace,
|
||||
"@while true {", "Error: expected \"}\"."
|
||||
|
Loading…
x
Reference in New Issue
Block a user