mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-27 12:29:28 +00:00
Pass parent to NeedsParentheses
(#5708)
This commit is contained in:
parent
30702c2977
commit
067b2a6ce6
55 changed files with 562 additions and 606 deletions
|
@ -1,11 +1,12 @@
|
|||
use crate::comments::{leading_comments, trailing_comments, Comments};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprAttribute, ExprConstant};
|
||||
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::write;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprAttribute, ExprConstant};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExprAttribute;
|
||||
|
@ -35,7 +36,7 @@ impl FormatNodeRule<ExprAttribute> for FormatExprAttribute {
|
|||
dangling_comments.split_at(leading_attribute_comments_start);
|
||||
|
||||
if needs_parentheses {
|
||||
value.format().with_options(Parenthesize::Always).fmt(f)?;
|
||||
value.format().with_options(Parentheses::Always).fmt(f)?;
|
||||
} else if let Expr::Attribute(expr_attribute) = value.as_ref() {
|
||||
// We're in a attribute chain (`a.b.c`). The outermost node adds parentheses if
|
||||
// required, the inner ones don't need them so we skip the `Expr` formatting that
|
||||
|
@ -71,41 +72,23 @@ impl FormatNodeRule<ExprAttribute> for FormatExprAttribute {
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if there are any own line comments in an attribute chain (a.b.c). This method is
|
||||
/// recursive up to the innermost expression that the attribute chain starts behind.
|
||||
fn has_breaking_comments_attribute_chain(
|
||||
expr_attribute: &ExprAttribute,
|
||||
comments: &Comments,
|
||||
) -> bool {
|
||||
if comments
|
||||
.dangling_comments(expr_attribute)
|
||||
.iter()
|
||||
.any(|comment| comment.line_position().is_own_line())
|
||||
|| comments.has_trailing_own_line_comments(expr_attribute)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if let Expr::Attribute(inner) = expr_attribute.value.as_ref() {
|
||||
return has_breaking_comments_attribute_chain(inner, comments);
|
||||
}
|
||||
|
||||
return comments.has_trailing_own_line_comments(expr_attribute.value.as_ref());
|
||||
}
|
||||
|
||||
impl NeedsParentheses for ExprAttribute {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
if has_breaking_comments_attribute_chain(self, context.comments()) {
|
||||
return Parentheses::Always;
|
||||
}
|
||||
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
) -> OptionalParentheses {
|
||||
// Checks if there are any own line comments in an attribute chain (a.b.c).
|
||||
if context
|
||||
.comments()
|
||||
.dangling_comments(self)
|
||||
.iter()
|
||||
.any(|comment| comment.line_position().is_own_line())
|
||||
|| context.comments().has_trailing_own_line_comments(self)
|
||||
{
|
||||
OptionalParentheses::Always
|
||||
} else {
|
||||
self.value.needs_parentheses(parent, context)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue