mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-22 04:25:11 +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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprAwait;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -20,9 +19,9 @@ impl FormatNodeRule<ExprAwait> for FormatExprAwait {
|
|||
impl NeedsParentheses for ExprAwait {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
use crate::comments::{trailing_comments, trailing_node_comments};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, in_parentheses_only_group, is_expression_parenthesized,
|
||||
NeedsParentheses, Parenthesize,
|
||||
in_parentheses_only_group, is_expression_parenthesized, NeedsParentheses, OptionalParentheses,
|
||||
};
|
||||
use crate::expression::Parentheses;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
||||
use rustpython_parser::ast::{
|
||||
Constant, Expr, ExprAttribute, ExprBinOp, ExprConstant, ExprUnaryOp, Operator, UnaryOp,
|
||||
};
|
||||
|
@ -175,9 +174,9 @@ impl FormatRule<Operator, PyFormatContext<'_>> for FormatOperator {
|
|||
impl NeedsParentheses for ExprBinOp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::comments::leading_comments;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, in_parentheses_only_group, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
in_parentheses_only_group, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::{BoolOp, ExprBoolOp};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -70,10 +70,10 @@ impl FormatNodeRule<ExprBoolOp> for FormatExprBoolOp {
|
|||
impl NeedsParentheses for ExprBoolOp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,17 +1,18 @@
|
|||
use crate::builders::PyFormatterExtensions;
|
||||
use crate::comments::dangling_comments;
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::trivia::{SimpleTokenizer, TokenKind};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{format_with, group, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustpython_parser::ast::{Expr, ExprCall, Ranged};
|
||||
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
|
||||
use crate::comments::dangling_comments;
|
||||
|
||||
use crate::expression::parentheses::{
|
||||
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::trivia::{SimpleTokenizer, TokenKind};
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExprCall;
|
||||
|
||||
|
@ -52,14 +53,21 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|||
[argument] if keywords.is_empty() => {
|
||||
let parentheses =
|
||||
if is_single_argument_parenthesized(argument, item.end(), source) {
|
||||
Parenthesize::Always
|
||||
Parentheses::Always
|
||||
} else {
|
||||
Parenthesize::Never
|
||||
Parentheses::Never
|
||||
};
|
||||
joiner.entry(argument, &argument.format().with_options(parentheses));
|
||||
}
|
||||
arguments => {
|
||||
joiner.nodes(arguments).nodes(keywords.iter());
|
||||
joiner
|
||||
.entries(
|
||||
// We have the parentheses from the call so the arguments never need any
|
||||
arguments
|
||||
.iter()
|
||||
.map(|arg| (arg, arg.format().with_options(Parentheses::Preserve))),
|
||||
)
|
||||
.nodes(keywords.iter());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -100,13 +108,10 @@ impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|||
impl NeedsParentheses for ExprCall {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
) -> OptionalParentheses {
|
||||
self.func.needs_parentheses(parent, context)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::comments::leading_comments;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, in_parentheses_only_group, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
in_parentheses_only_group, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::{CmpOp, ExprCompare};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -73,10 +73,10 @@ impl FormatNodeRule<ExprCompare> for FormatExprCompare {
|
|||
impl NeedsParentheses for ExprCompare {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,17 @@
|
|||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::string::{FormatString, StringLayout};
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
use rustpython_parser::ast::{Constant, ExprConstant, Ranged};
|
||||
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_python_ast::str::is_implicit_concatenation;
|
||||
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::expression::string::{FormatString, StringPrefix, StringQuotes};
|
||||
use crate::prelude::*;
|
||||
use crate::{not_yet_implemented_custom_text, verbatim_text, FormatNodeRule};
|
||||
use ruff_formatter::{write, FormatRuleWithOptions};
|
||||
use rustpython_parser::ast::{Constant, ExprConstant};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatExprConstant {
|
||||
string_layout: StringLayout,
|
||||
}
|
||||
|
||||
impl FormatRuleWithOptions<ExprConstant, PyFormatContext<'_>> for FormatExprConstant {
|
||||
type Options = StringLayout;
|
||||
|
||||
fn with_options(mut self, options: Self::Options) -> Self {
|
||||
self.string_layout = options;
|
||||
self
|
||||
}
|
||||
}
|
||||
pub struct FormatExprConstant;
|
||||
|
||||
impl FormatNodeRule<ExprConstant> for FormatExprConstant {
|
||||
fn fmt_fields(&self, item: &ExprConstant, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
|
@ -39,7 +31,7 @@ impl FormatNodeRule<ExprConstant> for FormatExprConstant {
|
|||
Constant::Int(_) | Constant::Float(_) | Constant::Complex { .. } => {
|
||||
write!(f, [verbatim_text(item)])
|
||||
}
|
||||
Constant::Str(_) => FormatString::new(item, self.string_layout).fmt(f),
|
||||
Constant::Str(_) => FormatString::new(item).fmt(f),
|
||||
Constant::Bytes(_) => {
|
||||
not_yet_implemented_custom_text(r#"b"NOT_YET_IMPLEMENTED_BYTE_STRING""#).fmt(f)
|
||||
}
|
||||
|
@ -61,20 +53,32 @@ impl FormatNodeRule<ExprConstant> for FormatExprConstant {
|
|||
impl NeedsParentheses for ExprConstant {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
_parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional if self.value.is_str() && parenthesize.is_if_breaks() => {
|
||||
// Custom handling that only adds parentheses for implicit concatenated strings.
|
||||
if parenthesize.is_if_breaks() {
|
||||
Parentheses::Custom
|
||||
} else {
|
||||
Parentheses::Optional
|
||||
}
|
||||
) -> OptionalParentheses {
|
||||
if self.value.is_str() {
|
||||
let contents = context.locator().slice(self.range());
|
||||
// Don't wrap triple quoted strings
|
||||
if is_multiline_string(self, context.source()) || !is_implicit_concatenation(contents) {
|
||||
OptionalParentheses::Never
|
||||
} else {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
} else {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn is_multiline_string(constant: &ExprConstant, source: &str) -> bool {
|
||||
if constant.value.is_str() {
|
||||
let contents = &source[constant.range()];
|
||||
let prefix = StringPrefix::parse(contents);
|
||||
let quotes =
|
||||
StringQuotes::parse(&contents[TextRange::new(prefix.text_len(), contents.text_len())]);
|
||||
|
||||
quotes.map_or(false, StringQuotes::is_triple) && contents.contains(['\n', '\r'])
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use crate::comments::{dangling_node_comments, leading_comments};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::Ranged;
|
||||
use rustpython_parser::ast::{Expr, ExprDict};
|
||||
|
@ -99,12 +97,9 @@ impl FormatNodeRule<ExprDict> for FormatExprDict {
|
|||
impl NeedsParentheses for ExprDict {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprDictComp;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -23,12 +22,9 @@ impl FormatNodeRule<ExprDictComp> for FormatExprDictComp {
|
|||
impl NeedsParentheses for ExprDictComp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprFormattedValue;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -18,9 +17,9 @@ impl FormatNodeRule<ExprFormattedValue> for FormatExprFormattedValue {
|
|||
impl NeedsParentheses for ExprFormattedValue {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprGeneratorExp;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -23,12 +22,9 @@ impl FormatNodeRule<ExprGeneratorExp> for FormatExprGeneratorExp {
|
|||
impl NeedsParentheses for ExprGeneratorExp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::comments::leading_comments;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, in_parentheses_only_group, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
in_parentheses_only_group, NeedsParentheses, OptionalParentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprIfExp;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -46,9 +46,9 @@ impl FormatNodeRule<ExprIfExp> for FormatExprIfExp {
|
|||
impl NeedsParentheses for ExprIfExp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprJoinedStr;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -18,9 +17,9 @@ impl FormatNodeRule<ExprJoinedStr> for FormatExprJoinedStr {
|
|||
impl NeedsParentheses for ExprJoinedStr {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprLambda;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -23,9 +22,9 @@ impl FormatNodeRule<ExprLambda> for FormatExprLambda {
|
|||
impl NeedsParentheses for ExprLambda {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
use crate::comments::{dangling_comments, CommentLinePosition};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::{ExprList, Ranged};
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -71,12 +69,9 @@ impl FormatNodeRule<ExprList> for FormatExprList {
|
|||
impl NeedsParentheses for ExprList {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::AsFormat;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{format_args, write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprListComp;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -44,12 +42,9 @@ impl FormatNodeRule<ExprListComp> for FormatExprListComp {
|
|||
impl NeedsParentheses for ExprListComp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatContext};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprName;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -28,10 +27,10 @@ impl FormatNodeRule<ExprName> for FormatExprName {
|
|||
impl NeedsParentheses for ExprName {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprNamedExpr;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -33,14 +32,11 @@ impl FormatNodeRule<ExprNamedExpr> for FormatExprNamedExpr {
|
|||
impl NeedsParentheses for ExprNamedExpr {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
// Unlike tuples, named expression parentheses are not part of the range even when
|
||||
// mandatory. See [PEP 572](https://peps.python.org/pep-0572/) for details.
|
||||
Parentheses::Optional => Parentheses::Always,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
// Unlike tuples, named expression parentheses are not part of the range even when
|
||||
// mandatory. See [PEP 572](https://peps.python.org/pep-0572/) for details.
|
||||
OptionalParentheses::Always
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,8 @@
|
|||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{parenthesized, NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::format_args;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprSet;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -29,12 +27,9 @@ impl FormatNodeRule<ExprSet> for FormatExprSet {
|
|||
impl NeedsParentheses for ExprSet {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented_custom_text, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprSetComp;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -23,12 +22,9 @@ impl FormatNodeRule<ExprSetComp> for FormatExprSetComp {
|
|||
impl NeedsParentheses for ExprSetComp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
use crate::comments::{dangling_comments, SourceComment};
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::trivia::Token;
|
||||
use crate::trivia::{first_non_trivia_token, TokenKind};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{hard_line_break, line_suffix_boundary, space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatError, FormatResult};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::ExprSlice;
|
||||
use rustpython_parser::ast::{Expr, Ranged};
|
||||
|
@ -262,9 +260,9 @@ fn leading_comments_spacing(
|
|||
impl NeedsParentheses for ExprSlice {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
use rustpython_parser::ast::ExprStarred;
|
||||
|
||||
use ruff_formatter::write;
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
||||
|
@ -33,9 +32,9 @@ impl FormatNodeRule<ExprStarred> for FormatExprStarred {
|
|||
impl NeedsParentheses for ExprStarred {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
use rustpython_parser::ast::{Expr, ExprSubscript};
|
||||
|
||||
use ruff_formatter::{format_args, write};
|
||||
use ruff_python_ast::node::AstNode;
|
||||
use ruff_python_ast::node::{AnyNodeRef, AstNode};
|
||||
|
||||
use crate::comments::trailing_comments;
|
||||
use crate::context::NodeLevel;
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::expr_tuple::TupleParentheses;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, in_parentheses_only_group, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
in_parentheses_only_group, NeedsParentheses, OptionalParentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -87,12 +86,11 @@ impl FormatNodeRule<ExprSubscript> for FormatExprSubscript {
|
|||
impl NeedsParentheses for ExprSubscript {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
{
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use crate::builders::parenthesize_if_expands;
|
||||
use crate::comments::{dangling_comments, CommentLinePosition};
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, parenthesized, NeedsParentheses, Parentheses,
|
||||
Parenthesize,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use ruff_formatter::{format_args, write, FormatRuleWithOptions};
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::ExprTuple;
|
||||
use rustpython_parser::ast::{Expr, Ranged};
|
||||
|
||||
use ruff_formatter::{format_args, write, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
|
||||
use crate::builders::parenthesize_if_expands;
|
||||
use crate::comments::{dangling_comments, CommentLinePosition};
|
||||
use crate::expression::parentheses::{
|
||||
parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
|
||||
#[derive(Eq, PartialEq, Debug, Default)]
|
||||
pub enum TupleParentheses {
|
||||
/// Effectively `None` in `Option<Parentheses>`
|
||||
|
@ -148,13 +150,10 @@ impl Format<PyFormatContext<'_>> for ExprSequence<'_> {
|
|||
impl NeedsParentheses for ExprTuple {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => Parentheses::Never,
|
||||
parentheses => parentheses,
|
||||
}
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Never
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
use crate::comments::trailing_comments;
|
||||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::trivia::{SimpleTokenizer, TokenKind};
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{hard_line_break, space, text};
|
||||
use ruff_formatter::{Format, FormatContext, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_text_size::{TextLen, TextRange};
|
||||
use rustpython_parser::ast::UnaryOp;
|
||||
use rustpython_parser::ast::{ExprUnaryOp, Ranged};
|
||||
|
@ -70,19 +69,14 @@ impl FormatNodeRule<ExprUnaryOp> for FormatExprUnaryOp {
|
|||
impl NeedsParentheses for ExprUnaryOp {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
_parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
||||
Parentheses::Optional => {
|
||||
// We preserve the parentheses of the operand. It should not be necessary to break this expression.
|
||||
if is_operand_parenthesized(self, context.source()) {
|
||||
Parentheses::Never
|
||||
} else {
|
||||
Parentheses::Optional
|
||||
}
|
||||
}
|
||||
parentheses => parentheses,
|
||||
) -> OptionalParentheses {
|
||||
// We preserve the parentheses of the operand. It should not be necessary to break this expression.
|
||||
if is_operand_parenthesized(self, context.source()) {
|
||||
OptionalParentheses::Never
|
||||
} else {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprYield;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -18,9 +17,9 @@ impl FormatNodeRule<ExprYield> for FormatExprYield {
|
|||
impl NeedsParentheses for ExprYield {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
use crate::context::PyFormatContext;
|
||||
use crate::expression::parentheses::{
|
||||
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses};
|
||||
use crate::{not_yet_implemented, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::{write, Buffer, FormatResult};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::ExprYieldFrom;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -18,9 +17,9 @@ impl FormatNodeRule<ExprYieldFrom> for FormatExprYieldFrom {
|
|||
impl NeedsParentheses for ExprYieldFrom {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
default_expression_needs_parentheses(self.into(), parenthesize, context)
|
||||
_parent: AnyNodeRef,
|
||||
_context: &PyFormatContext,
|
||||
) -> OptionalParentheses {
|
||||
OptionalParentheses::Multiline
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
use rustpython_parser::ast;
|
||||
use rustpython_parser::ast::{Expr, Operator};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
use crate::builders::parenthesize_if_expands;
|
||||
use rustpython_parser::ast;
|
||||
use rustpython_parser::ast::{Expr, Operator};
|
||||
|
||||
use ruff_formatter::{FormatOwnedWithRule, FormatRefWithRule, FormatRule, FormatRuleWithOptions};
|
||||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use ruff_python_ast::visitor::preorder::{walk_expr, PreorderVisitor};
|
||||
|
||||
use crate::builders::parenthesize_if_expands;
|
||||
use crate::context::NodeLevel;
|
||||
use crate::expression::expr_tuple::TupleParentheses;
|
||||
use crate::expression::parentheses::{
|
||||
is_expression_parenthesized, optional_parentheses, parenthesized, NeedsParentheses,
|
||||
Parentheses, Parenthesize,
|
||||
OptionalParentheses, Parentheses, Parenthesize,
|
||||
};
|
||||
use crate::expression::string::StringLayout;
|
||||
use crate::prelude::*;
|
||||
|
||||
pub(crate) mod expr_attribute;
|
||||
|
@ -46,25 +46,25 @@ pub(crate) mod expr_yield_from;
|
|||
pub(crate) mod parentheses;
|
||||
pub(crate) mod string;
|
||||
|
||||
#[derive(Default)]
|
||||
#[derive(Copy, Clone, PartialEq, Eq, Default)]
|
||||
pub struct FormatExpr {
|
||||
parenthesize: Parenthesize,
|
||||
parentheses: Parentheses,
|
||||
}
|
||||
|
||||
impl FormatRuleWithOptions<Expr, PyFormatContext<'_>> for FormatExpr {
|
||||
type Options = Parenthesize;
|
||||
type Options = Parentheses;
|
||||
|
||||
fn with_options(mut self, options: Self::Options) -> Self {
|
||||
self.parenthesize = options;
|
||||
self.parentheses = options;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
|
||||
fn fmt(&self, item: &Expr, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let parentheses = item.needs_parentheses(self.parenthesize, f.context());
|
||||
fn fmt(&self, expression: &Expr, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let parentheses = self.parentheses;
|
||||
|
||||
let format_expr = format_with(|f| match item {
|
||||
let format_expr = format_with(|f| match expression {
|
||||
Expr::BoolOp(expr) => expr.format().with_options(Some(parentheses)).fmt(f),
|
||||
Expr::NamedExpr(expr) => expr.format().fmt(f),
|
||||
Expr::BinOp(expr) => expr.format().with_options(Some(parentheses)).fmt(f),
|
||||
|
@ -84,10 +84,7 @@ impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
|
|||
Expr::Call(expr) => expr.format().fmt(f),
|
||||
Expr::FormattedValue(expr) => expr.format().fmt(f),
|
||||
Expr::JoinedStr(expr) => expr.format().fmt(f),
|
||||
Expr::Constant(expr) => expr
|
||||
.format()
|
||||
.with_options(StringLayout::Default(Some(parentheses)))
|
||||
.fmt(f),
|
||||
Expr::Constant(expr) => expr.format().fmt(f),
|
||||
Expr::Attribute(expr) => expr.format().fmt(f),
|
||||
Expr::Subscript(expr) => expr.format().fmt(f),
|
||||
Expr::Starred(expr) => expr.format().fmt(f),
|
||||
|
@ -100,74 +97,136 @@ impl FormatRule<Expr, PyFormatContext<'_>> for FormatExpr {
|
|||
Expr::Slice(expr) => expr.format().fmt(f),
|
||||
});
|
||||
|
||||
let result = match parentheses {
|
||||
Parentheses::Always => parenthesized("(", &format_expr, ")").fmt(f),
|
||||
// Add optional parentheses. Ignore if the item renders parentheses itself.
|
||||
Parentheses::Optional => {
|
||||
if can_omit_optional_parentheses(item, f.context()) {
|
||||
optional_parentheses(&format_expr).fmt(f)
|
||||
} else {
|
||||
parenthesize_if_expands(&format_expr).fmt(f)
|
||||
}
|
||||
}
|
||||
Parentheses::Custom | Parentheses::Never => {
|
||||
let saved_level = f.context().node_level();
|
||||
|
||||
let new_level = match saved_level {
|
||||
NodeLevel::TopLevel | NodeLevel::CompoundStatement => {
|
||||
NodeLevel::Expression(None)
|
||||
}
|
||||
level @ (NodeLevel::Expression(_) | NodeLevel::ParenthesizedExpression) => {
|
||||
level
|
||||
}
|
||||
};
|
||||
|
||||
f.context_mut().set_node_level(new_level);
|
||||
|
||||
let result = Format::fmt(&format_expr, f);
|
||||
f.context_mut().set_node_level(saved_level);
|
||||
result
|
||||
let parenthesize = match parentheses {
|
||||
Parentheses::Preserve => {
|
||||
is_expression_parenthesized(AnyNodeRef::from(expression), f.context().source())
|
||||
}
|
||||
Parentheses::Always => true,
|
||||
Parentheses::Never => false,
|
||||
};
|
||||
|
||||
result
|
||||
if parenthesize {
|
||||
parenthesized("(", &format_expr, ")").fmt(f)
|
||||
} else {
|
||||
let saved_level = match f.context().node_level() {
|
||||
saved_level @ (NodeLevel::TopLevel | NodeLevel::CompoundStatement) => {
|
||||
f.context_mut().set_node_level(NodeLevel::Expression(None));
|
||||
Some(saved_level)
|
||||
}
|
||||
NodeLevel::Expression(_) | NodeLevel::ParenthesizedExpression => None,
|
||||
};
|
||||
|
||||
let result = Format::fmt(&format_expr, f);
|
||||
|
||||
if let Some(saved_level) = saved_level {
|
||||
f.context_mut().set_node_level(saved_level);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Wraps an expression in an optional parentheses except if its [`NeedsParentheses::needs_parentheses`] implementation
|
||||
/// indicates that it is okay to omit the parentheses. For example, parentheses can always be omitted for lists,
|
||||
/// because they already bring their own parentheses.
|
||||
pub(crate) fn maybe_parenthesize_expression<'a, T>(
|
||||
expression: &'a Expr,
|
||||
parent: T,
|
||||
parenthesize: Parenthesize,
|
||||
) -> MaybeParenthesizeExpression<'a>
|
||||
where
|
||||
T: Into<AnyNodeRef<'a>>,
|
||||
{
|
||||
MaybeParenthesizeExpression {
|
||||
expression,
|
||||
parent: parent.into(),
|
||||
parenthesize,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct MaybeParenthesizeExpression<'a> {
|
||||
expression: &'a Expr,
|
||||
parent: AnyNodeRef<'a>,
|
||||
parenthesize: Parenthesize,
|
||||
}
|
||||
|
||||
impl Format<PyFormatContext<'_>> for MaybeParenthesizeExpression<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
|
||||
let MaybeParenthesizeExpression {
|
||||
expression,
|
||||
parent,
|
||||
parenthesize,
|
||||
} = self;
|
||||
|
||||
let parenthesize = match parenthesize {
|
||||
Parenthesize::Optional => {
|
||||
is_expression_parenthesized(AnyNodeRef::from(*expression), f.context().source())
|
||||
}
|
||||
Parenthesize::IfBreaks => false,
|
||||
};
|
||||
|
||||
let parentheses =
|
||||
if parenthesize || f.context().comments().has_leading_comments(*expression) {
|
||||
OptionalParentheses::Always
|
||||
} else {
|
||||
expression.needs_parentheses(*parent, f.context())
|
||||
};
|
||||
|
||||
match parentheses {
|
||||
OptionalParentheses::Multiline => {
|
||||
if can_omit_optional_parentheses(expression, f.context()) {
|
||||
optional_parentheses(&expression.format().with_options(Parentheses::Never))
|
||||
.fmt(f)
|
||||
} else {
|
||||
parenthesize_if_expands(&expression.format().with_options(Parentheses::Never))
|
||||
.fmt(f)
|
||||
}
|
||||
}
|
||||
OptionalParentheses::Always => {
|
||||
expression.format().with_options(Parentheses::Always).fmt(f)
|
||||
}
|
||||
OptionalParentheses::Never => {
|
||||
expression.format().with_options(Parentheses::Never).fmt(f)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl NeedsParentheses for Expr {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
) -> OptionalParentheses {
|
||||
match self {
|
||||
Expr::BoolOp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::NamedExpr(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::BinOp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::UnaryOp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Lambda(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::IfExp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Dict(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Set(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::ListComp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::SetComp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::DictComp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::GeneratorExp(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Await(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Yield(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::YieldFrom(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Compare(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Call(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::FormattedValue(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::JoinedStr(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Constant(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Attribute(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Subscript(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Starred(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Name(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::List(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Tuple(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::Slice(expr) => expr.needs_parentheses(parenthesize, context),
|
||||
Expr::BoolOp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::NamedExpr(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::BinOp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::UnaryOp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Lambda(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::IfExp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Dict(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Set(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::ListComp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::SetComp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::DictComp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::GeneratorExp(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Await(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Yield(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::YieldFrom(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Compare(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Call(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::FormattedValue(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::JoinedStr(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Constant(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Attribute(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Subscript(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Starred(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Name(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::List(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Tuple(expr) => expr.needs_parentheses(parent, context),
|
||||
Expr::Slice(expr) => expr.needs_parentheses(parent, context),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,101 +6,50 @@ use ruff_formatter::{format_args, Argument, Arguments};
|
|||
use ruff_python_ast::node::AnyNodeRef;
|
||||
use rustpython_parser::ast::Ranged;
|
||||
|
||||
pub(crate) trait NeedsParentheses {
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses;
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) enum OptionalParentheses {
|
||||
/// Add parentheses if the expression expands over multiple lines
|
||||
Multiline,
|
||||
|
||||
/// Always set parentheses regardless if the expression breaks or if they were
|
||||
/// present in the source.
|
||||
Always,
|
||||
|
||||
/// Never add parentheses
|
||||
Never,
|
||||
}
|
||||
|
||||
pub(super) fn default_expression_needs_parentheses(
|
||||
node: AnyNodeRef,
|
||||
parenthesize: Parenthesize,
|
||||
context: &PyFormatContext,
|
||||
) -> Parentheses {
|
||||
debug_assert!(
|
||||
node.is_expression(),
|
||||
"Should only be called for expressions"
|
||||
);
|
||||
|
||||
#[allow(clippy::if_same_then_else)]
|
||||
if parenthesize.is_always() {
|
||||
Parentheses::Always
|
||||
} else if parenthesize.is_never() {
|
||||
Parentheses::Never
|
||||
}
|
||||
// `Optional` or `Preserve` and expression has parentheses in source code.
|
||||
else if !parenthesize.is_if_breaks() && is_expression_parenthesized(node, context.source()) {
|
||||
Parentheses::Always
|
||||
}
|
||||
// `Optional` or `IfBreaks`: Add parentheses if the expression doesn't fit on a line but enforce
|
||||
// parentheses if the expression has leading comments
|
||||
else if !parenthesize.is_preserve() {
|
||||
if context.comments().has_leading_comments(node) {
|
||||
Parentheses::Always
|
||||
} else {
|
||||
Parentheses::Optional
|
||||
}
|
||||
} else {
|
||||
//`Preserve` and expression has no parentheses in the source code
|
||||
Parentheses::Never
|
||||
}
|
||||
pub(crate) trait NeedsParentheses {
|
||||
/// Determines if this object needs optional parentheses or if it is safe to omit the parentheses.
|
||||
fn needs_parentheses(
|
||||
&self,
|
||||
parent: AnyNodeRef,
|
||||
context: &PyFormatContext,
|
||||
) -> OptionalParentheses;
|
||||
}
|
||||
|
||||
/// Configures if the expression should be parenthesized.
|
||||
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
|
||||
pub enum Parenthesize {
|
||||
/// Parenthesize the expression if it has parenthesis in the source.
|
||||
#[default]
|
||||
Preserve,
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub(crate) enum Parenthesize {
|
||||
/// Parenthesizes the expression if it doesn't fit on a line OR if the expression is parenthesized in the source code.
|
||||
Optional,
|
||||
|
||||
/// Parenthesizes the expression only if it doesn't fit on a line.
|
||||
IfBreaks,
|
||||
|
||||
/// Always adds parentheses
|
||||
Always,
|
||||
|
||||
/// Never adds parentheses. Parentheses are handled by the caller.
|
||||
Never,
|
||||
}
|
||||
|
||||
impl Parenthesize {
|
||||
pub(crate) const fn is_always(self) -> bool {
|
||||
matches!(self, Parenthesize::Always)
|
||||
}
|
||||
|
||||
pub(crate) const fn is_never(self) -> bool {
|
||||
matches!(self, Parenthesize::Never)
|
||||
}
|
||||
|
||||
pub(crate) const fn is_if_breaks(self) -> bool {
|
||||
matches!(self, Parenthesize::IfBreaks)
|
||||
}
|
||||
|
||||
pub(crate) const fn is_preserve(self) -> bool {
|
||||
matches!(self, Parenthesize::Preserve)
|
||||
}
|
||||
}
|
||||
|
||||
/// Whether it is necessary to add parentheses around an expression.
|
||||
/// This is different from [`Parenthesize`] in that it is the resolved representation: It takes into account
|
||||
/// whether there are parentheses in the source code or not.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq, Default)]
|
||||
pub enum Parentheses {
|
||||
#[default]
|
||||
Preserve,
|
||||
|
||||
/// Always set parentheses regardless if the expression breaks or if they were
|
||||
/// present in the source.
|
||||
Always,
|
||||
|
||||
/// Only add parentheses when necessary because the expression breaks over multiple lines.
|
||||
Optional,
|
||||
|
||||
/// Custom handling by the node's formatter implementation
|
||||
Custom,
|
||||
|
||||
/// Never add parentheses
|
||||
Never,
|
||||
}
|
||||
|
@ -182,20 +131,20 @@ impl<'ast> Format<PyFormatContext<'ast>> for FormatParenthesized<'_, 'ast> {
|
|||
/// a parentheses (`()`, `[]`, `{}`).
|
||||
pub(crate) fn optional_parentheses<'content, 'ast, Content>(
|
||||
content: &'content Content,
|
||||
) -> OptionalParentheses<'content, 'ast>
|
||||
) -> FormatOptionalParentheses<'content, 'ast>
|
||||
where
|
||||
Content: Format<PyFormatContext<'ast>>,
|
||||
{
|
||||
OptionalParentheses {
|
||||
FormatOptionalParentheses {
|
||||
content: Argument::new(content),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct OptionalParentheses<'content, 'ast> {
|
||||
pub(crate) struct FormatOptionalParentheses<'content, 'ast> {
|
||||
content: Argument<'content, PyFormatContext<'ast>>,
|
||||
}
|
||||
|
||||
impl<'ast> Format<PyFormatContext<'ast>> for OptionalParentheses<'_, 'ast> {
|
||||
impl<'ast> Format<PyFormatContext<'ast>> for FormatOptionalParentheses<'_, 'ast> {
|
||||
fn fmt(&self, f: &mut Formatter<PyFormatContext<'ast>>) -> FormatResult<()> {
|
||||
let saved_level = f.context().node_level();
|
||||
|
||||
|
|
|
@ -1,41 +1,27 @@
|
|||
use crate::builders::parenthesize_if_expands;
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::expression::parentheses::Parentheses;
|
||||
use crate::prelude::*;
|
||||
use crate::QuoteStyle;
|
||||
use std::borrow::Cow;
|
||||
|
||||
use bitflags::bitflags;
|
||||
use ruff_formatter::{format_args, write, FormatError};
|
||||
use ruff_python_ast::str::is_implicit_concatenation;
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
use rustpython_parser::ast::{ExprConstant, Ranged};
|
||||
use rustpython_parser::lexer::{lex_starts_at, LexicalError, LexicalErrorType};
|
||||
use rustpython_parser::{Mode, Tok};
|
||||
use std::borrow::Cow;
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
pub enum StringLayout {
|
||||
Default(Option<Parentheses>),
|
||||
use ruff_formatter::{format_args, write, FormatError};
|
||||
use ruff_python_ast::str::is_implicit_concatenation;
|
||||
|
||||
/// Enforces that implicit continuation strings are printed on a single line even if they exceed
|
||||
/// the configured line width.
|
||||
Flat,
|
||||
}
|
||||
|
||||
impl Default for StringLayout {
|
||||
fn default() -> Self {
|
||||
Self::Default(None)
|
||||
}
|
||||
}
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::expression::parentheses::in_parentheses_only_group;
|
||||
use crate::prelude::*;
|
||||
use crate::QuoteStyle;
|
||||
|
||||
pub(super) struct FormatString<'a> {
|
||||
constant: &'a ExprConstant,
|
||||
layout: StringLayout,
|
||||
}
|
||||
|
||||
impl<'a> FormatString<'a> {
|
||||
pub(super) fn new(constant: &'a ExprConstant, layout: StringLayout) -> Self {
|
||||
pub(super) fn new(constant: &'a ExprConstant) -> Self {
|
||||
debug_assert!(constant.value.is_str());
|
||||
Self { constant, layout }
|
||||
Self { constant }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -45,13 +31,7 @@ impl<'a> Format<PyFormatContext<'_>> for FormatString<'a> {
|
|||
let string_content = f.context().locator().slice(string_range);
|
||||
|
||||
if is_implicit_concatenation(string_content) {
|
||||
let format_continuation = FormatStringContinuation::new(self.constant, self.layout);
|
||||
|
||||
if let StringLayout::Default(Some(Parentheses::Custom)) = self.layout {
|
||||
parenthesize_if_expands(&format_continuation).fmt(f)
|
||||
} else {
|
||||
format_continuation.fmt(f)
|
||||
}
|
||||
in_parentheses_only_group(&FormatStringContinuation::new(self.constant)).fmt(f)
|
||||
} else {
|
||||
FormatStringPart::new(string_range).fmt(f)
|
||||
}
|
||||
|
@ -60,13 +40,12 @@ impl<'a> Format<PyFormatContext<'_>> for FormatString<'a> {
|
|||
|
||||
struct FormatStringContinuation<'a> {
|
||||
constant: &'a ExprConstant,
|
||||
layout: StringLayout,
|
||||
}
|
||||
|
||||
impl<'a> FormatStringContinuation<'a> {
|
||||
fn new(constant: &'a ExprConstant, layout: StringLayout) -> Self {
|
||||
fn new(constant: &'a ExprConstant) -> Self {
|
||||
debug_assert!(constant.value.is_str());
|
||||
Self { constant, layout }
|
||||
Self { constant }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,12 +64,7 @@ impl Format<PyFormatContext<'_>> for FormatStringContinuation<'_> {
|
|||
// because this is a black preview style.
|
||||
let lexer = lex_starts_at(string_content, Mode::Expression, string_range.start());
|
||||
|
||||
let separator = format_with(|f| match self.layout {
|
||||
StringLayout::Default(_) => soft_line_break_or_space().fmt(f),
|
||||
StringLayout::Flat => space().fmt(f),
|
||||
});
|
||||
|
||||
let mut joiner = f.join_with(separator);
|
||||
let mut joiner = f.join_with(soft_line_break_or_space());
|
||||
|
||||
for token in lexer {
|
||||
let (token, token_range) = match token {
|
||||
|
@ -220,7 +194,7 @@ impl Format<PyFormatContext<'_>> for FormatStringPart {
|
|||
|
||||
bitflags! {
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct StringPrefix: u8 {
|
||||
pub(super) struct StringPrefix: u8 {
|
||||
const UNICODE = 0b0000_0001;
|
||||
/// `r"test"`
|
||||
const RAW = 0b0000_0010;
|
||||
|
@ -232,7 +206,7 @@ bitflags! {
|
|||
}
|
||||
|
||||
impl StringPrefix {
|
||||
fn parse(input: &str) -> StringPrefix {
|
||||
pub(super) fn parse(input: &str) -> StringPrefix {
|
||||
let chars = input.chars();
|
||||
let mut prefix = StringPrefix::empty();
|
||||
|
||||
|
@ -257,7 +231,7 @@ impl StringPrefix {
|
|||
prefix
|
||||
}
|
||||
|
||||
const fn text_len(self) -> TextSize {
|
||||
pub(super) const fn text_len(self) -> TextSize {
|
||||
TextSize::new(self.bits().count_ones())
|
||||
}
|
||||
}
|
||||
|
@ -383,13 +357,13 @@ fn preferred_quotes(
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
struct StringQuotes {
|
||||
pub(super) struct StringQuotes {
|
||||
triple: bool,
|
||||
style: QuoteStyle,
|
||||
}
|
||||
|
||||
impl StringQuotes {
|
||||
fn parse(input: &str) -> Option<StringQuotes> {
|
||||
pub(super) fn parse(input: &str) -> Option<StringQuotes> {
|
||||
let mut chars = input.chars();
|
||||
|
||||
let quote_char = chars.next()?;
|
||||
|
@ -400,6 +374,10 @@ impl StringQuotes {
|
|||
Some(Self { triple, style })
|
||||
}
|
||||
|
||||
pub(super) const fn is_triple(self) -> bool {
|
||||
self.triple
|
||||
}
|
||||
|
||||
const fn text_len(self) -> TextSize {
|
||||
if self.triple {
|
||||
TextSize::new(3)
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -18,7 +19,7 @@ impl FormatNodeRule<Decorator> for FormatDecorator {
|
|||
f,
|
||||
[
|
||||
text("@"),
|
||||
expression.format().with_options(Parenthesize::Optional)
|
||||
maybe_parenthesize_expression(expression, item, Parenthesize::Optional)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::comments::trailing_comments;
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
|
@ -60,7 +61,10 @@ impl FormatNodeRule<ExceptHandlerExceptHandler> for FormatExceptHandlerExceptHan
|
|||
if let Some(type_) = type_ {
|
||||
write!(
|
||||
f,
|
||||
[space(), type_.format().with_options(Parenthesize::IfBreaks)]
|
||||
[
|
||||
space(),
|
||||
maybe_parenthesize_expression(type_, item, Parenthesize::IfBreaks)
|
||||
]
|
||||
)?;
|
||||
if let Some(name) = name {
|
||||
write!(f, [space(), text("as"), space(), name.format()])?;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
|
@ -18,7 +19,11 @@ impl FormatNodeRule<WithItem> for FormatWithItem {
|
|||
let inner = format_with(|f| {
|
||||
write!(
|
||||
f,
|
||||
[context_expr.format().with_options(Parenthesize::IfBreaks)]
|
||||
[maybe_parenthesize_expression(
|
||||
context_expr,
|
||||
item,
|
||||
Parenthesize::IfBreaks
|
||||
)]
|
||||
)?;
|
||||
if let Some(optional_vars) = optional_vars {
|
||||
write!(f, [space(), text("as"), space(), optional_vars.format()])?;
|
||||
|
|
|
@ -2,6 +2,7 @@ use rustpython_parser::ast::StmtAssign;
|
|||
|
||||
use ruff_formatter::write;
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -26,6 +27,13 @@ impl FormatNodeRule<StmtAssign> for FormatStmtAssign {
|
|||
write!(f, [target.format(), space(), text("="), space()])?;
|
||||
}
|
||||
|
||||
write!(f, [value.format().with_options(Parenthesize::IfBreaks)])
|
||||
write!(
|
||||
f,
|
||||
[maybe_parenthesize_expression(
|
||||
value,
|
||||
item,
|
||||
Parenthesize::IfBreaks
|
||||
)]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
use rustpython_parser::ast::StmtAsyncFunctionDef;
|
||||
|
||||
use ruff_python_ast::function::AnyFunctionDefinition;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_python_ast::function::AnyFunctionDefinition;
|
||||
use rustpython_parser::ast::StmtAsyncFunctionDef;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtAsyncFunctionDef;
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
|
@ -23,7 +24,7 @@ impl FormatNodeRule<StmtAugAssign> for FormatStmtAugAssign {
|
|||
op.format(),
|
||||
text("="),
|
||||
space(),
|
||||
value.format().with_options(Parenthesize::IfBreaks)
|
||||
maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks)
|
||||
]
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::comments::trailing_comments;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
|
||||
use crate::expression::parentheses::Parentheses;
|
||||
use crate::prelude::*;
|
||||
use crate::trivia::{SimpleTokenizer, TokenKind};
|
||||
use ruff_formatter::{format_args, write};
|
||||
|
@ -100,13 +101,13 @@ impl Format<PyFormatContext<'_>> for FormatInheritanceClause<'_> {
|
|||
.count();
|
||||
|
||||
// Ignore the first parentheses count
|
||||
let parenthesize = if left_paren_count > 1 {
|
||||
Parenthesize::Always
|
||||
let parentheses = if left_paren_count > 1 {
|
||||
Parentheses::Always
|
||||
} else {
|
||||
Parenthesize::Never
|
||||
Parentheses::Never
|
||||
};
|
||||
|
||||
joiner.entry(first, &first.format().with_options(parenthesize));
|
||||
joiner.entry(first, &first.format().with_options(parentheses));
|
||||
joiner.nodes(rest.iter());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use crate::builders::{parenthesize_if_expands, PyFormatterExtensions};
|
||||
use crate::comments::dangling_node_comments;
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{block_indent, format_with, space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use rustpython_parser::ast::{Ranged, StmtDelete};
|
||||
|
@ -32,7 +33,14 @@ impl FormatNodeRule<StmtDelete> for FormatStmtDelete {
|
|||
)
|
||||
}
|
||||
[single] => {
|
||||
write!(f, [single.format().with_options(Parenthesize::IfBreaks)])
|
||||
write!(
|
||||
f,
|
||||
[maybe_parenthesize_expression(
|
||||
single,
|
||||
item,
|
||||
Parenthesize::IfBreaks
|
||||
)]
|
||||
)
|
||||
}
|
||||
targets => {
|
||||
let item = format_with(|f| {
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::expression::parentheses::{is_expression_parenthesized, Parenthesize};
|
||||
use crate::expression::string::StringLayout;
|
||||
use rustpython_parser::ast::StmtExpr;
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
use rustpython_parser::ast::StmtExpr;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtExpr;
|
||||
|
@ -11,14 +12,6 @@ impl FormatNodeRule<StmtExpr> for FormatStmtExpr {
|
|||
fn fmt_fields(&self, item: &StmtExpr, f: &mut PyFormatter) -> FormatResult<()> {
|
||||
let StmtExpr { value, .. } = item;
|
||||
|
||||
if let Some(constant) = value.as_constant_expr() {
|
||||
if constant.value.is_str()
|
||||
&& !is_expression_parenthesized(value.as_ref().into(), f.context().source())
|
||||
{
|
||||
return constant.format().with_options(StringLayout::Flat).fmt(f);
|
||||
}
|
||||
}
|
||||
|
||||
value.format().with_options(Parenthesize::Optional).fmt(f)
|
||||
maybe_parenthesize_expression(value, item, Parenthesize::Optional).fmt(f)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::comments::{leading_alternate_branch_comments, trailing_comments};
|
||||
use crate::expression::expr_tuple::TupleParentheses;
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
|
@ -17,7 +18,7 @@ impl Format<PyFormatContext<'_>> for ExprTupleWithoutParentheses<'_> {
|
|||
.format()
|
||||
.with_options(TupleParentheses::StripInsideForLoop)
|
||||
.fmt(f),
|
||||
other => other.format().with_options(Parenthesize::IfBreaks).fmt(f),
|
||||
other => maybe_parenthesize_expression(other, self.0, Parenthesize::IfBreaks).fmt(f),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -54,7 +55,7 @@ impl FormatNodeRule<StmtFor> for FormatStmtFor {
|
|||
space(),
|
||||
text("in"),
|
||||
space(),
|
||||
iter.format().with_options(Parenthesize::IfBreaks),
|
||||
maybe_parenthesize_expression(iter, item, Parenthesize::IfBreaks),
|
||||
text(":"),
|
||||
trailing_comments(trailing_condition_comments),
|
||||
block_indent(&body.format())
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
use rustpython_parser::ast::{Ranged, StmtFunctionDef};
|
||||
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule};
|
||||
use ruff_python_ast::function::AnyFunctionDefinition;
|
||||
|
||||
use crate::comments::{leading_comments, trailing_comments};
|
||||
use crate::context::NodeLevel;
|
||||
use crate::expression::parentheses::{optional_parentheses, Parenthesize};
|
||||
use crate::expression::parentheses::{optional_parentheses, Parentheses};
|
||||
use crate::prelude::*;
|
||||
use crate::trivia::{lines_after, skip_trailing_trivia};
|
||||
use crate::FormatNodeRule;
|
||||
use ruff_formatter::{write, FormatOwnedWithRule, FormatRefWithRule};
|
||||
use ruff_python_ast::function::AnyFunctionDefinition;
|
||||
use rustpython_parser::ast::{Ranged, StmtFunctionDef};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct FormatStmtFunctionDef;
|
||||
|
@ -98,7 +100,7 @@ impl FormatRule<AnyFunctionDefinition<'_>, PyFormatContext<'_>> for FormatAnyFun
|
|||
text("->"),
|
||||
space(),
|
||||
optional_parentheses(
|
||||
&return_annotation.format().with_options(Parenthesize::Never)
|
||||
&return_annotation.format().with_options(Parentheses::Never)
|
||||
)
|
||||
]
|
||||
)?;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::comments::{leading_alternate_branch_comments, trailing_comments, SourceComment};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -48,7 +49,7 @@ impl FormatNodeRule<StmtIf> for FormatStmtIf {
|
|||
[
|
||||
text(current.keyword()),
|
||||
space(),
|
||||
test.format().with_options(Parenthesize::IfBreaks),
|
||||
maybe_parenthesize_expression(test, current_statement, Parenthesize::IfBreaks),
|
||||
text(":"),
|
||||
trailing_comments(if_trailing_comments),
|
||||
block_indent(&body.format())
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use rustpython_parser::ast::StmtRaise;
|
||||
|
||||
#[derive(Default)]
|
||||
|
@ -21,7 +22,10 @@ impl FormatNodeRule<StmtRaise> for FormatStmtRaise {
|
|||
if let Some(value) = exc {
|
||||
write!(
|
||||
f,
|
||||
[space(), value.format().with_options(Parenthesize::Optional)]
|
||||
[
|
||||
space(),
|
||||
maybe_parenthesize_expression(value, item, Parenthesize::Optional)
|
||||
]
|
||||
)?;
|
||||
}
|
||||
|
||||
|
@ -32,7 +36,7 @@ impl FormatNodeRule<StmtRaise> for FormatStmtRaise {
|
|||
space(),
|
||||
text("from"),
|
||||
space(),
|
||||
value.format().with_options(Parenthesize::Optional)
|
||||
maybe_parenthesize_expression(value, item, Parenthesize::Optional)
|
||||
]
|
||||
)?;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::{AsFormat, FormatNodeRule, PyFormatter};
|
||||
use crate::{FormatNodeRule, PyFormatter};
|
||||
use ruff_formatter::prelude::{space, text};
|
||||
use ruff_formatter::{write, Buffer, Format, FormatResult};
|
||||
use rustpython_parser::ast::StmtReturn;
|
||||
|
@ -16,7 +17,7 @@ impl FormatNodeRule<StmtReturn> for FormatStmtReturn {
|
|||
[
|
||||
text("return"),
|
||||
space(),
|
||||
value.format().with_options(Parenthesize::IfBreaks)
|
||||
maybe_parenthesize_expression(value, item, Parenthesize::IfBreaks)
|
||||
]
|
||||
)
|
||||
} else {
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
use crate::comments::{leading_alternate_branch_comments, trailing_comments};
|
||||
use crate::expression::maybe_parenthesize_expression;
|
||||
use crate::expression::parentheses::Parenthesize;
|
||||
use crate::prelude::*;
|
||||
use crate::FormatNodeRule;
|
||||
|
@ -33,7 +34,7 @@ impl FormatNodeRule<StmtWhile> for FormatStmtWhile {
|
|||
[
|
||||
text("while"),
|
||||
space(),
|
||||
test.format().with_options(Parenthesize::IfBreaks),
|
||||
maybe_parenthesize_expression(test, item, Parenthesize::IfBreaks),
|
||||
text(":"),
|
||||
trailing_comments(trailing_condition_comments),
|
||||
block_indent(&body.format())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue