From a8ebc91702029a33065410552dae715e20127ab2 Mon Sep 17 00:00:00 2001 From: ConnorSkees <39542938+ConnorSkees@users.noreply.github.com> Date: Sun, 26 Jan 2020 16:50:08 -0500 Subject: [PATCH] Normalize newlines in comments --- src/lexer.rs | 33 ++++++++++++++++++++++++--------- tests/main.rs | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/lexer.rs b/src/lexer.rs index 8413c3b..df90cba 100644 --- a/src/lexer.rs +++ b/src/lexer.rs @@ -7,6 +7,9 @@ use crate::common::{Keyword, Op, Pos, Symbol}; use crate::selector::{Attribute, AttributeKind, CaseKind}; use crate::{Token, TokenKind, Whitespace}; +// Rust does not allow us to escape '\f' +const FORM_FEED: char = '\x0C'; + #[derive(Debug, Clone)] pub(crate) struct Lexer<'a> { tokens: Vec, @@ -51,7 +54,7 @@ impl<'a> Iterator for Lexer<'a> { '"' => symbol!(self, DoubleQuote), ' ' => whitespace!(self, Space), '\t' => whitespace!(self, Tab), - '\n' | '\x0C' => { + '\n' | &FORM_FEED => { self.buf.next(); self.pos.newline(); TokenKind::Whitespace(Whitespace::Newline) @@ -170,14 +173,26 @@ impl<'a> Lexer<'a> { self.pos.next_char(); let mut comment = String::new(); while let Some(tok) = self.buf.next() { - if tok == '\n' { - self.pos.newline() - } else { - self.pos.next_char(); - } - if tok == '*' && self.buf.peek() == Some(&'/') { - self.buf.next(); - break; + match tok { + '\n' => self.pos.newline(), + FORM_FEED => { + self.pos.newline(); + comment.push('\n'); + continue; + } + '\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(); + break; + } + _ => self.pos.next_char(), } comment.push(tok); } diff --git a/tests/main.rs b/tests/main.rs index 031e108..33f180a 100644 --- a/tests/main.rs +++ b/tests/main.rs @@ -345,6 +345,21 @@ mod test_comments { "// a { color: red }\na {\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)] @@ -699,6 +714,10 @@ mod test_values { test!(preserves_keyword_or, "a {\n color: or;\n}\n"); test!(preserves_keyword_unset, "a {\n color: unset;\n}\n"); test!(preserves_keyword_nan, "a {\n color: NaN;\n}\n"); + test!( + preserves_quotes, + "a {\n color: \"'red' \\\"blue\\\"\";\n}\n" + ); test!( whitespace_space_list_number, "a {\n color: 1 2 3 ;\n}\n",