mirror of https://github.com/astral-sh/ruff
100 lines
3.2 KiB
Rust
100 lines
3.2 KiB
Rust
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::{AsFormat, FormatNodeRule, PyFormatter};
|
|
use ruff_formatter::prelude::{format_with, group, text};
|
|
use ruff_formatter::{write, Buffer, FormatResult};
|
|
use rustpython_parser::ast::ExprCall;
|
|
|
|
#[derive(Default)]
|
|
pub struct FormatExprCall;
|
|
|
|
impl FormatNodeRule<ExprCall> for FormatExprCall {
|
|
fn fmt_fields(&self, item: &ExprCall, f: &mut PyFormatter) -> FormatResult<()> {
|
|
let ExprCall {
|
|
range: _,
|
|
func,
|
|
args,
|
|
keywords,
|
|
} = item;
|
|
|
|
// We have a case with `f()` without any argument, which is a special case because we can
|
|
// have a comment with no node attachment inside:
|
|
// ```python
|
|
// f(
|
|
// # This function has a dangling comment
|
|
// )
|
|
// ```
|
|
if args.is_empty() && keywords.is_empty() {
|
|
let comments = f.context().comments().clone();
|
|
let comments = comments.dangling_comments(item);
|
|
return write!(
|
|
f,
|
|
[
|
|
func.format(),
|
|
text("("),
|
|
dangling_comments(comments),
|
|
text(")")
|
|
]
|
|
);
|
|
}
|
|
|
|
let all_args = format_with(|f| {
|
|
f.join_comma_separated()
|
|
.entries(
|
|
// We have the parentheses from the call so the arguments never need any
|
|
args.iter()
|
|
.map(|arg| (arg, arg.format().with_options(Parenthesize::Never))),
|
|
)
|
|
.nodes(keywords.iter())
|
|
.finish()
|
|
});
|
|
|
|
write!(
|
|
f,
|
|
[
|
|
func.format(),
|
|
// The outer group is for things like
|
|
// ```python
|
|
// get_collection(
|
|
// hey_this_is_a_very_long_call,
|
|
// it_has_funny_attributes_asdf_asdf,
|
|
// too_long_for_the_line,
|
|
// really=True,
|
|
// )
|
|
// ```
|
|
// The inner group is for things like:
|
|
// ```python
|
|
// get_collection(
|
|
// hey_this_is_a_very_long_call, it_has_funny_attributes_asdf_asdf, really=True
|
|
// )
|
|
// ```
|
|
// TODO(konstin): Doesn't work see wrongly formatted test
|
|
parenthesized("(", &group(&all_args), ")")
|
|
]
|
|
)
|
|
}
|
|
|
|
fn fmt_dangling_comments(&self, _node: &ExprCall, _f: &mut PyFormatter) -> FormatResult<()> {
|
|
// Handled in `fmt_fields`
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl NeedsParentheses for ExprCall {
|
|
fn needs_parentheses(
|
|
&self,
|
|
parenthesize: Parenthesize,
|
|
context: &PyFormatContext,
|
|
) -> Parentheses {
|
|
match default_expression_needs_parentheses(self.into(), parenthesize, context) {
|
|
Parentheses::Optional => Parentheses::Never,
|
|
parentheses => parentheses,
|
|
}
|
|
}
|
|
}
|