Formatter: Add EmptyWithDanglingComments helper (#5951)

**Summary** Add a `EmptyWithDanglingComments` format helper that formats
comments inside empty parentheses, brackets or curly braces. Previously,
this was implemented separately, and partially incorrectly, for each use
case.

Empty `()`, `[]` and `{}` are special because there can be dangling
comments, and they can be in
two positions:
```python
x = [  # end-of-line
    # own line
]
```
These comments are dangling because they can't be assigned to any
element inside as they would
in all other cases.

**Test Plan** Added a regression test.

145 (from previously 149) instances of unstable formatting remaining.

```
$ cargo run --bin ruff_dev --release -- format-dev --stability-check --error-file formatter-ecosystem-errors.txt --multi-project target/checkouts > formatter-ecosystem-progress.txt
$ rg "Unstable formatting" target/formatter-ecosystem-errors.txt | wc -l
145
```
This commit is contained in:
konsti 2023-07-23 14:32:16 +02:00 committed by GitHub
parent f886b58c92
commit 46f8961292
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 94 additions and 56 deletions

View file

@ -1,11 +1,11 @@
use ruff_text_size::{TextRange, TextSize};
use rustpython_parser::ast::{Expr, ExprCall, Ranged};
use crate::builders::empty_parenthesized_with_dangling_comments;
use ruff_formatter::write;
use ruff_python_ast::node::AnyNodeRef;
use ruff_python_trivia::{SimpleTokenKind, SimpleTokenizer};
use crate::comments::dangling_comments;
use crate::expression::expr_generator_exp::GeneratorExpParentheses;
use crate::expression::parentheses::{
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
@ -34,14 +34,15 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
// ```
if args.is_empty() && keywords.is_empty() {
let comments = f.context().comments().clone();
let comments = comments.dangling_comments(item);
return write!(
f,
[
func.format(),
text("("),
dangling_comments(comments),
text(")")
empty_parenthesized_with_dangling_comments(
text("("),
comments.dangling_comments(item),
text(")"),
)
]
);
}