Skip to content

Commit

Permalink
Ungroup
Browse files Browse the repository at this point in the history
  • Loading branch information
charliermarsh committed Aug 8, 2023
1 parent 833c02b commit 4f7d0fd
Show file tree
Hide file tree
Showing 3 changed files with 89 additions and 46 deletions.
87 changes: 61 additions & 26 deletions crates/ruff_python_formatter/src/expression/parentheses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ where
comments: &[],
content: Argument::new(content),
right,
ungroup: false,
}
}

Expand All @@ -123,6 +124,7 @@ pub(crate) struct FormatParenthesized<'content, 'ast> {
comments: &'content [SourceComment],
content: Argument<'content, PyFormatContext<'ast>>,
right: &'static str,
ungroup: bool,
}

impl<'content, 'ast> FormatParenthesized<'content, 'ast> {
Expand All @@ -141,26 +143,38 @@ impl<'content, 'ast> FormatParenthesized<'content, 'ast> {
) -> FormatParenthesized<'content, 'ast> {
FormatParenthesized { comments, ..self }
}

/// Avoid grouping the parenthesized contents.
pub(crate) fn with_ungroup(self) -> FormatParenthesized<'content, 'ast> {
FormatParenthesized {
ungroup: true,
..self
}
}
}

impl<'ast> Format<PyFormatContext<'ast>> for FormatParenthesized<'_, 'ast> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'ast>>) -> FormatResult<()> {
let inner = format_with(|f| {
if self.comments.is_empty() {
group(&format_args![
text(self.left),
&soft_block_indent(&Arguments::from(&self.content)),
text(self.right)
])
.fmt(f)
write!(
f,
[
text(self.left),
&soft_block_indent(&Arguments::from(&self.content)),
text(self.right)
]
)
} else {
group(&format_args![
text(self.left),
&dangling_open_parenthesis_comments(self.comments),
&soft_block_indent(&Arguments::from(&self.content)),
text(self.right)
])
.fmt(f)
write!(
f,
[
text(self.left),
&dangling_open_parenthesis_comments(self.comments),
&soft_block_indent(&Arguments::from(&self.content)),
text(self.right)
]
)
}
});

Expand All @@ -173,12 +187,14 @@ impl<'ast> Format<PyFormatContext<'ast>> for FormatParenthesized<'_, 'ast> {
// This ensures that expanding this parenthesized expression does not expand the optional parentheses group.
write!(
f,
[fits_expanded(&inner)
[fits_expanded(&group(&inner))
.with_condition(Some(Condition::if_group_fits_on_line(group_id)))]
)
} else if self.ungroup {
write!(f, [inner])
} else {
// It's not necessary to wrap the content if it is not inside of an optional_parentheses group.
write!(f, [inner])
write!(f, [group(&inner)])
}
}
}
Expand Down Expand Up @@ -337,13 +353,15 @@ pub(crate) fn empty_parenthesized<'content>(
left,
comments: &[],
right,
ungroup: false,
}
}

pub(crate) struct FormatEmptyParenthesized<'content> {
left: &'static str,
comments: &'content [SourceComment],
right: &'static str,
ungroup: bool,
}

impl<'content> FormatEmptyParenthesized<'content> {
Expand All @@ -360,6 +378,14 @@ impl<'content> FormatEmptyParenthesized<'content> {
) -> FormatEmptyParenthesized<'content> {
FormatEmptyParenthesized { comments, ..self }
}

/// Avoid grouping the parenthesized contents.
pub(crate) fn with_ungroup(self) -> FormatEmptyParenthesized<'content> {
FormatEmptyParenthesized {
ungroup: true,
..self
}
}
}

impl Format<PyFormatContext<'_>> for FormatEmptyParenthesized<'_> {
Expand All @@ -370,17 +396,26 @@ impl Format<PyFormatContext<'_>> for FormatEmptyParenthesized<'_> {
debug_assert!(self.comments[end_of_line_split..]
.iter()
.all(|comment| comment.line_position().is_own_line()));
write!(
f,
[group(&format_args![
text(self.left),
// end-of-line comments
trailing_comments(&self.comments[..end_of_line_split]),
// own line comments, which need to be indented
soft_block_indent(&dangling_comments(&self.comments[end_of_line_split..])),
text(self.right)
])]
)

let inner = format_with(|f| {
write!(
f,
[
text(self.left),
// end-of-line comments
trailing_comments(&self.comments[..end_of_line_split]),
// own line comments, which need to be indented
soft_block_indent(&dangling_comments(&self.comments[end_of_line_split..])),
text(self.right)
]
)
});

if self.ungroup {
write!(f, [inner])
} else {
write!(f, [group(&inner)])
}
}
}

Expand Down
7 changes: 5 additions & 2 deletions crates/ruff_python_formatter/src/other/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -246,13 +246,16 @@ impl FormatNodeRule<Parameters> for FormatParameters {
// No parameters, format any dangling comments between `()`
write!(
f,
[empty_parenthesized("(", ")").with_dangling_comments(dangling)]
[empty_parenthesized("(", ")")
.with_dangling_comments(dangling)
.with_ungroup()]
)
} else {
write!(
f,
[parenthesized("(", &group(&format_inner), ")")
.with_dangling_comments(parenthesis_dangling)]
.with_dangling_comments(parenthesis_dangling)
.with_ungroup()]
)
}
}
Expand Down
41 changes: 23 additions & 18 deletions crates/ruff_python_formatter/src/statement/stmt_function_def.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,29 +54,34 @@ impl FormatNodeRule<StmtFunctionDef> for FormatStmtFunctionDef {

write!(f, [text("def"), space(), item.name.format()])?;

if let Some(type_params) = item.type_params.as_ref() {
write!(f, [type_params.format()])?;
}
let format_inner = format_with(|f: &mut PyFormatter| {
if let Some(type_params) = item.type_params.as_ref() {
write!(f, [type_params.format()])?;
}

write!(f, [item.parameters.format()])?;

if let Some(return_annotation) = item.returns.as_ref() {
write!(
f,
[
space(),
text("->"),
space(),
optional_parentheses(
&return_annotation.format().with_options(Parentheses::Never)
)
]
)?;
}
write!(f, [item.parameters.format()])?;

if let Some(return_annotation) = item.returns.as_ref() {
write!(
f,
[
space(),
text("->"),
space(),
optional_parentheses(
&return_annotation.format().with_options(Parentheses::Never)
)
]
)?;
}

Ok(())
});

write!(
f,
[
group(&format_inner),
text(":"),
trailing_comments(trailing_definition_comments),
block_indent(&item.body.format().with_options(SuiteKind::Function))
Expand Down

0 comments on commit 4f7d0fd

Please sign in to comment.