ruff/crates/ruff_python_formatter/src/statement
Charlie Marsh 17ceb5dcb3
Preserve newlines after nested compound statements (#7608)
## Summary

Given:
```python
if True:
    if True:
        pass
    else:
        pass
        # a

        # b
        # c

else:
    pass
```

We want to preserve the newline after the `# c` (before the `else`).
However, the `last_node` ends at the `pass`, and the comments are
trailing comments on the `pass`, not trailing comments on the
`last_node` (the `if`). As such, when counting the trailing newlines on
the outer `if`, we abort as soon as we see the comment (`# a`).

This PR changes the logic to skip _all_ comments (even those with
newlines between them). This is safe as we know that there are no
"leading" comments on the `else`, so there's no risk of skipping those
accidentally.

Closes https://github.com/astral-sh/ruff/issues/7602.

## Test Plan

No change in compatibility.

Before:

| project | similarity index | total files | changed files |

|--------------|------------------:|------------------:|------------------:|
| cpython | 0.76083 | 1789 | 1631 |
| django | 0.99983 | 2760 | 36 |
| transformers | 0.99963 | 2587 | 319 |
| twine | 1.00000 | 33 | 0 |
| typeshed | 0.99979 | 3496 | 22 |
| warehouse | 0.99967 | 648 | 15 |
| zulip | 0.99972 | 1437 | 21 |

After:

| project | similarity index | total files | changed files |

|--------------|------------------:|------------------:|------------------:|
| cpython | 0.76083 | 1789 | 1631 |
| django | 0.99983 | 2760 | 36 |
| transformers | 0.99963 | 2587 | 319 |
| twine | 1.00000 | 33 | 0 |
| typeshed | 0.99983 | 3496 | 18 |
| warehouse | 0.99967 | 648 | 15 |
| zulip | 0.99972 | 1437 | 21 |
2023-09-25 14:21:44 +00:00
..
clause.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
mod.rs Support fmt: skip on compound statements (#6593) 2023-08-17 06:05:41 +00:00
stmt_ann_assign.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_assert.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_assign.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_aug_assign.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_break.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_class_def.rs Preserve newlines after nested compound statements (#7608) 2023-09-25 14:21:44 +00:00
stmt_continue.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_delete.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_expr.rs Use the formatter prelude in more files (#6882) 2023-08-25 16:51:07 -04:00
stmt_for.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_function_def.rs Treat parameters-with-newline as empty in function formatting (#7550) 2023-09-20 16:20:22 -04:00
stmt_global.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_if.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_import.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_import_from.rs Remove Int wrapper type from parser (#7577) 2023-09-21 17:01:44 +00:00
stmt_ipy_escape_command.rs Memoize text width (#6552) 2023-09-06 07:10:13 +00:00
stmt_match.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_nonlocal.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_pass.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_raise.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_return.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_try.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_type_alias.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_while.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
stmt_with.rs Introduce Token element (#7048) 2023-09-02 10:05:47 +02:00
suite.rs Preserve newlines after nested compound statements (#7608) 2023-09-25 14:21:44 +00:00