mirror of
https://github.com/danbulant/oxc
synced 2026-05-24 12:21:58 +00:00
feat(prettier): implement is_next_line_empty_after_index (#1575)
This commit is contained in:
parent
a9f0206805
commit
7236368d5a
5 changed files with 60 additions and 39 deletions
|
|
@ -74,7 +74,7 @@ impl<'a> Prettier<'a> {
|
|||
}
|
||||
|
||||
if self
|
||||
.skip_spaces(comment.end, false)
|
||||
.skip_spaces(Some(comment.end), false)
|
||||
.and_then(|idx| self.skip_newline(Some(idx), false))
|
||||
.is_some_and(|i| self.has_newline(i, /* backwards */ false))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ impl<'a> Format<'a> for Program<'a> {
|
|||
let mut parts = p.vec();
|
||||
if let Some(hashbang) = &self.hashbang {
|
||||
parts.push(hashbang.format(p));
|
||||
if p.is_next_line_empty(hashbang.span.end - 1) {
|
||||
if p.is_next_line_empty_after_index(hashbang.span.end - 1) {
|
||||
parts.extend(hardline!());
|
||||
}
|
||||
}
|
||||
|
|
@ -427,7 +427,7 @@ impl<'a> Format<'a> for SwitchStatement<'a> {
|
|||
parts.push(format!(p, case));
|
||||
Doc::Indent(parts)
|
||||
});
|
||||
if i != len - 1 && p.is_next_line_empty(case.span.end) {
|
||||
if i != len - 1 && p.is_next_line_empty(case.span) {
|
||||
cases_parts.extend(hardline!());
|
||||
}
|
||||
}
|
||||
|
|
@ -467,7 +467,7 @@ impl<'a> Format<'a> for SwitchCase<'a> {
|
|||
|
||||
if i != 0 && matches!(stmt, Statement::BreakStatement(_)) {
|
||||
let last_stmt = &consequent[i - 1];
|
||||
if p.is_next_line_empty(last_stmt.span().end) {
|
||||
if p.is_next_line_empty(last_stmt.span()) {
|
||||
consequent_parts.extend(hardline!());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ pub(super) fn print_statement_sequence<'a>(
|
|||
if i < len - 1 {
|
||||
parts.extend(hardline!());
|
||||
|
||||
if p.is_next_line_empty(stmt.span().end) {
|
||||
if p.is_next_line_empty(stmt.span()) {
|
||||
parts.extend(hardline!());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,12 +14,12 @@ mod printer;
|
|||
|
||||
use std::{iter::Peekable, vec};
|
||||
|
||||
use doc::DocBuilder;
|
||||
use oxc_allocator::Allocator;
|
||||
use oxc_ast::{ast::Program, AstKind, CommentKind, Trivias};
|
||||
use oxc_span::Span;
|
||||
use oxc_syntax::identifier::is_line_terminator;
|
||||
|
||||
use crate::{doc::Doc, format::Format, printer::Printer};
|
||||
use crate::{doc::Doc, doc::DocBuilder, format::Format, printer::Printer};
|
||||
|
||||
pub use crate::options::{ArrowParens, EndOfLine, PrettierOptions, QuoteProps, TrailingComma};
|
||||
|
||||
|
|
@ -135,8 +135,55 @@ impl<'a> Prettier<'a> {
|
|||
trailing_comma.is_all() || (trailing_comma.is_es5() && !level_all)
|
||||
}
|
||||
|
||||
fn is_next_line_empty(&self, end: u32) -> bool {
|
||||
self.source_text[end as usize..].chars().nth(1).is_some_and(|c| c == '\n')
|
||||
fn is_next_line_empty(&self, span: Span) -> bool {
|
||||
self.is_next_line_empty_after_index(span.end)
|
||||
}
|
||||
|
||||
fn is_next_line_empty_after_index(&self, start_index: u32) -> bool {
|
||||
let mut old_idx = None;
|
||||
let mut idx = Some(start_index);
|
||||
while idx != old_idx {
|
||||
old_idx = idx;
|
||||
idx = self.skip_to_line_end(idx);
|
||||
// idx = self.skip_inline_comment(idx);
|
||||
idx = self.skip_spaces(idx, /* backwards */ false);
|
||||
}
|
||||
// idx = self.skip_trailing_comment(idx);
|
||||
idx = self.skip_newline(idx, /* backwards */ false);
|
||||
idx.is_some_and(|idx| self.has_newline(idx, /* backwards */ false))
|
||||
// self.source_text[end as usize..].chars().nth(1).is_some_and(|c| c == '\n')
|
||||
}
|
||||
|
||||
fn skip_to_line_end(&self, start_index: Option<u32>) -> Option<u32> {
|
||||
self.skip(start_index, false, |c| matches!(c, ' ' | '\t' | ',' | ';'))
|
||||
}
|
||||
|
||||
fn skip_spaces(&self, start_index: Option<u32>, backwards: bool) -> Option<u32> {
|
||||
self.skip(start_index, backwards, |c| matches!(c, ' ' | '\t'))
|
||||
}
|
||||
|
||||
fn skip<F>(&self, start_index: Option<u32>, backwards: bool, f: F) -> Option<u32>
|
||||
where
|
||||
F: Fn(char) -> bool,
|
||||
{
|
||||
let start_index = start_index?;
|
||||
let mut index = start_index;
|
||||
if backwards {
|
||||
for c in self.source_text[..=start_index as usize].chars().rev() {
|
||||
if !f(c) {
|
||||
return Some(index);
|
||||
}
|
||||
index -= 1_u32;
|
||||
}
|
||||
} else {
|
||||
for c in self.source_text[start_index as usize..].chars() {
|
||||
if !f(c) {
|
||||
return Some(index);
|
||||
}
|
||||
index += 1_u32;
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_possible_truncation)]
|
||||
|
|
@ -154,26 +201,6 @@ impl<'a> Prettier<'a> {
|
|||
Some(start_index)
|
||||
}
|
||||
|
||||
fn skip_spaces(&self, start_index: u32, backwards: bool) -> Option<u32> {
|
||||
let mut index = start_index;
|
||||
if backwards {
|
||||
for c in self.source_text[..=start_index as usize].chars().rev() {
|
||||
if !matches!(c, ' ' | '\t') {
|
||||
return Some(index);
|
||||
}
|
||||
index -= 1_u32;
|
||||
}
|
||||
} else {
|
||||
for c in self.source_text[start_index as usize..].chars() {
|
||||
if !matches!(c, ' ' | '\t') {
|
||||
return Some(index);
|
||||
}
|
||||
index += 1_u32;
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn has_newline(&self, start_index: u32, backwards: bool) -> bool {
|
||||
if (backwards && start_index == 0)
|
||||
|| (!backwards && start_index as usize == self.source_text.len())
|
||||
|
|
@ -181,15 +208,15 @@ impl<'a> Prettier<'a> {
|
|||
return false;
|
||||
}
|
||||
let start_index = if backwards { start_index - 1 } else { start_index };
|
||||
let idx = self.skip_spaces(start_index, backwards);
|
||||
let idx = self.skip_spaces(Some(start_index), backwards);
|
||||
let idx2 = self.skip_newline(idx, backwards);
|
||||
idx != idx2
|
||||
}
|
||||
|
||||
fn is_previous_line_empty(&self, start_index: u32) -> bool {
|
||||
let idx = start_index - 1;
|
||||
let idx = self.skip_spaces(idx, true);
|
||||
let Some(idx) = self.skip_newline(idx, true) else { return false };
|
||||
let idx = self.skip_spaces(Some(idx), true);
|
||||
let idx = self.skip_newline(idx, true);
|
||||
let idx = self.skip_spaces(idx, true);
|
||||
let idx2 = self.skip_newline(idx, true);
|
||||
idx != idx2
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Compatibility: 194/580 (33.45%)
|
||||
Compatibility: 196/580 (33.79%)
|
||||
|
||||
# Failed
|
||||
|
||||
|
|
@ -124,9 +124,6 @@ Compatibility: 194/580 (33.45%)
|
|||
* class-extends/extends.js
|
||||
* class-extends/tuple-and-record.js
|
||||
|
||||
### class-static-block
|
||||
* class-static-block/class-static-block.js
|
||||
|
||||
### classes
|
||||
* classes/assignment.js
|
||||
* classes/empty.js
|
||||
|
|
@ -300,9 +297,6 @@ Compatibility: 194/580 (33.45%)
|
|||
* functional-composition/reselect_createselector.js
|
||||
* functional-composition/rxjs_pipe.js
|
||||
|
||||
### generator
|
||||
* generator/anonymous.js
|
||||
|
||||
### identifier/for-of
|
||||
* identifier/for-of/await.js
|
||||
* identifier/for-of/let.js
|
||||
|
|
|
|||
Loading…
Reference in a new issue