Pass parent to NeedsParentheses (#5708)

This commit is contained in:
Micha Reiser 2023-07-13 08:57:29 +02:00 committed by GitHub
parent 30702c2977
commit 067b2a6ce6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 562 additions and 606 deletions

View file

@ -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)
}
}
}