Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(js_formatter): avoid introducing linebreaks for single line string interpolations #2500

Merged
merged 13 commits into from
May 10, 2024

Conversation

ah-yu
Copy link
Contributor

@ah-yu ah-yu commented Apr 18, 2024

Summary

Closes #2470

In the newest version of Prettier, efforts have been made to optimize the formatting of string interpolations within template literals, aiming to keep them on a single line whenever possible. However, there are two exceptions to this rule:

  • If line breaks are present inside the string interpolation while typing, for example:
    let message = `${this(
        long.placeholder.text.goes.here.so.we.get.a.linebreak,
    )} already had a line break, so it can be broken up`
  • If the string interpolation contains forced line breaks in generated IR, such as hard_line_break

Test Plan

Add new tests and update corresponding snapshots

Note: This PR changes the behavior of formatting string interpolations within template literals so some existing snapshots need to be updated.

@github-actions github-actions bot added A-Formatter Area: formatter L-JavaScript Language: JavaScript and super languages labels Apr 18, 2024
Copy link

codspeed-hq bot commented Apr 18, 2024

CodSpeed Performance Report

Merging #2500 will not alter performance

Comparing ah-yu:str_template_fmt (9b7152e) with main (49cace8)

Summary

✅ 97 untouched benchmarks

@ah-yu ah-yu force-pushed the str_template_fmt branch 2 times, most recently from fba1854 to 9a4f42f Compare May 6, 2024 10:31
: ""}
- @media (max-width: ${(props) =>
- props.noBreakPoint ? "0" : constants.layout.breakpoint.break1}px) {
+ @media (max-width: ${(props) => props.noBreakPoint ? "0" : constants.layout.breakpoint.break1}px) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mismatch occurs because Prettier treats the template string as CSS since the template string is prefixed with styled.div but Biome treats it as a normal template string.

+)} <script>const tpl = html\`<div>\${innerExpr( 1 )} ${outerExpr(
+ 2,
+)}</div>\`</script>`;
+const nestedFun = /* HTML */ `${outerExpr(1)} <script>const tpl = html\`<div>\${innerExpr( 1 )} ${outerExpr(2)}</div>\`</script>`;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All mismatches occur in this file because Prettier treats these template strings as HTML since the template string has the leading comment /* HTML */ but Biome treats them as normal template strings.

@ah-yu ah-yu marked this pull request as ready for review May 8, 2024 03:59
@@ -597,6 +608,41 @@ fn clean_interned(
}
}

fn clean_best_fitting(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should document a bit of the logic. For example, we want to document what defines "being inside an expanded conditional content". (e.g. is_in_expanded_conditional_content)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is for quick verification purposes, forgot to remove it. I've adjusted the logic related to RemoveSoftLinesBuffer a bit in 99330db. Please take a look

@@ -179,6 +216,10 @@ impl AnyTemplateElement {
AnyTemplateElement::TsTemplateElement(template) => template.r_curly_token(),
}
}

fn has_new_line_in_range(&self) -> bool {
self.syntax().text().contains_char('\n')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This won't work on Windows, where newlines can be \r. Also, wouldn't you risk hitting false positives, where you might have a string literal that contains a literal new line? e.g:

const f = `some \n \n ${foo} \n bar`;

Wouldn't it be safer to extract the trivia and check for TriviaKind::Whitespace that contain newlines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. Fixed in 43493fa

Copy link
Member

@ematipico ematipico left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! We should add a changelog entry, then we can merge it

@ah-yu ah-yu force-pushed the str_template_fmt branch from d86c2d4 to 9b7152e Compare May 10, 2024 06:40
@github-actions github-actions bot added the A-Changelog Area: changelog label May 10, 2024
@ah-yu ah-yu merged commit 7b9dd64 into biomejs:main May 10, 2024
12 checks passed
@ah-yu ah-yu deleted the str_template_fmt branch May 10, 2024 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Changelog Area: changelog A-Formatter Area: formatter L-JavaScript Language: JavaScript and super languages
Projects
None yet
Development

Successfully merging this pull request may close these issues.

📝 Biome breaks template strings where prettier doesn't
2 participants