Skip to content

Commit

Permalink
Fixup comment handling on inner parenthesis in function definition
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Aug 7, 2023
1 parent 44a1b29 commit b63851f
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -295,3 +295,70 @@ def f(*args, b, **kwds, ): pass
def f(*, b, **kwds, ): pass
def f(a, *args, b, **kwds, ): pass
def f(a, *, b, **kwds, ): pass

# Handle comments on inner parenthesis.
def f(
# first
# second
):
...


def f( # first
# second
): # third
...


def f( # first
): # second
...


def f(
a,
/,
# first
b
# second
):
...


def f( # first
*,
# second
b
# third
):
...


def f( # first
# second
*,
# third
b
# fourth
):
...


def f( # first
a,
# second
): # third
...


def f( # first
a
): # second
...


def f( # first
a
# second
): # third
...
1 change: 1 addition & 0 deletions crates/ruff_python_formatter/src/comments/placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ pub(super) fn place_comment<'a>(
comment.or_else(|comment| match comment.enclosing_node() {
AnyNodeRef::Parameters(arguments) => {
handle_parameters_separator_comment(comment, arguments, locator)
.or_else(|comment| handle_bracketed_end_of_line_comment(comment, locator))
}
AnyNodeRef::Arguments(_) | AnyNodeRef::TypeParams(_) => {
handle_bracketed_end_of_line_comment(comment, locator)
Expand Down
66 changes: 58 additions & 8 deletions crates/ruff_python_formatter/src/other/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::usize;
use ruff_python_ast::{Parameters, Ranged};
use ruff_text_size::{TextRange, TextSize};

use crate::builders::empty_parenthesized_with_dangling_comments;
use ruff_formatter::{format_args, write, FormatRuleWithOptions};
use ruff_python_ast::node::{AnyNodeRef, AstNode};
use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer};
Expand All @@ -12,7 +13,7 @@ use crate::comments::{
CommentLinePosition, SourceComment,
};
use crate::context::{NodeLevel, WithNodeLevel};
use crate::expression::parentheses::parenthesized;
use crate::expression::parentheses::{parenthesized, parenthesized_with_inner_comments};
use crate::prelude::*;
use crate::FormatNodeRule;

Expand Down Expand Up @@ -63,8 +64,41 @@ impl FormatNodeRule<Parameters> for FormatParameters {

let comments = f.context().comments().clone();
let dangling = comments.dangling_comments(item);

let (slash, star) = find_argument_separators(f.context().source(), item);

// First dangling comment: trailing the opening parenthesis, e.g.:
// ```python
// def f( # comment
// x,
// y,
// z,
// ): ...
// TODO(charlie): We already identified this comment as such in placement.rs. Is there any
// way to avoid this implicit coupling?
let parenthesis_comments_end = usize::from(dangling.first().is_some_and(|comment| {
if comment.line_position().is_end_of_line() {
// Ensure that there are no tokens between the open bracket and the comment.
let mut lexer = SimpleTokenizer::new(
f.context().source(),
TextRange::new(item.start(), comment.start()),
)
.skip_trivia()
.skip_while(|t| {
matches!(
t.kind(),
SimpleTokenKind::LParen
| SimpleTokenKind::LBrace
| SimpleTokenKind::LBracket
)
});
if lexer.next().is_none() {
return true;
}
}
false
}));

let format_inner = format_with(|f: &mut PyFormatter| {
let separator = format_with(|f| write!(f, [text(","), soft_line_break_or_space()]));
let mut joiner = f.join_with(separator);
Expand All @@ -76,8 +110,16 @@ impl FormatNodeRule<Parameters> for FormatParameters {
last_node = Some(parameter_with_default.into());
}

// Second dangling comment: trailing the slash, e.g.:
// ```python
// def f(
// x,
// /, # comment
// y,
// z,
// ): ...
let slash_comments_end = if posonlyargs.is_empty() {
0
parenthesis_comments_end
} else {
let slash_comments_end = dangling.partition_point(|comment| {
let assignment = assign_argument_separator_comment_placement(
Expand All @@ -95,7 +137,7 @@ impl FormatNodeRule<Parameters> for FormatParameters {
});
joiner.entry(&CommentsAroundText {
text: "/",
comments: &dangling[..slash_comments_end],
comments: &dangling[parenthesis_comments_end..slash_comments_end],
});
slash_comments_end
};
Expand Down Expand Up @@ -202,14 +244,22 @@ impl FormatNodeRule<Parameters> for FormatParameters {
// No parameters, format any dangling comments between `()`
write!(
f,
[
[empty_parenthesized_with_dangling_comments(
text("("),
block_indent(&dangling_comments(dangling)),
text(")")
]
&dangling,
text(")"),
)]
)
} else {
write!(f, [parenthesized("(", &group(&format_inner), ")")])
write!(
f,
[parenthesized_with_inner_comments(
"(",
&dangling[..parenthesis_comments_end],
&group(&format_inner),
")"
)]
)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,73 @@ def f(*args, b, **kwds, ): pass
def f(*, b, **kwds, ): pass
def f(a, *args, b, **kwds, ): pass
def f(a, *, b, **kwds, ): pass

# Handle comments on inner parenthesis.
def f(
# first
# second
):
...


def f( # first
# second
): # third
...


def f( # first
): # second
...


def f(
a,
/,
# first
b
# second
):
...


def f( # first
*,
# second
b
# third
):
...


def f( # first
# second
*,
# third
b
# fourth
):
...


def f( # first
a,
# second
): # third
...


def f( # first
a
): # second
...


def f( # first
a
# second
): # third
...
```

## Output
Expand Down Expand Up @@ -753,6 +820,71 @@ def f(
**kwds,
):
pass


# Handle comments on inner parenthesis.
def f(
# first
# second
):
...


def f( # first
# second
): # third
...


def f(): # first # second
...


def f(
a,
/,
# first
b,
# second
):
...


def f( # first
*,
# second
b,
# third
):
...


def f( # first
# second
*,
# third
b,
# fourth
):
...


def f( # first
a,
# second
): # third
...


def f(a): # first # second
...


def f( # first
a,
# second
): # third
...
```


Expand Down

0 comments on commit b63851f

Please sign in to comment.