Skip to content

Commit

Permalink
Format
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Aug 2, 2023
1 parent 09fa5b0 commit b5af1c1
Show file tree
Hide file tree
Showing 19 changed files with 520 additions and 236 deletions.
38 changes: 38 additions & 0 deletions crates/ruff_python_ast/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2620,6 +2620,34 @@ impl AstNode for Comprehension {
AnyNode::from(self)
}
}
impl AstNode for Arguments {
fn cast(kind: AnyNode) -> Option<Self>
where
Self: Sized,
{
if let AnyNode::Arguments(node) = kind {
Some(node)
} else {
None
}
}

fn cast_ref(kind: AnyNodeRef) -> Option<&Self> {
if let AnyNodeRef::Arguments(node) = kind {
Some(node)
} else {
None
}
}

fn as_any_node_ref(&self) -> AnyNodeRef {
AnyNodeRef::from(self)
}

fn into_any_node(self) -> AnyNode {
AnyNode::from(self)
}
}
impl AstNode for Parameters {
fn cast(kind: AnyNode) -> Option<Self>
where
Expand Down Expand Up @@ -3451,6 +3479,11 @@ impl From<Comprehension> for AnyNode {
AnyNode::Comprehension(node)
}
}
impl From<Arguments> for AnyNode {
fn from(node: Arguments) -> Self {
AnyNode::Arguments(node)
}
}
impl From<Parameters> for AnyNode {
fn from(node: Parameters) -> Self {
AnyNode::Parameters(node)
Expand Down Expand Up @@ -4893,6 +4926,11 @@ impl<'a> From<&'a Comprehension> for AnyNodeRef<'a> {
AnyNodeRef::Comprehension(node)
}
}
impl<'a> From<&'a Arguments> for AnyNodeRef<'a> {
fn from(node: &'a Arguments) -> Self {
AnyNodeRef::Arguments(node)
}
}
impl<'a> From<&'a Parameters> for AnyNodeRef<'a> {
fn from(node: &'a Parameters) -> Self {
AnyNodeRef::Parameters(node)
Expand Down
3 changes: 3 additions & 0 deletions crates/ruff_python_formatter/foo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
f( # abc
1
)
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,28 @@ def f(*args, **kwargs):
f(
a.very_long_function_function_that_is_so_long_that_it_expands_the_parent_but_its_only_a_single_argument()
)

f( # abc
)

f( # abc
# abc
)

f(
# abc
)

f ( # abc
1
)

f (
# abc
1
)

f (
1
# abc
)
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,36 @@ class Test:
"""Docstring"""
# comment
x = 1


class C(): # comment
pass


class C( # comment
):
pass


class C(
# comment
):
pass


class C(): # comment
pass


class C( # comment
# comment
1
):
pass


class C(
1
# comment
):
pass
4 changes: 2 additions & 2 deletions crates/ruff_python_formatter/src/builders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use ruff_python_ast::Ranged;
use ruff_python_trivia::{SimpleToken, SimpleTokenKind, SimpleTokenizer};
use ruff_text_size::{TextRange, TextSize};

use crate::comments::{dangling_comments, SourceComment};
use crate::comments::{dangling_comments, trailing_comments, SourceComment};
use crate::context::{NodeLevel, WithNodeLevel};
use crate::prelude::*;
use crate::MagicTrailingComma;
Expand Down Expand Up @@ -252,7 +252,7 @@ impl<'ast> Format<PyFormatContext<'ast>> for EmptyWithDanglingComments<'_> {
[group(&format_args![
self.opening,
// end-of-line comments
dangling_comments(&self.comments[..end_of_line_split]),
trailing_comments(&self.comments[..end_of_line_split]),
// own line comments, which need to be indented
soft_block_indent(&dangling_comments(&self.comments[end_of_line_split..])),
self.closing
Expand Down
63 changes: 61 additions & 2 deletions crates/ruff_python_formatter/src/comments/placement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ use std::cmp::Ordering;
use ruff_python_ast::node::AnyNodeRef;
use ruff_python_ast::whitespace::indentation;
use ruff_python_ast::{
self as ast, Comprehension, Expr, ExprAttribute, ExprBinOp, ExprIfExp, ExprSlice, ExprStarred,
MatchCase, Parameters, Ranged,
self as ast, Arguments, Comprehension, Expr, ExprAttribute, ExprBinOp, ExprIfExp, ExprSlice,
ExprStarred, MatchCase, Parameters, Ranged,
};
use ruff_python_trivia::{
indentation_at_offset, PythonWhitespace, SimpleToken, SimpleTokenKind, SimpleTokenizer,
Expand Down Expand Up @@ -46,6 +46,7 @@ pub(super) fn place_comment<'a>(
AnyNodeRef::Parameters(arguments) => {
handle_parameters_separator_comment(comment, arguments, locator)
}
AnyNodeRef::Arguments(arguments) => handle_arguments_comment(comment, arguments),
AnyNodeRef::Comprehension(comprehension) => {
handle_comprehension_comment(comment, comprehension, locator)
}
Expand Down Expand Up @@ -1105,6 +1106,64 @@ fn find_only_token_in_range(
token
}

/// Attach an enclosed end-of-line comment to a set of [`Arguments`].
///
/// For example, given:
/// ```python
/// foo( # comment
/// bar,
/// )
/// ```
///
/// The comment will be attached to the [`Arguments`] node as a dangling comment, to ensure
/// that it remains on the same line as open parenthesis.
fn handle_arguments_comment<'a>(
comment: DecoratedComment<'a>,
arguments: &'a Arguments,
) -> CommentPlacement<'a> {
// The comment needs to be on the same line, but before the first argument. For example, we want
// to treat this as a dangling comment:
// ```python
// foo( # comment
// bar,
// baz,
// qux,
// )
// ```
// However, this should _not_ be treated as a dangling comment:
// ```python
// foo(bar, # comment
// baz,
// qux,
// )
// ```
// Thus, we check whether the comment is an end-of-line comment _between_ the start of the
// statement and the first argument. If so, the only possible position is immediately following
// the open parenthesis.
if comment.line_position().is_end_of_line() {
let first_argument = match (arguments.args.as_slice(), arguments.keywords.as_slice()) {
([first_arg, ..], [first_keyword, ..]) => {
if first_arg.start() < first_keyword.start() {
Some(first_arg.range())
} else {
Some(first_keyword.range())
}
}
([first_arg, ..], []) => Some(first_arg.range()),
([], [first_keyword, ..]) => Some(first_keyword.range()),
([], []) => None,
};

if let Some(first_argument) = first_argument {
if arguments.start() < comment.start() && comment.end() < first_argument.start() {
return CommentPlacement::dangling(comment.enclosing_node(), comment);
}
}
}

CommentPlacement::Default(comment)
}

/// Attach an enclosed end-of-line comment to a [`StmtImportFrom`].
///
/// For example, given:
Expand Down
12 changes: 10 additions & 2 deletions crates/ruff_python_formatter/src/comments/visitor.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
use std::iter::Peekable;

use ruff_python_ast::{
Alias, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword, MatchCase, Mod,
Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam, WithItem,
Alias, Arguments, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword,
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
WithItem,
};
use ruff_text_size::{TextRange, TextSize};

Expand Down Expand Up @@ -229,6 +230,13 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
self.finish_node(format_spec);
}

fn visit_arguments(&mut self, arguments: &'ast Arguments) {
if self.start_node(arguments).is_traverse() {
walk_arguments(self, arguments);
}
self.finish_node(arguments);
}

fn visit_parameters(&mut self, parameters: &'ast Parameters) {
if self.start_node(parameters).is_traverse() {
walk_parameters(self, parameters);
Expand Down
Loading

0 comments on commit b5af1c1

Please sign in to comment.