refactor(es/codegen): Extract code from generic functions to reduce compile time (#7127)

This commit is contained in:
Donny/강동윤 2023-03-23 13:37:02 +09:00 committed by GitHub
parent f81ac50c2a
commit 08fa94fc73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 249 additions and 172 deletions

View File

@ -35,15 +35,12 @@ pub trait SourceMapperExt {
false
}
fn should_write_separating_line_terminator<P: Spanned, N: Spanned>(
fn should_write_separating_line_terminator(
&self,
prev: Option<P>,
next: Option<N>,
prev: Option<Span>,
next: Option<Span>,
format: ListFormat,
) -> bool {
let prev = prev.map(|s| s.span());
let next = next.map(|s| s.span());
if format.contains(ListFormat::MultiLine) {
return true;
}
@ -63,10 +60,10 @@ pub trait SourceMapperExt {
false
}
fn should_write_leading_line_terminator<N: Spanned>(
fn should_write_leading_line_terminator(
&self,
parent_node: Span,
children: &[N],
first_child: Option<Span>,
format: ListFormat,
) -> bool {
if format.contains(ListFormat::MultiLine) {
@ -78,11 +75,11 @@ pub trait SourceMapperExt {
return true;
}
if children.is_empty() {
if first_child.is_none() {
return !self.is_on_same_line(parent_node.lo(), parent_node.hi());
}
let first_child = children[0].span();
let first_child = first_child.unwrap();
if parent_node.is_synthesized() || first_child.is_synthesized() {
return first_child.starts_on_new_line(format);
}
@ -93,10 +90,10 @@ pub trait SourceMapperExt {
}
}
fn should_write_closing_line_terminator<N: Spanned>(
fn should_write_closing_line_terminator(
&self,
parent_node: Span,
children: &[N],
last_child: Option<Span>,
format: ListFormat,
) -> bool {
if format.contains(ListFormat::MultiLine) {
@ -108,11 +105,12 @@ pub trait SourceMapperExt {
return true;
}
if children.is_empty() {
if last_child.is_none() {
return !self.is_on_same_line(parent_node.lo(), parent_node.hi());
}
let last_child = children[children.len() - 1].span();
let last_child = last_child.unwrap();
if parent_node.is_synthesized() || last_child.is_synthesized() {
last_child.starts_on_new_line(format)
} else {

View File

@ -2155,29 +2155,32 @@ where
)
}
#[allow(clippy::cognitive_complexity)]
fn emit_list5<N: Node>(
/// This method exists to reduce compile time.
#[inline(never)]
fn emit_first_of_list5(
&mut self,
parent_node: Span,
children: Option<&[N]>,
children: Option<usize>,
format: ListFormat,
start: usize,
count: usize,
) -> Result {
) -> Option<Result> {
if children.is_none() && format.contains(ListFormat::OptionalIfUndefined) {
return Ok(());
return Some(Ok(()));
}
let is_empty = children.is_none() || start > children.unwrap().len() || count == 0;
let is_empty = children.is_none() || start > children.unwrap() || count == 0;
if is_empty && format.contains(ListFormat::OptionalIfEmpty) {
return Ok(());
return Some(Ok(()));
}
if format.contains(ListFormat::BracketsMask) {
self.wr.write_punct(None, format.opening_bracket())?;
if let Err(err) = self.wr.write_punct(None, format.opening_bracket()) {
return Some(Err(err));
}
if is_empty {
self.emit_trailing_comments_of_pos(
if let Err(err) = self.emit_trailing_comments_of_pos(
{
// TODO: children.lo()
@ -2185,55 +2188,26 @@ where
},
true,
false,
)?;
) {
return Some(Err(err));
}
}
}
// self.handlers.onBeforeEmitNodeArray(children);
if is_empty {
// Write a line terminator if the parent node was multi-line
if format.contains(ListFormat::MultiLine) {
if !self.cfg.minify {
self.wr.write_line()?;
}
} else if format.contains(ListFormat::SpaceBetweenBraces)
&& !(format.contains(ListFormat::NoSpaceIfEmpty))
&& !self.cfg.minify
{
self.wr.write_space()?;
}
} else {
let children = children.unwrap();
// Write the opening line terminator or leading whitespace.
let may_emit_intervening_comments =
!format.intersects(ListFormat::NoInterveningComments);
let mut should_emit_intervening_comments = may_emit_intervening_comments;
if self
.cm
.should_write_leading_line_terminator(parent_node, children, format)
{
if !self.cfg.minify {
self.wr.write_line()?;
}
should_emit_intervening_comments = false;
} else if format.contains(ListFormat::SpaceBetweenBraces) && !self.cfg.minify {
self.wr.write_space()?;
None
}
// Increase the indent, if requested.
if format.contains(ListFormat::Indented) && !self.cfg.minify {
self.wr.increase_indent()?;
}
// Emit each child.
let mut previous_sibling: Option<Span> = None;
let mut should_decrease_indent_after_emit = false;
for i in 0..count {
let child = &children[start + i];
/// This method exists to reduce compile time.
#[inline(never)]
fn emit_pre_child_for_list5(
&mut self,
parent_node: Span,
format: ListFormat,
previous_sibling: Option<Span>,
child: Span,
should_decrease_indent_after_emit: &mut bool,
should_emit_intervening_comments: &mut bool,
) -> Result {
// Write the delimiter if this is not the first node.
if let Some(previous_sibling) = previous_sibling {
// i.e
@ -2266,38 +2240,30 @@ where
&& !self.cfg.minify
{
self.wr.increase_indent()?;
should_decrease_indent_after_emit = true;
*should_decrease_indent_after_emit = true;
}
if !self.cfg.minify {
self.wr.write_line()?;
}
should_emit_intervening_comments = false;
*should_emit_intervening_comments = false;
} else if format.contains(ListFormat::SpaceBetweenSiblings) {
formatting_space!(self);
}
}
child.emit_with(self)?;
// Emit this child.
if should_emit_intervening_comments {
if self.comments.is_some() {
let comment_range = child.comment_range();
self.emit_trailing_comments_of_pos(comment_range.hi(), false, true)?;
}
} else {
should_emit_intervening_comments = may_emit_intervening_comments;
}
if should_decrease_indent_after_emit {
self.wr.decrease_indent()?;
should_decrease_indent_after_emit = false;
}
previous_sibling = Some(child.span());
Ok(())
}
/// This method exists to reduce compile time.
#[inline(never)]
fn emit_list_finisher_of_list5(
&mut self,
parent_node: Span,
format: ListFormat,
previous_sibling: Option<Span>,
last_child: Option<Span>,
) -> Result {
// Write a trailing comma, if requested.
let has_trailing_comma = format.contains(ListFormat::ForceTrailingComma)
|| format.contains(ListFormat::AllowTrailingComma) && {
@ -2363,7 +2329,7 @@ where
// Write the closing line terminator or closing whitespace.
if self
.cm
.should_write_closing_line_terminator(parent_node, children, format)
.should_write_closing_line_terminator(parent_node, last_child, format)
{
if !self.cfg.minify {
self.wr.write_line()?;
@ -2371,10 +2337,20 @@ where
} else if format.contains(ListFormat::SpaceBetweenBraces) && !self.cfg.minify {
self.wr.write_space()?;
}
Ok(())
}
// self.handlers.onAfterEmitNodeArray(children);
/// This method exists to reduce compile time.
#[inline(never)]
fn emit_last_of_list5(
&mut self,
parent_node: Span,
is_empty: bool,
format: ListFormat,
start: usize,
count: usize,
) -> Result {
if format.contains(ListFormat::BracketsMask) {
if is_empty {
self.emit_leading_comments(
@ -2391,6 +2367,109 @@ where
Ok(())
}
fn emit_list5<N: Node>(
&mut self,
parent_node: Span,
children: Option<&[N]>,
format: ListFormat,
start: usize,
count: usize,
) -> Result {
if let Some(result) =
self.emit_first_of_list5(parent_node, children.map(|v| v.len()), format, start, count)
{
return result;
}
let is_empty = children.is_none() || start > children.unwrap().len() || count == 0;
if is_empty {
// Write a line terminator if the parent node was multi-line
if format.contains(ListFormat::MultiLine) {
if !self.cfg.minify {
self.wr.write_line()?;
}
} else if format.contains(ListFormat::SpaceBetweenBraces)
&& !(format.contains(ListFormat::NoSpaceIfEmpty))
&& !self.cfg.minify
{
self.wr.write_space()?;
}
} else {
let children = children.unwrap();
// Write the opening line terminator or leading whitespace.
let may_emit_intervening_comments =
!format.intersects(ListFormat::NoInterveningComments);
let mut should_emit_intervening_comments = may_emit_intervening_comments;
if self.cm.should_write_leading_line_terminator(
parent_node,
children.first().map(|v| v.span()),
format,
) {
if !self.cfg.minify {
self.wr.write_line()?;
}
should_emit_intervening_comments = false;
} else if format.contains(ListFormat::SpaceBetweenBraces) && !self.cfg.minify {
self.wr.write_space()?;
}
// Increase the indent, if requested.
if format.contains(ListFormat::Indented) && !self.cfg.minify {
self.wr.increase_indent()?;
}
// Emit each child.
let mut previous_sibling: Option<Span> = None;
let mut should_decrease_indent_after_emit = false;
for i in 0..count {
let child = &children[start + i];
self.emit_pre_child_for_list5(
parent_node,
format,
previous_sibling,
child.span(),
&mut should_decrease_indent_after_emit,
&mut should_emit_intervening_comments,
)?;
child.emit_with(self)?;
// Emit this child.
if should_emit_intervening_comments {
if self.comments.is_some() {
let comment_range = child.comment_range();
self.emit_trailing_comments_of_pos(comment_range.hi(), false, true)?;
}
} else {
should_emit_intervening_comments = may_emit_intervening_comments;
}
if should_decrease_indent_after_emit {
self.wr.decrease_indent()?;
should_decrease_indent_after_emit = false;
}
previous_sibling = Some(child.span());
}
self.emit_list_finisher_of_list5(
parent_node,
format,
previous_sibling,
children.last().map(|v| v.span()),
)?;
}
// self.handlers.onAfterEmitNodeArray(children);
self.emit_last_of_list5(parent_node, is_empty, format, start, count)?;
Ok(())
}
}
/// Patterns