Normalize newlines in comments
This commit is contained in:
parent
f3787ef305
commit
a8ebc91702
27
src/lexer.rs
27
src/lexer.rs
@ -7,6 +7,9 @@ use crate::common::{Keyword, Op, Pos, Symbol};
|
|||||||
use crate::selector::{Attribute, AttributeKind, CaseKind};
|
use crate::selector::{Attribute, AttributeKind, CaseKind};
|
||||||
use crate::{Token, TokenKind, Whitespace};
|
use crate::{Token, TokenKind, Whitespace};
|
||||||
|
|
||||||
|
// Rust does not allow us to escape '\f'
|
||||||
|
const FORM_FEED: char = '\x0C';
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Lexer<'a> {
|
pub(crate) struct Lexer<'a> {
|
||||||
tokens: Vec<Token>,
|
tokens: Vec<Token>,
|
||||||
@ -51,7 +54,7 @@ impl<'a> Iterator for Lexer<'a> {
|
|||||||
'"' => symbol!(self, DoubleQuote),
|
'"' => symbol!(self, DoubleQuote),
|
||||||
' ' => whitespace!(self, Space),
|
' ' => whitespace!(self, Space),
|
||||||
'\t' => whitespace!(self, Tab),
|
'\t' => whitespace!(self, Tab),
|
||||||
'\n' | '\x0C' => {
|
'\n' | &FORM_FEED => {
|
||||||
self.buf.next();
|
self.buf.next();
|
||||||
self.pos.newline();
|
self.pos.newline();
|
||||||
TokenKind::Whitespace(Whitespace::Newline)
|
TokenKind::Whitespace(Whitespace::Newline)
|
||||||
@ -170,15 +173,27 @@ impl<'a> Lexer<'a> {
|
|||||||
self.pos.next_char();
|
self.pos.next_char();
|
||||||
let mut comment = String::new();
|
let mut comment = String::new();
|
||||||
while let Some(tok) = self.buf.next() {
|
while let Some(tok) = self.buf.next() {
|
||||||
if tok == '\n' {
|
match tok {
|
||||||
self.pos.newline()
|
'\n' => self.pos.newline(),
|
||||||
} else {
|
FORM_FEED => {
|
||||||
self.pos.next_char();
|
self.pos.newline();
|
||||||
|
comment.push('\n');
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
if tok == '*' && self.buf.peek() == Some(&'/') {
|
'\r' => {
|
||||||
|
if self.buf.peek() == Some(&'\n') {
|
||||||
|
self.buf.next();
|
||||||
|
}
|
||||||
|
self.pos.newline();
|
||||||
|
comment.push('\n');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
'*' if self.buf.peek() == Some(&'/') => {
|
||||||
self.buf.next();
|
self.buf.next();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
_ => self.pos.next_char(),
|
||||||
|
}
|
||||||
comment.push(tok);
|
comment.push(tok);
|
||||||
}
|
}
|
||||||
return TokenKind::MultilineComment(comment);
|
return TokenKind::MultilineComment(comment);
|
||||||
|
@ -345,6 +345,21 @@ mod test_comments {
|
|||||||
"// a { color: red }\na {\n height: 1 1px;\n}\n",
|
"// a { color: red }\na {\n height: 1 1px;\n}\n",
|
||||||
"a {\n height: 1 1px;\n}\n"
|
"a {\n height: 1 1px;\n}\n"
|
||||||
);
|
);
|
||||||
|
test!(
|
||||||
|
converts_form_feed_in_comment,
|
||||||
|
"a {\n /* \x0C*/ color: red;\n}\n",
|
||||||
|
"a {\n /* \n*/\n color: red;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
converts_crlf_in_comment,
|
||||||
|
"a {\n /* \r\n*/ color: red;\n}\n",
|
||||||
|
"a {\n /* \n*/\n color: red;\n}\n"
|
||||||
|
);
|
||||||
|
test!(
|
||||||
|
converts_cr_in_comment,
|
||||||
|
"a {\n /* \r*/ color: red;\n}\n",
|
||||||
|
"a {\n /* \n*/\n color: red;\n}\n"
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -699,6 +714,10 @@ mod test_values {
|
|||||||
test!(preserves_keyword_or, "a {\n color: or;\n}\n");
|
test!(preserves_keyword_or, "a {\n color: or;\n}\n");
|
||||||
test!(preserves_keyword_unset, "a {\n color: unset;\n}\n");
|
test!(preserves_keyword_unset, "a {\n color: unset;\n}\n");
|
||||||
test!(preserves_keyword_nan, "a {\n color: NaN;\n}\n");
|
test!(preserves_keyword_nan, "a {\n color: NaN;\n}\n");
|
||||||
|
test!(
|
||||||
|
preserves_quotes,
|
||||||
|
"a {\n color: \"'red' \\\"blue\\\"\";\n}\n"
|
||||||
|
);
|
||||||
test!(
|
test!(
|
||||||
whitespace_space_list_number,
|
whitespace_space_list_number,
|
||||||
"a {\n color: 1 2 3 ;\n}\n",
|
"a {\n color: 1 2 3 ;\n}\n",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user