perf(rome_formatter): Improve Printer source map performance
MODIFY
crates/rome_formatter/src/lib.rs
crates/rome_formatter/src/lib.rs
@@ -378,6 +378,12 @@ impl Printed {
self.sourcemap
}
+ /// Takes the list of [SourceMarker] mapping byte positions in the output string
+ /// to the input source code.
+ pub fn take_sourcemap(&mut self) -> Vec<SourceMarker> {
+ std::mem::take(&mut self.sourcemap)
+ }
+
/// Access the resulting code, borrowing the result
pub fn as_code(&self) -> &str {
&self.code
@@ -399,6 +405,11 @@ impl Printed {
pub fn verbatim_ranges(&self) -> &[TextRange] {
&self.verbatim_ranges
}
+
+ /// Takes the ranges of nodes that have been formatted as verbatim, replacing them with an empty list.
+ pub fn take_verbatim_ranges(&mut self) -> Vec<TextRange> {
+ std::mem::take(&mut self.verbatim_ranges)
+ }
}
/// Public return type of the formatter
@@ -1026,7 +1037,7 @@ where
// Perform the actual formatting of the root node with
// an appropriate indentation level
- let formatted = format_sub_tree(
+ let mut printed = format_sub_tree(
context,
&FormatRefWithRule::<_, R>::new(common_root, R::default()),
)?;
@@ -1038,8 +1049,8 @@ where
let mut range_start = None;
let mut range_end = None;
- let sourcemap = Vec::from(formatted.sourcemap());
- for marker in &sourcemap {
+ let sourcemap = printed.sourcemap();
+ for marker in sourcemap {
// marker.source <= range.start()
if let Some(start_dist) = range.start().checked_sub(marker.source) {
range_start = match range_start {
@@ -1081,15 +1092,15 @@ where
Some((end_marker, _)) => (end_marker.source, end_marker.dest),
None => (
common_root.text_range().end(),
- TextSize::try_from(formatted.as_code().len()).expect("code length out of bounds"),
+ TextSize::try_from(printed.as_code().len()).expect("code length out of bounds"),
),
};
let input_range = TextRange::new(start_source, end_source);
let output_range = TextRange::new(start_dest, end_dest);
- let sourcemap = Vec::from(formatted.sourcemap());
- let verbatim_ranges = Vec::from(formatted.verbatim_ranges());
- let code = &formatted.into_code()[output_range];
+ let sourcemap = printed.take_sourcemap();
+ let verbatim_ranges = printed.take_verbatim_ranges();
+ let code = &printed.into_code()[output_range];
Ok(Printed::new(
code.into(),
Some(input_range),
@@ -1165,9 +1176,9 @@ pub fn format_sub_tree<
};
let formatted = format_node(context, root)?;
- let printed = formatted.print_with_indent(initial_indent);
- let sourcemap = Vec::from(printed.sourcemap());
- let verbatim_ranges = Vec::from(printed.verbatim_ranges());
+ let mut printed = formatted.print_with_indent(initial_indent);
+ let sourcemap = printed.take_sourcemap();
+ let verbatim_ranges = printed.take_verbatim_ranges();
Ok(Printed::new(
printed.into_code(),
Some(syntax.text_range()),

MODIFY
crates/rome_formatter/src/printer/mod.rs
crates/rome_formatter/src/printer/mod.rs
@@ -8,7 +8,7 @@ use crate::format_element::{
use crate::intersperse::Intersperse;
use crate::{FormatElement, GroupId, IndentStyle, Printed, SourceMarker, TextRange};
-use rome_rowan::TextSize;
+use rome_rowan::{TextLen, TextSize};
use std::iter::{once, Rev};
use std::num::NonZeroU8;
@@ -108,7 +108,7 @@ impl<'a> Printer<'a> {
// Insert source map markers before and after the token
//
- // If the token has source position informations the start marker
+ // If the token has source position information the start marker
// will use the start position of the original token, and the end
// marker will use that position + the text length of the token
//
@@ -119,9 +119,9 @@ impl<'a> Printer<'a> {
self.state.source_position = *source;
}
- self.state.source_markers.push(SourceMarker {
+ self.push_marker(SourceMarker {
source: self.state.source_position,
- dest: TextSize::of(&self.state.buffer),
+ dest: self.state.buffer.text_len(),
});
self.print_str(token);
@@ -130,9 +130,9 @@ impl<'a> Printer<'a> {
self.state.source_position += TextSize::of(&**token);
}
- self.state.source_markers.push(SourceMarker {
+ self.push_marker(SourceMarker {
source: self.state.source_position,
- dest: TextSize::of(&self.state.buffer),
+ dest: self.state.buffer.text_len(),
});
}
@@ -323,6 +323,16 @@ impl<'a> Printer<'a> {
}
}
+ fn push_marker(&mut self, marker: SourceMarker) {
+ if let Some(last) = self.state.source_markers.last() {
+ if last != &marker {
+ self.state.source_markers.push(marker)
+ }
+ } else {
+ self.state.source_markers.push(marker);
+ }
+ }
+
fn queue_line_suffixes(
&mut self,
line_break: &'a FormatElement,

perf(rome_formatter): Improve Printer source map performance (#3104)