Skip to content

Commit 963b87f

Browse files
committed
perf(formatter): add text_without_whitespace for text that can never have whitespace (#15403)
1 parent f30ce4b commit 963b87f

File tree

7 files changed

+24
-28
lines changed

7 files changed

+24
-28
lines changed

crates/oxc_formatter/src/formatter/builders.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use Tag::{
77
StartLabelled, StartLineSuffix,
88
};
99
use oxc_span::{GetSpan, Span};
10-
use oxc_syntax::identifier::{is_line_terminator, is_white_space_single_line};
10+
use oxc_syntax::identifier::{is_identifier_name, is_line_terminator, is_white_space_single_line};
1111

1212
use super::{
1313
Argument, Arguments, Buffer, Comments, GroupId, TextSize, VecBuffer,
@@ -302,21 +302,13 @@ pub fn text(text: &str) -> Text<'_> {
302302
Text { text, width: None }
303303
}
304304

305-
/// Creates a text from a dynamic string and a known width, for example,
306-
/// identifiers or numbers that do not contain line breaks.
307-
pub fn text_with_width(text: &str, width: TextWidth) -> Text<'_> {
308-
if width.is_multiline() {
309-
debug_assert!(
310-
text.as_bytes().iter().any(|&b| matches!(b, b'\n' | b'\t')),
311-
"Text with a known multiline width must contain at least one whitespace character. Found invalid content: '{text}'"
312-
);
313-
} else {
314-
debug_assert!(
315-
!text.as_bytes().iter().any(|&b| matches!(b, b'\n' | b'\t')),
316-
"Text with a known width must not contain whitespace characters when the width is single line. Found invalid content: '{text}'"
317-
);
318-
}
319-
Text { text, width: Some(width) }
305+
/// Creates a text from a dynamic string that contains no whitespace characters
306+
pub fn text_without_whitespace(text: &str) -> Text<'_> {
307+
debug_assert!(
308+
text.as_bytes().iter().all(|&b| !b.is_ascii_whitespace()),
309+
"The content '{text}' contains whitespace characters but text must not contain any whitespace characters."
310+
);
311+
Text { text, width: Some(TextWidth::from_non_whitespace_str(text)) }
320312
}
321313

322314
#[derive(Eq, PartialEq)]

crates/oxc_formatter/src/formatter/format_element/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::hash::{Hash, Hasher};
77
use std::num::NonZeroU32;
88
use std::{borrow::Cow, ops::Deref, rc::Rc};
99

10-
use unicode_width::UnicodeWidthChar;
10+
use unicode_width::{UnicodeWidthChar, UnicodeWidthStr};
1111

1212
use crate::{IndentWidth, TabWidth};
1313

@@ -420,6 +420,11 @@ impl TextWidth {
420420
Self::Width(Width::new(width))
421421
}
422422

423+
pub fn from_non_whitespace_str(name: &str) -> TextWidth {
424+
#[expect(clippy::cast_possible_truncation)]
425+
Self::Width(Width::new(name.width() as u32))
426+
}
427+
423428
pub fn from_len(len: usize) -> TextWidth {
424429
#[expect(clippy::cast_possible_truncation)]
425430
TextWidth::Width(Width::new(len as u32))

crates/oxc_formatter/src/formatter/token/number.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ pub struct CleanedNumberLiteralText<'a> {
4141
impl<'a> Format<'a> for CleanedNumberLiteralText<'a> {
4242
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
4343
let text = format_trimmed_number(self.text, self.options);
44-
let width = TextWidth::from_len(text.len());
45-
text_with_width(f.context().allocator().alloc_str(&text), width).fmt(f)
44+
text_without_whitespace(f.context().allocator().alloc_str(&text)).fmt(f)
4645
}
4746
}
4847

crates/oxc_formatter/src/utils/jsx.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,7 @@ impl<'a> JsxWord<'a> {
246246

247247
impl<'a> Format<'a> for JsxWord<'a> {
248248
fn fmt(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
249-
write!(f, [text(self.text)])
249+
write!(f, [text_without_whitespace(self.text)])
250250
}
251251
}
252252

crates/oxc_formatter/src/write/class.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, PropertyDefinition<'a>> {
130130

131131
impl<'a> FormatWrite<'a> for AstNode<'a, PrivateIdentifier<'a>> {
132132
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
133-
write!(f, ["#", text(self.name().as_str())])
133+
write!(f, ["#", text_without_whitespace(self.name().as_str())])
134134
}
135135
}
136136

@@ -214,7 +214,7 @@ impl<'a> Format<'a> for AstNode<'a, Vec<'a, TSIndexSignatureName<'a>>> {
214214

215215
impl<'a> FormatWrite<'a> for AstNode<'a, TSIndexSignatureName<'a>> {
216216
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
217-
write!(f, [text(self.name().as_str()), self.type_annotation()])
217+
write!(f, [text_without_whitespace(self.name().as_str()), self.type_annotation()])
218218
}
219219
}
220220

crates/oxc_formatter/src/write/jsx/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, JSXSpreadAttribute<'a>> {
337337

338338
impl<'a> FormatWrite<'a> for AstNode<'a, JSXIdentifier<'a>> {
339339
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
340-
write!(f, text(self.name().as_str()))
340+
write!(f, text_without_whitespace(self.name().as_str()))
341341
}
342342
}
343343

crates/oxc_formatter/src/write/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -103,25 +103,25 @@ pub trait FormatWrite<'ast, T = ()> {
103103

104104
impl<'a> FormatWrite<'a> for AstNode<'a, IdentifierName<'a>> {
105105
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
106-
write!(f, text(self.name().as_str()))
106+
write!(f, text_without_whitespace(self.name().as_str()))
107107
}
108108
}
109109

110110
impl<'a> FormatWrite<'a> for AstNode<'a, IdentifierReference<'a>> {
111111
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
112-
write!(f, text(self.name().as_str()))
112+
write!(f, text_without_whitespace(self.name().as_str()))
113113
}
114114
}
115115

116116
impl<'a> FormatWrite<'a> for AstNode<'a, BindingIdentifier<'a>> {
117117
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
118-
write!(f, text(self.name().as_str()))
118+
write!(f, text_without_whitespace(self.name().as_str()))
119119
}
120120
}
121121

122122
impl<'a> FormatWrite<'a> for AstNode<'a, LabelIdentifier<'a>> {
123123
fn write(&self, f: &mut Formatter<'_, 'a>) -> FormatResult<()> {
124-
write!(f, text(self.name().as_str()))
124+
write!(f, text_without_whitespace(self.name().as_str()))
125125
}
126126
}
127127

@@ -1095,7 +1095,7 @@ impl<'a> FormatWrite<'a> for AstNode<'a, RegExpLiteral<'a>> {
10951095
flags.sort_unstable();
10961096
let flags = flags.iter().collect::<String>();
10971097
let s = StringBuilder::from_strs_array_in([pattern, "/", &flags], f.context().allocator());
1098-
write!(f, text(s.into_str(),))
1098+
write!(f, text(s.into_str()))
10991099
}
11001100
}
11011101

0 commit comments

Comments
 (0)