Skip to content

Commit

Permalink
Track magic comma
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaReiser committed Jul 9, 2023
1 parent d13134a commit 96dca07
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 22 deletions.
25 changes: 16 additions & 9 deletions crates/ruff_python_formatter/src/expression/mod.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
use std::cmp::Ordering;

use rustpython_parser::ast;
use rustpython_parser::ast::{Expr, Operator};
use std::cmp::Ordering;

use crate::builders::optional_parentheses;
use ruff_formatter::{
format_args, FormatOwnedWithRule, FormatRefWithRule, FormatRule, FormatRuleWithOptions,
};
use ruff_python_ast::node::AnyNodeRef;
use ruff_python_ast::expression::ExpressionRef;
use ruff_python_ast::visitor::preorder::{walk_expr, PreorderVisitor};

use crate::builders::optional_parentheses;
use crate::context::NodeLevel;
use crate::expression::expr_tuple::TupleParentheses;
use crate::expression::parentheses::{
Expand Down Expand Up @@ -217,11 +218,15 @@ impl<'ast> IntoFormat<PyFormatContext<'ast>> for Expr {
/// the expression `a * b * c` contains two multiply operations. We prefer parentheses in that case.
/// `(a * b) * c` or `a * b + c` are okay, because the subexpression is parenthesized, or the expression uses operands with a lower priority
fn can_omit_optional_parentheses(expr: &Expr, context: &PyFormatContext) -> bool {
let mut visitor = CanOmitParenthesesVisitor::new(context.source());
if context.comments().has_leading_comments(expr) {
false
} else {
let mut visitor = CanOmitParenthesesVisitor::new(context.source());

visitor.visit_subexpression(expr);
visitor.visit_subexpression(expr);

visitor.can_omit_parentheses()
visitor.can_omit_parentheses()
}
}

#[derive(Clone, Debug)]
Expand Down Expand Up @@ -339,8 +344,10 @@ impl<'source> CanOmitParenthesesVisitor<'source> {
| Expr::DictComp(_)
| Expr::Call(_)
| Expr::Subscript(_)
) || is_expression_parenthesized(AnyNodeRef::from(value.as_ref()), self.source)
{
) || is_expression_parenthesized(
ExpressionRef::from(value.as_ref()),
self.source,
) {
self.update_max_priority(OperatorPriority::Attribute);
}
}
Expand Down Expand Up @@ -370,7 +377,7 @@ impl<'source> CanOmitParenthesesVisitor<'source> {
impl PreorderVisitor<'_> for CanOmitParenthesesVisitor<'_> {
fn visit_expr(&mut self, expr: &'_ Expr) {
// Rule only applies for non-parenthesized expressions.
if is_expression_parenthesized(AnyNodeRef::from(expr), self.source) {
if is_expression_parenthesized(ExpressionRef::from(expr), self.source) {
return;
}

Expand Down
16 changes: 3 additions & 13 deletions crates/ruff_python_formatter/src/expression/parentheses.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,27 +32,17 @@ pub(super) fn default_expression_needs_parentheses(
// `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 can_omit_optional_parentheses(node, context) {
Parentheses::Optional
} else {
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
}
}

fn can_omit_optional_parentheses(expr: ExpressionRef, context: &PyFormatContext) -> bool {
if context.comments().has_leading_comments(expr) {
false
} else {
true
}
}

// fn has_magic_comma(expr: AnyNodeRef)

/// Configures if the expression should be parenthesized.
#[derive(Copy, Clone, Debug, Default, Eq, PartialEq)]
pub enum Parenthesize {
Expand Down

0 comments on commit 96dca07

Please sign in to comment.