Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 18 additions & 44 deletions crates/oxc_formatter/src/formatter/builders.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::{backtrace, borrow::Cow, cell::Cell, num::NonZeroU8};
use std::{backtrace, cell::Cell, num::NonZeroU8};

use Tag::{
EndAlign, EndConditionalContent, EndDedent, EndEntry, EndFill, EndGroup, EndIndent,
Expand Down Expand Up @@ -302,6 +302,23 @@ pub fn text(text: &str) -> Text<'_> {
Text { text, width: None }
}

/// Creates a text from a dynamic string and a known width, for example,
/// identifiers or numbers that do not contain line breaks.
pub fn text_with_width(text: &str, width: TextWidth) -> Text<'_> {
if width.is_multiline() {
debug_assert!(
text.as_bytes().iter().any(|&b| matches!(b, b'\n' | b'\t')),
"Text with a known multiline width must contain at least one whitespace character. Found invalid content: '{text}'"
);
} else {
debug_assert!(
!text.as_bytes().iter().any(|&b| matches!(b, b'\n' | b'\t')),
"Text with a known width must not contain whitespace characters when the width is single line. Found invalid content: '{text}'"
);
}
Text { text, width: Some(width) }
}

#[derive(Eq, PartialEq)]
pub struct Text<'a> {
text: &'a str,
Expand All @@ -325,49 +342,6 @@ impl std::fmt::Debug for Text<'_> {
}
}

/// String that is the same as in the input source text if `text` is [`Cow::Borrowed`] or
/// some replaced content if `text` is [`Cow::Owned`].
pub fn syntax_token_cow_slice(text: Cow<'_, str>, span: Span) -> SyntaxTokenCowSlice<'_> {
debug_assert_no_newlines(&text);
SyntaxTokenCowSlice { text, span }
}

pub struct SyntaxTokenCowSlice<'a> {
text: Cow<'a, str>,
span: Span,
}

impl<'a> Format<'a> for SyntaxTokenCowSlice<'a> {
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
match &self.text {
Cow::Borrowed(content) => {
// let range = TextRange::at(self.start, text.text_len());
// debug_assert_eq!(
// *text,
// &self.token.token()[range - self.token.text_range().start()],
// "The borrowed string doesn't match the specified token substring. Does the borrowed string belong to this token and range?"
// );

// let relative_range = range - self.token.text_range().start();
// let slice = self.token.token_text().slice(relative_range);

text(f.source_text().text_for(&self.span)).fmt(f)
}
Cow::Owned(text) => f.write_element(FormatElement::Text {
// TODO: Should use arena String to replace Cow::Owned.
text: f.context().allocator().alloc_str(text),
width: TextWidth::from_text(text, f.options().indent_width),
}),
}
}
}

impl std::fmt::Debug for SyntaxTokenCowSlice<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::write!(f, "SyntaxTokenCowSlice({})", self.text)
}
}

#[track_caller]
fn debug_assert_no_newlines(text: &str) {
debug_assert!(
Expand Down
5 changes: 5 additions & 0 deletions crates/oxc_formatter/src/formatter/format_element/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,11 @@ impl TextWidth {
Self::Width(Width::new(width))
}

pub fn from_len(len: usize) -> TextWidth {
#[expect(clippy::cast_possible_truncation)]
TextWidth::Width(Width::new(len as u32))
}

pub const fn width(self) -> Option<Width> {
match self {
TextWidth::Width(width) => Some(width),
Expand Down
4 changes: 3 additions & 1 deletion crates/oxc_formatter/src/formatter/token/number.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@ pub struct CleanedNumberLiteralText<'a> {

impl<'a> Format<'a> for CleanedNumberLiteralText<'a> {
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
syntax_token_cow_slice(format_trimmed_number(self.text, self.options), self.span).fmt(f)
let text = format_trimmed_number(self.text, self.options);
let width = TextWidth::from_len(text.len());
text_with_width(f.context().allocator().alloc_str(&text), width).fmt(f)
}
}

Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_formatter/src/utils/assignment_like.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use crate::{
},
};

use super::string_utils::{FormatLiteralStringToken, StringLiteralParentKind};
use super::string::{FormatLiteralStringToken, StringLiteralParentKind};

#[derive(Clone, Copy)]
pub enum AssignmentLike<'a, 'b> {
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_formatter/src/utils/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod jsx;
pub mod member_chain;
pub mod object;
pub mod statement_body;
pub mod string_utils;
pub mod string;
pub mod suppressed;
pub mod typecast;
pub mod typescript;
Expand Down
2 changes: 1 addition & 1 deletion crates/oxc_formatter/src/utils/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use crate::{
Buffer, Format, FormatResult,
ast_nodes::{AstNode, AstNodes},
formatter::Formatter,
utils::string_utils::{FormatLiteralStringToken, StringLiteralParentKind},
utils::string::{FormatLiteralStringToken, StringLiteralParentKind},
write,
};

Expand Down
Loading
Loading