use ruff_formatter::write;
use ruff_python_ast::StmtAnnAssign;
use crate::expression::is_splittable_expression;
use crate::expression::parentheses::{NeedsParentheses, OptionalParentheses, Parentheses};
use crate::prelude::*;
use crate::statement::stmt_assign::{
AnyAssignmentOperator, AnyBeforeOperator, FormatStatementsLastExpression,
};
use crate::statement::trailing_semicolon;
#[derive(Default)]
pub struct FormatStmtAnnAssign;
impl FormatNodeRule<StmtAnnAssign> for FormatStmtAnnAssign {
fn fmt_fields(&self, item: &StmtAnnAssign, f: &mut PyFormatter) -> FormatResult<()> {
let StmtAnnAssign {
range: _,
node_index: _,
target,
annotation,
value,
simple: _,
} = item;
let comments = f.context().comments().clone();
let annotation_parentheses = annotation
.as_ref()
.needs_parentheses(item.into(), f.context());
write!(f, [target.format(), token(":"), space()])?;
if let Some(value) = value {
if annotation_parentheses != OptionalParentheses::Always
&& is_splittable_expression(annotation, f.context())
{
FormatStatementsLastExpression::RightToLeft {
before_operator: AnyBeforeOperator::Expression(annotation),
operator: AnyAssignmentOperator::Assign,
value,
statement: item.into(),
}
.fmt(f)?;
} else {
let parentheses = if comments.has_leading(annotation.as_ref())
|| comments.has_trailing(annotation.as_ref())
|| annotation_parentheses == OptionalParentheses::Always
{
Parentheses::Always
} else {
Parentheses::Never
};
annotation.format().with_options(parentheses).fmt(f)?;
write!(
f,
[
space(),
token("="),
space(),
FormatStatementsLastExpression::left_to_right(value, item)
]
)?;
}
} else if annotation_parentheses == OptionalParentheses::Always {
annotation
.format()
.with_options(Parentheses::Always)
.fmt(f)?;
} else {
FormatStatementsLastExpression::left_to_right(annotation, item).fmt(f)?;
}
if f.options().source_type().is_ipynb()
&& f.context().node_level().is_last_top_level_statement()
&& target.is_name_expr()
&& trailing_semicolon(item.into(), f.context().source()).is_some()
{
token(";").fmt(f)?;
}
Ok(())
}
}