Skip to content

Commit

Permalink
Properly group assignment targets
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Jul 13, 2023
1 parent 067b2a6 commit 7854933
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@

# Break the last element
a = asdf = fjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfal = 1

aa = [
bakjdshflkjahdslkfjlasfdahjlfds
] = dddd = ddd = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3
6 changes: 5 additions & 1 deletion crates/ruff_python_formatter/src/expression/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,6 +443,10 @@ impl<'input> PreorderVisitor<'input> for CanOmitOptionalParenthesesVisitor<'inpu
}

fn has_parentheses(expr: &Expr, source: &str) -> bool {
has_own_parentheses(expr) || is_expression_parenthesized(AnyNodeRef::from(expr), source)
}

pub(crate) const fn has_own_parentheses(expr: &Expr) -> bool {
matches!(
expr,
Expr::Dict(_)
Expand All @@ -454,7 +458,7 @@ fn has_parentheses(expr: &Expr, source: &str) -> bool {
| Expr::DictComp(_)
| Expr::Call(_)
| Expr::Subscript(_)
) || is_expression_parenthesized(AnyNodeRef::from(expr), source)
)
}

#[derive(Debug, Copy, Clone, Ord, PartialOrd, Eq, PartialEq)]
Expand Down
84 changes: 73 additions & 11 deletions crates/ruff_python_formatter/src/statement/stmt_assign.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
use rustpython_parser::ast::StmtAssign;
use rustpython_parser::ast::{Expr, StmtAssign};

use ruff_formatter::write;
use ruff_formatter::{format_args, write, FormatError};

use crate::expression::maybe_parenthesize_expression;
use crate::expression::parentheses::Parenthesize;
use crate::context::NodeLevel;
use crate::expression::parentheses::{Parentheses, Parenthesize};
use crate::expression::{has_own_parentheses, maybe_parenthesize_expression};
use crate::prelude::*;
use crate::FormatNodeRule;

// Note: This currently does wrap but not the black way so the types below likely need to be
// replaced entirely
//

#[derive(Default)]
pub struct FormatStmtAssign;

Expand All @@ -23,9 +20,18 @@ impl FormatNodeRule<StmtAssign> for FormatStmtAssign {
type_comment: _,
} = item;

for target in targets {
write!(f, [target.format(), space(), text("="), space()])?;
}
let (first, rest) = targets.split_first().ok_or(FormatError::SyntaxError)?;

write!(
f,
[
first.format(),
space(),
text("="),
space(),
FormatTargets { targets: rest }
]
)?;

write!(
f,
Expand All @@ -37,3 +43,59 @@ impl FormatNodeRule<StmtAssign> for FormatStmtAssign {
)
}
}

struct FormatTargets<'a> {
targets: &'a [Expr],
}

impl Format<PyFormatContext<'_>> for FormatTargets<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
if let Some((first, rest)) = self.targets.split_first() {
let needs_parentheses =
!has_own_parentheses(first) || f.context().comments().has_leading_comments(first);

let group_id = if needs_parentheses {
None
} else {
Some(f.group_id("assignment_parentheses"))
};

let saved_level = f.context().node_level();
f.context_mut()
.set_node_level(NodeLevel::Expression(group_id));

let format_first = format_with(|f: &mut PyFormatter| {
let result = if needs_parentheses {
write!(
f,
[
if_group_breaks(&text("(")),
soft_block_indent(&first.format().with_options(Parentheses::Never)),
if_group_breaks(&text(")"))
]
)
} else {
first.format().with_options(Parentheses::Never).fmt(f)
};

f.context_mut().set_node_level(saved_level);

result
});

let result = group(&format_args![
format_first,
space(),
text("="),
space(),
FormatTargets { targets: rest }
])
.with_group_id(group_id)
.fmt(f);

result
} else {
Ok(())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,34 @@ a2 = (
# Break the last element
a = asdf = fjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfal = 1
aa = [
bakjdshflkjahdslkfjlasfdahjlfds
] = dddd = ddd = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3
```

## Output
```py
# break left hand side
a1akjdshflkjahdslkfjlasfdahjlfds = bakjdshflkjahdslkfjlasfdahjlfds = cakjdshflkjahdslkfjlasfdahjlfds = kjaödkjaföjfahlfdalfhaöfaöfhaöfha = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3
a1akjdshflkjahdslkfjlasfdahjlfds = (
bakjdshflkjahdslkfjlasfdahjlfds
) = (
cakjdshflkjahdslkfjlasfdahjlfds
) = kjaödkjaföjfahlfdalfhaöfaöfhaöfha = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3
# join left hand side
a2 = (b2) = 2
a2 = b2 = 2
# Break the last element
a = asdf = fjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfal = 1
a = (
asdf
) = (
fjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfalflaflapamsakjsdhflakjdslfjhalsdljfal
) = 1
aa = [
bakjdshflkjahdslkfjlasfdahjlfds
] = dddd = ddd = fkjaödkjaföjfahlfdalfhaöfaöfhaöfha = g = 3
```


Expand Down

0 comments on commit 7854933

Please sign in to comment.