Thanks to visit codestin.com
Credit goes to github.com

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
11 changes: 11 additions & 0 deletions .changeset/lemon-planes-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@biomejs/biome": patch
---

Refactored formatter to use strict `Token` element for better performance. The new `Token` variant is optimized for static, ASCII-only text (keywords, operators, punctuation) with the following constraints:

- ASCII only (no Unicode characters)
- No newlines (`\n`, `\r`)
- No tab characters (`\t`)

This enables faster printing and fitting logic by using bulk string operations (`push_str`, `len()`) instead of character-by-character iteration with Unicode width calculations.
7 changes: 2 additions & 5 deletions crates/biome_css_formatter/src/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ impl FormatRule<SourceComment<CssLanguage>> for FormatCssLeadingComment {

// SAFETY: Safe, `is_doc_comment` only returns `true` for multiline comments
let first_line = lines.next().unwrap();
write!(f, [dynamic_text(first_line.trim_end(), source_offset)])?;
write!(f, [text(first_line.trim_end(), source_offset)])?;

source_offset += first_line.text_len();

Expand All @@ -44,10 +44,7 @@ impl FormatRule<SourceComment<CssLanguage>> for FormatCssLeadingComment {
1,
&format_once(|f| {
for line in lines {
write!(
f,
[hard_line_break(), dynamic_text(line.trim(), source_offset)]
)?;
write!(f, [hard_line_break(), text(line.trim(), source_offset)])?;

source_offset += line.text_len();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ impl FormatNodeRule<CssDeclarationWithSemicolon> for FormatCssDeclarationWithSem
// if semicolon is present, use the token's format to keep the comments
write!(f, [semicolon_token.format()])
} else {
write!(f, [text(";")])
write!(f, [token(";")])
}
}
}
4 changes: 2 additions & 2 deletions crates/biome_css_formatter/src/css/value/url_value_raw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@ impl FormatNodeRule<CssUrlValueRaw> for FormatCssUrlValueRaw {
fn fmt_fields(&self, node: &CssUrlValueRaw, f: &mut CssFormatter) -> FormatResult<()> {
let CssUrlValueRawFields { value_token } = node.as_fields();
let value_token = value_token?;
let text = value_token.token_text();
let token_text = value_token.token_text();
write!(
f,
[format_replaced(
&value_token,
&dynamic_text(text.trim(), value_token.text_trimmed_range().start())
&text(token_text.trim(), value_token.text_trimmed_range().start())
)]
)
}
Expand Down
7 changes: 3 additions & 4 deletions crates/biome_css_formatter/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,10 +316,9 @@ impl FormatRule<CssSyntaxToken> for FormatCssSyntaxToken {
let original = token.text_trimmed();
match original.to_ascii_lowercase_cow() {
Cow::Borrowed(_) => self.format_trimmed_token_trivia(token, f),
Cow::Owned(lowercase) => write!(
f,
[dynamic_text(&lowercase, token.text_trimmed_range().start())]
),
Cow::Owned(lowercase) => {
write!(f, [text(&lowercase, token.text_trimmed_range().start())])
}
}
} else {
self.format_trimmed_token_trivia(token, f)
Expand Down
4 changes: 2 additions & 2 deletions crates/biome_css_formatter/src/utils/string_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use biome_formatter::QuoteStyle;
use biome_formatter::token::string::normalize_string;
use biome_formatter::{
Format, FormatResult,
prelude::{dynamic_text, write},
prelude::{text, write},
};
use biome_rowan::SyntaxToken;
use biome_string_case::StrLikeExtension;
Expand All @@ -35,7 +35,7 @@ impl Format<CssFormatContext> for FormatTokenAsLowercase {
f,
[format_replaced(
&self.token,
&dynamic_text(&lowercase, self.token.text_trimmed_range().start()),
&text(&lowercase, self.token.text_trimmed_range().start()),
)]
),
}
Expand Down
4 changes: 2 additions & 2 deletions crates/biome_css_formatter/src/verbatim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use crate::context::CssFormatContext;
use biome_css_syntax::{CssLanguage, CssSyntaxNode};
use biome_formatter::format_element::tag::VerbatimKind;
use biome_formatter::formatter::Formatter;
use biome_formatter::prelude::{Tag, dynamic_text};
use biome_formatter::prelude::{Tag, text};
use biome_formatter::trivia::{FormatLeadingComments, FormatTrailingComments};
use biome_formatter::{
Buffer, CstFormatContext, Format, FormatContext, FormatElement, FormatError, FormatResult,
Expand Down Expand Up @@ -114,7 +114,7 @@ impl Format<CssFormatContext> for FormatCssVerbatimNode<'_> {
},
);

dynamic_text(
text(
&normalize_newlines(&original_source, LINE_TERMINATORS),
self.node.text_trimmed_range().start(),
)
Expand Down
26 changes: 13 additions & 13 deletions crates/biome_css_semantic/src/format_semantic_model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,11 @@ impl Format<FormatSemanticModelContext> for Rule {
write!(
f,
[
dynamic_text(
text(
self.node().syntax().text_trimmed().into_text().text(),
self.node().syntax().text_trimmed_range().start()
),
text(":"),
token(":"),
space(),
&self.specificity(),
]
Expand All @@ -108,13 +108,13 @@ impl Format<FormatSemanticModelContext> for Selector {
write!(
f,
[
dynamic_text(self.text().into_text().text(), self.range().start()),
text(":"),
text(self.text().into_text().text(), self.range().start()),
token(":"),
space(),
&self.specificity(),
space(),
text(" @ "),
dynamic_text(range.as_str(), TextSize::default()),
token(" @ "),
text(range.as_str(), TextSize::default()),
]
)
}
Expand All @@ -125,15 +125,15 @@ impl Format<FormatSemanticModelContext> for Specificity {
write!(
f,
[
text("("),
dynamic_text(self.0.to_string().as_str(), TextSize::default()),
text(","),
token("("),
text(self.0.to_string().as_str(), TextSize::default()),
token(","),
space(),
dynamic_text(self.1.to_string().as_str(), TextSize::default()),
text(","),
text(self.1.to_string().as_str(), TextSize::default()),
token(","),
space(),
dynamic_text(self.2.to_string().as_str(), TextSize::default()),
text(")")
text(self.2.to_string().as_str(), TextSize::default()),
token(")")
]
)
}
Expand Down
16 changes: 8 additions & 8 deletions crates/biome_formatter/src/arguments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ impl<Context> Format<Context> for Argument<'_, Context> {
///
/// # fn main() -> FormatResult<()> {
/// let formatted = format!(SimpleFormatContext::default(), [
/// format_args!(text("a"), space(), text("b"))
/// format_args!(token("a"), space(), token("b"))
/// ])?;
///
/// assert_eq!("a b", formatted.print()?.as_code());
Expand Down Expand Up @@ -140,26 +140,26 @@ mod tests {
write!(
&mut buffer,
[
text("function"),
token("function"),
space(),
text("a"),
token("a"),
space(),
group(&format_args!(text("("), text(")")))
group(&format_args!(token("("), token(")")))
]
)
.unwrap();

assert_eq!(
buffer.into_vec(),
vec![
FormatElement::StaticText { text: "function" },
FormatElement::Token { text: "function" },
FormatElement::Space,
FormatElement::StaticText { text: "a" },
FormatElement::Token { text: "a" },
FormatElement::Space,
// Group
FormatElement::Tag(Tag::StartGroup(tag::Group::new())),
FormatElement::StaticText { text: "(" },
FormatElement::StaticText { text: ")" },
FormatElement::Token { text: "(" },
FormatElement::Token { text: ")" },
FormatElement::Tag(Tag::EndGroup)
]
);
Expand Down
40 changes: 20 additions & 20 deletions crates/biome_formatter/src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ pub trait Buffer {
/// let mut state = FormatState::new(SimpleFormatContext::default());
/// let mut buffer = VecBuffer::new(&mut state);
///
/// buffer.write_element(FormatElement::StaticText { text: "test"}).unwrap();
/// buffer.write_element(FormatElement::Token { text: "test"}).unwrap();
///
/// assert_eq!(buffer.into_vec(), vec![FormatElement::StaticText { text: "test" }]);
/// assert_eq!(buffer.into_vec(), vec![FormatElement::Token { text: "test" }]);
/// ```
///
fn write_element(&mut self, element: FormatElement) -> FormatResult<()>;
Expand All @@ -53,9 +53,9 @@ pub trait Buffer {
/// let mut state = FormatState::new(SimpleFormatContext::default());
/// let mut buffer = VecBuffer::new(&mut state);
///
/// buffer.write_fmt(format_args!(text("Hello World"))).unwrap();
/// buffer.write_fmt(format_args!(token("Hello World"))).unwrap();
///
/// assert_eq!(buffer.into_vec(), vec![FormatElement::StaticText{ text: "Hello World" }]);
/// assert_eq!(buffer.into_vec(), vec![FormatElement::Token{ text: "Hello World" }]);
/// ```
fn write_fmt(mut self: &mut Self, arguments: Arguments<Self::Context>) -> FormatResult<()> {
write(&mut self, arguments)
Expand Down Expand Up @@ -269,7 +269,7 @@ Make sure that you take and restore the snapshot in order and that this snapshot
///
/// impl Format<SimpleFormatContext> for Preamble {
/// fn fmt(&self, f: &mut Formatter<SimpleFormatContext>) -> FormatResult<()> {
/// write!(f, [text("# heading"), hard_line_break()])
/// write!(f, [token("# heading"), hard_line_break()])
/// }
/// }
///
Expand All @@ -280,7 +280,7 @@ Make sure that you take and restore the snapshot in order and that this snapshot
/// {
/// let mut with_preamble = PreambleBuffer::new(&mut buffer, Preamble);
///
/// write!(&mut with_preamble, [text("this text will be on a new line")])?;
/// write!(&mut with_preamble, [token("this text will be on a new line")])?;
/// }
///
/// let formatted = Formatted::new(Document::from(buffer.into_vec()), SimpleFormatContext::default());
Expand All @@ -300,7 +300,7 @@ Make sure that you take and restore the snapshot in order and that this snapshot
///
/// impl Format<SimpleFormatContext> for Preamble {
/// fn fmt(&self, f: &mut Formatter<SimpleFormatContext>) -> FormatResult<()> {
/// write!(f, [text("# heading"), hard_line_break()])
/// write!(f, [token("# heading"), hard_line_break()])
/// }
/// }
///
Expand Down Expand Up @@ -455,11 +455,11 @@ where
/// write!(
/// buffer,
/// [
/// text("The next soft line or space gets replaced by a space"),
/// token("The next soft line or space gets replaced by a space"),
/// soft_line_break_or_space(),
/// text("and the line here"),
/// token("and the line here"),
/// soft_line_break(),
/// text("is removed entirely.")
/// token("is removed entirely.")
/// ]
/// )
/// })]
Expand All @@ -468,10 +468,10 @@ where
/// assert_eq!(
/// formatted.document().as_ref(),
/// &[
/// FormatElement::StaticText { text: "The next soft line or space gets replaced by a space" },
/// FormatElement::Token { text: "The next soft line or space gets replaced by a space" },
/// FormatElement::Space,
/// FormatElement::StaticText { text: "and the line here" },
/// FormatElement::StaticText { text: "is removed entirely." }
/// FormatElement::Token { text: "and the line here" },
/// FormatElement::Token { text: "is removed entirely." }
/// ]
/// );
///
Expand Down Expand Up @@ -706,19 +706,19 @@ pub trait BufferExtensions: Buffer + Sized {
/// let formatted = format!(SimpleFormatContext::default(), [format_with(|f| {
/// let mut recording = f.start_recording();
///
/// write!(recording, [text("A")])?;
/// write!(recording, [text("B")])?;
/// write!(recording, [token("A")])?;
/// write!(recording, [token("B")])?;
///
/// write!(recording, [format_with(|f| write!(f, [text("C"), text("D")]))])?;
/// write!(recording, [format_with(|f| write!(f, [token("C"), token("D")]))])?;
///
/// let recorded = recording.stop();
/// assert_eq!(
/// recorded.deref(),
/// &[
/// FormatElement::StaticText{ text: "A" },
/// FormatElement::StaticText{ text: "B" },
/// FormatElement::StaticText{ text: "C" },
/// FormatElement::StaticText{ text: "D" }
/// FormatElement::Token{ text: "A" },
/// FormatElement::Token{ text: "B" },
/// FormatElement::Token{ text: "C" },
/// FormatElement::Token{ text: "D" }
/// ]
/// );
///
Expand Down
Loading
Loading