feat(linter): no-irregular-whitespace rule (#1835)

Parser, trivias and trivias_builder were edited to get all whitespaces.
Now Trivias struct store comments and whitespaces Vec. After that, i
will implement the no-irregular-whitespace rule.

P.S.: There isn't a way to implement this feature without lose a little
bit of performance, comparing with my last PR #1819 to minimax this
trouble instead of store the irregular whitespace as Span it was stored
as u32, i removed a map iterator and removed too a unused function. If
you have a suggestion about it pls give me a feedback.
This commit is contained in:
Deivid Almeida 2023-12-31 01:05:38 -03:00 committed by GitHub
parent 36cb7c53c5
commit c1cfd1759e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 7 deletions

View file

@ -1,11 +1,14 @@
//! Trivias such as comments //! Trivias such as comments
use oxc_span::Span;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use oxc_span::Span;
/// A vec of trivias from the lexer, tupled by (span.start, span.end). /// A vec of trivias from the lexer, tupled by (span.start, span.end).
pub type Trivias = Vec<(u32, u32, CommentKind)>; #[derive(Debug, Default)]
pub struct Trivias {
pub comments: Vec<(u32, u32, CommentKind)>,
pub irregular_whitespaces: Vec<Span>,
}
/// Trivias such as comments /// Trivias such as comments
/// ///
@ -15,11 +18,15 @@ pub type Trivias = Vec<(u32, u32, CommentKind)>;
pub struct TriviasMap { pub struct TriviasMap {
/// Keyed by span.start /// Keyed by span.start
comments: BTreeMap<u32, Comment>, comments: BTreeMap<u32, Comment>,
irregular_whitespaces: Vec<Span>,
} }
impl From<Trivias> for TriviasMap { impl From<Trivias> for TriviasMap {
fn from(trivias: Trivias) -> Self { fn from(trivias: Trivias) -> Self {
Self { comments: trivias.iter().map(|t| (t.0, Comment::new(t.1, t.2))).collect() } Self {
comments: trivias.comments.iter().map(|t| (t.0, Comment::new(t.1, t.2))).collect(),
irregular_whitespaces: trivias.irregular_whitespaces,
}
} }
} }
@ -91,4 +98,8 @@ impl TriviasMap {
pub fn comments_spans(&self) -> impl Iterator<Item = (Comment, Span)> + '_ { pub fn comments_spans(&self) -> impl Iterator<Item = (Comment, Span)> + '_ {
self.comments().iter().map(|(start, comment)| (*comment, Span::new(*start, comment.end))) self.comments().iter().map(|(start, comment)| (*comment, Span::new(*start, comment.end)))
} }
pub fn irregular_whitespaces(&self) -> &Vec<Span> {
&self.irregular_whitespaces
}
} }

View file

@ -356,6 +356,8 @@ impl<'a> Lexer<'a> {
Kind::Ident Kind::Ident
} }
c if is_irregular_whitespace(c) => { c if is_irregular_whitespace(c) => {
self.trivia_builder
.add_irregular_whitespace(self.current.token.start, self.offset());
self.consume_char(); self.consume_char();
Kind::WhiteSpace Kind::WhiteSpace
} }
@ -389,6 +391,11 @@ impl<'a> Lexer<'a> {
Kind::Comment Kind::Comment
} }
/// Section 12.1 Irregular White Space
fn skip_irregular_whitespace(&mut self) -> Kind {
Kind::WhiteSpace
}
/// Section 12.4 Multi Line Comment /// Section 12.4 Multi Line Comment
fn skip_multi_line_comment(&mut self) -> Kind { fn skip_multi_line_comment(&mut self) -> Kind {
while let Some(c) = self.current.chars.next() { while let Some(c) = self.current.chars.next() {
@ -1319,6 +1326,7 @@ const ERR: ByteHandler = |lexer| {
// <TAB> <VT> <FF> // <TAB> <VT> <FF>
const SPS: ByteHandler = |lexer| { const SPS: ByteHandler = |lexer| {
lexer.skip_irregular_whitespace();
lexer.consume_char(); lexer.consume_char();
Kind::WhiteSpace Kind::WhiteSpace
}; };

View file

@ -1,4 +1,5 @@
use oxc_ast::{CommentKind, Trivias}; use oxc_ast::{CommentKind, Trivias};
use oxc_span::Span;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct TriviaBuilder { pub struct TriviaBuilder {
@ -12,11 +13,15 @@ impl TriviaBuilder {
/// skip leading `//` /// skip leading `//`
pub fn add_single_line_comment(&mut self, start: u32, end: u32) { pub fn add_single_line_comment(&mut self, start: u32, end: u32) {
self.trivias.push((start + 2, end, CommentKind::SingleLine)); self.trivias.comments.push((start + 2, end, CommentKind::SingleLine));
} }
/// skip leading `/*` and trailing `*/` /// skip leading `/*` and trailing `*/`
pub fn add_multi_line_comment(&mut self, start: u32, end: u32) { pub fn add_multi_line_comment(&mut self, start: u32, end: u32) {
self.trivias.push((start + 2, end - 2, CommentKind::MultiLine)); self.trivias.comments.push((start + 2, end - 2, CommentKind::MultiLine));
}
pub fn add_irregular_whitespace(&mut self, start: u32, end: u32) {
self.trivias.irregular_whitespaces.push(Span::new(start, end));
} }
} }

View file

@ -80,7 +80,7 @@ impl<'a> Prettier<'a> {
allocator, allocator,
source_text, source_text,
options, options,
trivias: trivias.into_iter().peekable(), trivias: trivias.comments.into_iter().peekable(),
nodes: vec![], nodes: vec![],
group_id_builder: GroupIdBuilder::default(), group_id_builder: GroupIdBuilder::default(),
args: PrettierArgs::default(), args: PrettierArgs::default(),