Skip to content

Commit dbe818c

Browse files
authored
[fix] Don't duplicate parens for block-only callers that shadow variable names (#949)
* Fixtures * [fix] Don't duplicate parens for block-only callers that shadow variable names
1 parent b63fbaa commit dbe818c

3 files changed

Lines changed: 49 additions & 18 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def a = 1
2+
def b = 1
3+
4+
def c(&d)
5+
b(&d)
6+
b = 1
7+
b(&d)
8+
9+
a(&d)
10+
a.(&d)
11+
end
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
def a = 1
2+
def b = 1
3+
4+
def c(&d)
5+
b(&d)
6+
b = 1
7+
b(&d)
8+
9+
a(&d)
10+
a.(&d)
11+
end

librubyfmt/src/format_prism.rs

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1706,17 +1706,20 @@ fn use_parens_for_call_node<'src>(
17061706
&& is_empty_parentheses_node(&args.arguments().first().unwrap())))
17071707
});
17081708

1709+
// The block-argument render path emits its own parens around `(&blk)`, so we
1710+
// should never emit an extra empty `()` pair before it, regardless of any
1711+
// other reason we might otherwise add parens (e.g. a same-named local
1712+
// variable in scope, or a capitalized/const-style method name).
1713+
let has_block_arg_only = !has_arguments
1714+
&& call_node
1715+
.block()
1716+
.and_then(|b| b.as_block_argument_node())
1717+
.is_some();
1718+
if has_block_arg_only {
1719+
return false;
1720+
}
1721+
17091722
if is_terminal_call && method_name.first().is_some_and(|c| c.is_ascii_uppercase()) {
1710-
// The block-argument render path emits its own parens around `(&blk)`, so we can skip them
1711-
// if they're the only arg
1712-
let has_block_arg_only = !has_arguments
1713-
&& call_node
1714-
.block()
1715-
.and_then(|b| b.as_block_argument_node())
1716-
.is_some();
1717-
if has_block_arg_only {
1718-
return false;
1719-
}
17201723
if !has_arguments && call_node.block().is_some() && call_node.receiver().is_none() {
17211724
return false;
17221725
}
@@ -2006,14 +2009,20 @@ fn format_call_node<'src>(
20062009
}
20072010
} else {
20082011
// There's no arguments, but we may still need parens
2009-
let should_use_parens = is_dot_call
2010-
|| use_parens_for_call_node(
2011-
ps,
2012-
&call_node,
2013-
method_name,
2014-
is_final_call_in_chain,
2015-
ps.current_formatting_context(),
2016-
);
2012+
let has_block_arg_only = call_node.arguments().is_none()
2013+
&& call_node
2014+
.block()
2015+
.and_then(|b| b.as_block_argument_node())
2016+
.is_some();
2017+
let should_use_parens = !has_block_arg_only
2018+
&& (is_dot_call
2019+
|| use_parens_for_call_node(
2020+
ps,
2021+
&call_node,
2022+
method_name,
2023+
is_final_call_in_chain,
2024+
ps.current_formatting_context(),
2025+
));
20172026
if should_use_parens {
20182027
ps.emit_open_paren();
20192028
ps.emit_close_paren();

0 commit comments

Comments
 (0)