mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(formatter): keep source parens around html-in-js placeholders past comments (#28381)
It's a rare case, but just to be safe.
This commit is contained in:
1 parent
e738daede1
commit
fb3aefa8d6
4 files changed
+27
-14
No files matched your search
+3
@@ -0,0 +1,3 @@
|
|||||||
|
html`<script>f((${a}) /* c */)</script>`;
|
||||||
|
html`<script>f((${a}))</script>`;
|
||||||
|
html`<script>f(/* c */ (${a}))</script>`;
|
||||||
@@ -74,7 +74,7 @@
|
|||||||
|
|
||||||
## html-in-js
|
## html-in-js
|
||||||
|
|
||||||
### Option 1: 172/200 (86.00%)
|
### Option 1: 173/201 (86.07%)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"printWidth":80}
|
{"printWidth":80}
|
||||||
@@ -137,7 +137,7 @@
|
|||||||
- [externals/webawesome/textarea/textarea.ts](diffs/html-in-js/externals__webawesome__textarea__textarea.ts.md)
|
- [externals/webawesome/textarea/textarea.ts](diffs/html-in-js/externals__webawesome__textarea__textarea.ts.md)
|
||||||
- crates/oxc_formatter/DIVERGENCES.md#union-annotation-flat-retry
|
- crates/oxc_formatter/DIVERGENCES.md#union-annotation-flat-retry
|
||||||
|
|
||||||
### Option 2: 186/200 (93.00%)
|
### Option 2: 187/201 (93.03%)
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{"printWidth":100,"htmlWhitespaceSensitivity":"ignore"}
|
{"printWidth":100,"htmlWhitespaceSensitivity":"ignore"}
|
||||||
|
|||||||
+2
-2
@@ -74,7 +74,7 @@ const d = html`<style>
|
|||||||
const a = html`
|
const a = html`
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
- prettier_html_placeholder_0_2989_in_js: ${c};
|
- prettier_html_placeholder_0_2992_in_js: ${c};
|
||||||
+ ${b}: ${c};
|
+ ${b}: ${c};
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
@@ -110,7 +110,7 @@ const d = html`
|
|||||||
const a = html`
|
const a = html`
|
||||||
<style>
|
<style>
|
||||||
a {
|
a {
|
||||||
prettier_html_placeholder_0_2989_in_js: ${c};
|
prettier_html_placeholder_0_2992_in_js: ${c};
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -144,23 +144,33 @@ impl NeedsParentheses<'_> for AstNode<'_, '_, IdentifierReference<'_>> {
|
|||||||
|
|
||||||
/// Whether the source wraps `node` in parentheses of its own (the AST keeps none),
|
/// Whether the source wraps `node` in parentheses of its own (the AST keeps none),
|
||||||
/// besides those of the syntax around it (a sole call argument, an `if` test, ...).
|
/// besides those of the syntax around it (a sole call argument, an `if` test, ...).
|
||||||
|
/// Comments between them are skipped (`f((a) /* c */)`).
|
||||||
|
#[expect(clippy::cast_possible_truncation)] // Offsets fit in `u32`, source length does
|
||||||
fn is_parenthesized_in_source(
|
fn is_parenthesized_in_source(
|
||||||
node: &AstNode<'_, '_, IdentifierReference<'_>>,
|
node: &AstNode<'_, '_, IdentifierReference<'_>>,
|
||||||
f: &JsFormatter<'_, '_>,
|
f: &JsFormatter<'_, '_>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let bytes = f.source_text().as_str().as_bytes();
|
let bytes = f.source_text().as_str().as_bytes();
|
||||||
let (mut start, mut end) = (node.span.start as usize, node.span.end as usize);
|
let comments = f.context().comments();
|
||||||
let mut pairs = 0;
|
// The last byte before `pos` that is neither whitespace nor in a comment
|
||||||
loop {
|
let before = |mut pos: u32| -> Option<u32> {
|
||||||
let before = bytes[..start].iter().rposition(|b| !b.is_ascii_whitespace());
|
loop {
|
||||||
let after = bytes[end..].iter().position(|b| !b.is_ascii_whitespace()).map(|i| end + i);
|
let i = bytes[..pos as usize].iter().rposition(|b| !b.is_ascii_whitespace())? as u32;
|
||||||
match (before, after) {
|
match comments.all_comments_before(pos).last() {
|
||||||
(Some(before), Some(after)) if bytes[before] == b'(' && bytes[after] == b')' => {
|
Some(comment) if comment.span.end > i => pos = comment.span.start,
|
||||||
pairs += 1;
|
_ => return Some(i),
|
||||||
(start, end) = (before, after + 1);
|
|
||||||
}
|
}
|
||||||
_ => break,
|
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
let (mut start, mut end) = (node.span.start, node.span.end);
|
||||||
|
let mut pairs = 0;
|
||||||
|
while let Some(open) = before(start)
|
||||||
|
&& bytes[open as usize] == b'('
|
||||||
|
&& comments.is_followed_by_closing_paren(end)
|
||||||
|
{
|
||||||
|
pairs += 1;
|
||||||
|
start = open;
|
||||||
|
end = comments.position_after_character(end, b')');
|
||||||
}
|
}
|
||||||
let span = node.span;
|
let span = node.span;
|
||||||
let syntax_parens = match node.parent() {
|
let syntax_parens = match node.parent() {
|
||||||
|
|||||||
Reference in new issue
Block a user