Skip to content

Commit c9c0c63

Browse files
committed
fix(formatter): handle member chain for the call's parent is a chain expression
1 parent 27b4f36 commit c9c0c63

File tree

3 files changed

+23
-12
lines changed

3 files changed

+23
-12
lines changed

crates/oxc_formatter/src/ast_nodes/impls/ast_nodes.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,15 @@ impl<'a> AstNodes<'a> {
2323
if matches!(node, AstNodes::Program(_)) { None } else { Some(node.parent()) }
2424
})
2525
}
26+
27+
/// If the node is a ChainExpression, recursively skip to its parent until a non-ChainExpression node is found.
28+
/// This is useful for analyses that want to ignore the presence of ChainExpressions in the AST
29+
pub fn without_chain_expression(&self) -> &AstNodes<'a> {
30+
match self {
31+
AstNodes::ChainExpression(chain_expression) => {
32+
chain_expression.parent.without_chain_expression()
33+
}
34+
_ => self,
35+
}
36+
}
2637
}

crates/oxc_formatter/src/utils/member_chain/mod.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ impl<'a, 'b> MemberChain<'a, 'b> {
3737
call_expression: &'b AstNode<'a, CallExpression<'a>>,
3838
f: &Formatter<'_, 'a>,
3939
) -> Self {
40-
let parent = &call_expression.parent;
4140
let mut chain_members = chain_members_iter(call_expression, f).collect::<Vec<_>>();
4241
chain_members.reverse();
4342

@@ -54,7 +53,7 @@ impl<'a, 'b> MemberChain<'a, 'b> {
5453

5554
// Here we check if the first element of Groups::groups can be moved inside the head.
5655
// If so, then we extract it and concatenate it together with the head.
57-
member_chain.maybe_merge_with_first_group(parent, f);
56+
member_chain.maybe_merge_with_first_group(call_expression.parent, f);
5857

5958
member_chain
6059
}
@@ -93,14 +92,16 @@ impl<'a, 'b> MemberChain<'a, 'b> {
9392
if self.head.members().len() == 1
9493
&& let ChainMember::Node(node) = self.head.members()[0]
9594
{
96-
if let Expression::Identifier(identifier) = node.as_ref() {
97-
has_computed_property ||
98-
is_factory(&identifier.name) ||
99-
// If an identifier has a name that is shorter than the tab with, then we join it with the "head"
100-
(matches!(parent, AstNodes::ExpressionStatement(stmt) if !stmt.is_arrow_function_body())
101-
&& has_short_name(&identifier.name, f.options().indent_width.value()))
102-
} else {
103-
matches!(node.as_ref(), Expression::ThisExpression(_))
95+
match node.as_ref() {
96+
Expression::Identifier(identifier) => {
97+
has_computed_property ||
98+
is_factory(&identifier.name) ||
99+
// If an identifier has a name that is shorter than the tab with, then we join it with the "head"
100+
(matches!(parent.without_chain_expression(), AstNodes::ExpressionStatement(stmt) if !stmt.is_arrow_function_body())
101+
&& has_short_name(&identifier.name, f.options().indent_width.value()))
102+
}
103+
Expression::ThisExpression(_) => true,
104+
_ => false,
104105
}
105106
} else if let Some(ChainMember::StaticMember(expression)) = self.head.members().last() {
106107
has_computed_property || is_factory(&expression.property().name)

tasks/prettier_conformance/snapshots/prettier.js.snap.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
js compatibility: 684/749 (91.32%)
1+
js compatibility: 685/749 (91.46%)
22

33
# Failed
44

@@ -42,7 +42,6 @@ js compatibility: 684/749 (91.32%)
4242
| js/label/empty_label.js | 💥 | 66.67% |
4343
| js/last-argument-expansion/dangling-comment-in-arrow-function.js | 💥 | 22.22% |
4444
| js/logical-expressions/multiple-comments/17192.js | 💥 | 60.00% |
45-
| js/method-chain/issue-17457.js | 💥 | 0.00% |
4645
| js/object-multiline/multiline.js | 💥✨ | 22.22% |
4746
| js/quote-props/classes.js | 💥💥✨✨ | 47.06% |
4847
| js/quote-props/objects.js | 💥💥✨✨ | 45.10% |

0 commit comments

Comments
 (0)