mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-28 21:05:08 +00:00
Add formatting of type parameters in class and function definitions (#6161)
Part of #5062 Closes https://github.com/astral-sh/ruff/issues/5931 Implements formatting of a sequence of type parameters in a dedicated struct for reuse by classes, functions, and type aliases (preparing for #5929). Adds formatting of type parameters in class and function definitions — previously, they were just elided.
This commit is contained in:
parent
9425ed72a0
commit
1a60d1e3c6
22 changed files with 825 additions and 172 deletions
|
@ -4,7 +4,7 @@ use ruff_python_ast::node::AnyNodeRef;
|
|||
use ruff_python_ast::whitespace::indentation;
|
||||
use ruff_python_ast::{
|
||||
self as ast, Arguments, Comprehension, Expr, ExprAttribute, ExprBinOp, ExprIfExp, ExprSlice,
|
||||
ExprStarred, MatchCase, Parameters, Ranged,
|
||||
ExprStarred, MatchCase, Parameters, Ranged, TypeParams,
|
||||
};
|
||||
use ruff_python_trivia::{
|
||||
indentation_at_offset, PythonWhitespace, SimpleToken, SimpleTokenKind, SimpleTokenizer,
|
||||
|
@ -85,6 +85,7 @@ pub(super) fn place_comment<'a>(
|
|||
handle_leading_class_with_decorators_comment(comment, class_def)
|
||||
}
|
||||
AnyNodeRef::StmtImportFrom(import_from) => handle_import_from_comment(comment, import_from),
|
||||
AnyNodeRef::TypeParams(type_params) => handle_type_params_comment(comment, type_params),
|
||||
_ => CommentPlacement::Default(comment),
|
||||
}
|
||||
}
|
||||
|
@ -563,6 +564,51 @@ fn handle_own_line_comment_after_branch<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
/// Attach an enclosed end-of-line comment to a set of [`TypeParams`].
|
||||
///
|
||||
/// For example, given:
|
||||
/// ```python
|
||||
/// type foo[ # comment
|
||||
/// bar,
|
||||
/// ] = ...
|
||||
/// ```
|
||||
///
|
||||
/// The comment will be attached to the [`TypeParams`] node as a dangling comment, to ensure
|
||||
/// that it remains on the same line as open bracket.
|
||||
fn handle_type_params_comment<'a>(
|
||||
comment: DecoratedComment<'a>,
|
||||
type_params: &'a TypeParams,
|
||||
) -> CommentPlacement<'a> {
|
||||
// The comment needs to be on the same line, but before the first type param. For example, we want
|
||||
// to treat this as a dangling comment:
|
||||
// ```python
|
||||
// type foo[ # comment
|
||||
// bar,
|
||||
// baz,
|
||||
// qux,
|
||||
// ]
|
||||
// ```
|
||||
// However, this should _not_ be treated as a dangling comment:
|
||||
// ```python
|
||||
// type 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 type param. If so, the only possible position is immediately following
|
||||
// the open parenthesis.
|
||||
if comment.line_position().is_end_of_line() {
|
||||
if let Some(first_type_param) = type_params.type_params.first() {
|
||||
if type_params.start() < comment.start() && comment.end() < first_type_param.start() {
|
||||
return CommentPlacement::dangling(comment.enclosing_node(), comment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CommentPlacement::Default(comment)
|
||||
}
|
||||
|
||||
/// Attaches comments for the positional-only parameters separator `/` or the keywords-only
|
||||
/// parameters separator `*` as dangling comments to the enclosing [`Parameters`] node.
|
||||
///
|
||||
|
|
|
@ -3,7 +3,7 @@ use std::iter::Peekable;
|
|||
use ruff_python_ast::{
|
||||
Alias, Arguments, Comprehension, Decorator, ElifElseClause, ExceptHandler, Expr, Keyword,
|
||||
MatchCase, Mod, Parameter, ParameterWithDefault, Parameters, Pattern, Ranged, Stmt, TypeParam,
|
||||
WithItem,
|
||||
TypeParams, WithItem,
|
||||
};
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
|
||||
|
@ -301,6 +301,13 @@ impl<'ast> PreorderVisitor<'ast> for CommentsVisitor<'ast> {
|
|||
self.finish_node(elif_else_clause);
|
||||
}
|
||||
|
||||
fn visit_type_params(&mut self, type_params: &'ast TypeParams) {
|
||||
if self.start_node(type_params).is_traverse() {
|
||||
walk_type_params(self, type_params);
|
||||
}
|
||||
self.finish_node(type_params);
|
||||
}
|
||||
|
||||
fn visit_type_param(&mut self, type_param: &'ast TypeParam) {
|
||||
if self.start_node(type_param).is_traverse() {
|
||||
walk_type_param(self, type_param);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue