Fix remaining CPython formatter errors except for function argument separator comments (#5210)

## Summary

This fixes two problems discovered when trying to format the cpython
repo with `cargo run --bin ruff_dev -- check-formatter-stability
projects/cpython`:

The first is to ignore try/except trailing comments for now since they
lead to unstable formatting on the dummy.

The second is to avoid dropping trailing if comments through placement:
This changes the placement to keep a comment trailing an if-elif or
if-elif-else to keep the comment a trailing comment on the entire if.
Previously the last comment would have been lost.
```python
if "first if":
    pass
elif "first elif":
    pass
```

The last remaining problem in cpython so far is function signature
argument separator comment placement which is its own PR on top of this.

## Test Plan

I added test fixtures of minimized examples with links back to the
original cpython location
This commit is contained in:
konstin 2023-06-21 19:45:53 +02:00 committed by GitHub
parent bf1a94ee54
commit bc63cc9b3c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 148 additions and 34 deletions

View file

@ -402,7 +402,11 @@ fn handle_trailing_body_comment<'a>(
}
// Only do something if the preceding node has a body (has indented statements).
let Some(last_child) = comment.preceding_node().and_then(last_child_in_body) else {
let Some(preceding_node) = comment.preceding_node() else {
return CommentPlacement::Default(comment);
};
let Some(last_child) = last_child_in_body(preceding_node) else {
return CommentPlacement::Default(comment);
};
@ -415,8 +419,24 @@ fn handle_trailing_body_comment<'a>(
// the indent-level doesn't depend on the tab width (the indent level must be the same if the tab width is 1 or 8).
let comment_indentation_len = comment_indentation.len();
// Keep the comment on the entire statement in case it's a trailing comment
// ```python
// if "first if":
// pass
// elif "first elif":
// pass
// # Trailing if comment
// ```
// Here we keep the comment a trailing comment of the `if`
let Some(preceding_node_indentation) = whitespace::indentation_at_offset(locator, preceding_node.start()) else {
return CommentPlacement::Default(comment);
};
if comment_indentation_len == preceding_node_indentation.len() {
return CommentPlacement::Default(comment);
}
let mut current_child = last_child;
let mut parent_body = comment.preceding_node();
let mut parent_body = Some(preceding_node);
let mut grand_parent_body = None;
loop {