mirror of
https://github.com/astral-sh/ruff.git
synced 2025-08-27 13:54:25 +00:00
Join implicit concatenated strings when they fit on a line (#13663)
This commit is contained in:
parent
e402e27a09
commit
73ee72b665
50 changed files with 3907 additions and 363 deletions
|
@ -14,6 +14,7 @@ use crate::expression::parentheses::{
|
|||
optional_parentheses, parenthesized, NeedsParentheses, OptionalParentheses, Parentheses,
|
||||
};
|
||||
use crate::prelude::*;
|
||||
use crate::preview::is_join_implicit_concatenated_string_enabled;
|
||||
|
||||
pub(crate) mod pattern_arguments;
|
||||
pub(crate) mod pattern_keyword;
|
||||
|
@ -226,7 +227,7 @@ pub(crate) fn can_pattern_omit_optional_parentheses(
|
|||
pattern: &Pattern,
|
||||
context: &PyFormatContext,
|
||||
) -> bool {
|
||||
let mut visitor = CanOmitOptionalParenthesesVisitor::default();
|
||||
let mut visitor = CanOmitOptionalParenthesesVisitor::new(context);
|
||||
visitor.visit_pattern(pattern, context);
|
||||
|
||||
if !visitor.any_parenthesized_expressions {
|
||||
|
@ -271,16 +272,32 @@ pub(crate) fn can_pattern_omit_optional_parentheses(
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
#[derive(Debug)]
|
||||
struct CanOmitOptionalParenthesesVisitor<'input> {
|
||||
max_precedence: OperatorPrecedence,
|
||||
max_precedence_count: usize,
|
||||
any_parenthesized_expressions: bool,
|
||||
join_implicit_concatenated_strings: bool,
|
||||
last: Option<&'input Pattern>,
|
||||
first: First<'input>,
|
||||
}
|
||||
|
||||
impl<'a> CanOmitOptionalParenthesesVisitor<'a> {
|
||||
fn new(context: &PyFormatContext) -> Self {
|
||||
Self {
|
||||
max_precedence: OperatorPrecedence::default(),
|
||||
max_precedence_count: 0,
|
||||
any_parenthesized_expressions: false,
|
||||
// TODO: Derive default for `CanOmitOptionalParenthesesVisitor` when removing the `join_implicit_concatenated_strings`
|
||||
// preview style.
|
||||
join_implicit_concatenated_strings: is_join_implicit_concatenated_string_enabled(
|
||||
context,
|
||||
),
|
||||
last: None,
|
||||
first: First::default(),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_pattern(&mut self, pattern: &'a Pattern, context: &PyFormatContext) {
|
||||
match pattern {
|
||||
Pattern::MatchSequence(_) | Pattern::MatchMapping(_) => {
|
||||
|
@ -289,18 +306,24 @@ impl<'a> CanOmitOptionalParenthesesVisitor<'a> {
|
|||
|
||||
Pattern::MatchValue(value) => match &*value.value {
|
||||
Expr::StringLiteral(string) => {
|
||||
self.update_max_precedence(OperatorPrecedence::String, string.value.len());
|
||||
if !self.join_implicit_concatenated_strings {
|
||||
self.update_max_precedence(OperatorPrecedence::String, string.value.len());
|
||||
}
|
||||
}
|
||||
Expr::BytesLiteral(bytes) => {
|
||||
self.update_max_precedence(OperatorPrecedence::String, bytes.value.len());
|
||||
if !self.join_implicit_concatenated_strings {
|
||||
self.update_max_precedence(OperatorPrecedence::String, bytes.value.len());
|
||||
}
|
||||
}
|
||||
// F-strings are allowed according to python's grammar but fail with a syntax error at runtime.
|
||||
// That's why we need to support them for formatting.
|
||||
Expr::FString(string) => {
|
||||
self.update_max_precedence(
|
||||
OperatorPrecedence::String,
|
||||
string.value.as_slice().len(),
|
||||
);
|
||||
if !self.join_implicit_concatenated_strings {
|
||||
self.update_max_precedence(
|
||||
OperatorPrecedence::String,
|
||||
string.value.as_slice().len(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Expr::NumberLiteral(_) | Expr::Attribute(_) | Expr::UnaryOp(_) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue