mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-02 22:55:08 +00:00
Introduce a new CST element for slice segments (#3195)
This commit is contained in:
parent
eb15371453
commit
6eaacf96be
8 changed files with 425 additions and 143 deletions
|
@ -10,7 +10,8 @@ use crate::builders::literal;
|
|||
use crate::context::ASTFormatContext;
|
||||
use crate::core::types::Range;
|
||||
use crate::cst::{
|
||||
Arguments, Boolop, Cmpop, Comprehension, Expr, ExprKind, Keyword, Operator, Unaryop,
|
||||
Arguments, Boolop, Cmpop, Comprehension, Expr, ExprKind, Keyword, Operator, SliceIndex,
|
||||
SliceIndexKind, Unaryop,
|
||||
};
|
||||
use crate::format::helpers::{is_self_closing, is_simple_power, is_simple_slice};
|
||||
use crate::format::numbers::{complex_literal, float_literal, int_literal};
|
||||
|
@ -86,15 +87,30 @@ fn format_subscript(
|
|||
value: &Expr,
|
||||
slice: &Expr,
|
||||
) -> FormatResult<()> {
|
||||
write!(f, [value.format()])?;
|
||||
write!(f, [text("[")])?;
|
||||
write!(
|
||||
f,
|
||||
[
|
||||
value.format(),
|
||||
text("["),
|
||||
group(&format_args![soft_block_indent(&slice.format())]),
|
||||
text("]")
|
||||
]
|
||||
[group(&format_args![soft_block_indent(&format_with(|f| {
|
||||
write!(f, [slice.format()])?;
|
||||
|
||||
// Apply any dangling comments.
|
||||
for trivia in &expr.trivia {
|
||||
if matches!(trivia.relationship, Relationship::Dangling) {
|
||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||
write!(f, [expand_parent()])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
write!(f, [literal(range)])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}))])]
|
||||
)?;
|
||||
|
||||
write!(f, [text("]")])?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -187,51 +203,182 @@ fn format_tuple(
|
|||
fn format_slice(
|
||||
f: &mut Formatter<ASTFormatContext<'_>>,
|
||||
expr: &Expr,
|
||||
lower: Option<&Expr>,
|
||||
upper: Option<&Expr>,
|
||||
step: Option<&Expr>,
|
||||
lower: &SliceIndex,
|
||||
upper: &SliceIndex,
|
||||
step: Option<&SliceIndex>,
|
||||
) -> FormatResult<()> {
|
||||
// https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices
|
||||
let is_simple = lower.map_or(true, is_simple_slice)
|
||||
&& upper.map_or(true, is_simple_slice)
|
||||
&& step.map_or(true, is_simple_slice);
|
||||
|
||||
if let Some(lower) = lower {
|
||||
write!(f, [lower.format()])?;
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
}
|
||||
write!(f, [text(":")])?;
|
||||
if let Some(upper) = upper {
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
write!(f, [upper.format()])?;
|
||||
if !is_simple && step.is_some() {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
}
|
||||
if let Some(step) = step {
|
||||
if !is_simple && upper.is_some() {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
write!(f, [text(":")])?;
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
write!(f, [step.format()])?;
|
||||
// // https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html#slices
|
||||
let lower_is_simple = if let SliceIndexKind::Index { value } = &lower.node {
|
||||
is_simple_slice(value)
|
||||
} else {
|
||||
let magic_trailing_colon = expr
|
||||
.trivia
|
||||
.iter()
|
||||
.any(|c| matches!(c.kind, TriviaKind::MagicTrailingColon));
|
||||
if magic_trailing_colon {
|
||||
if !is_simple && upper.is_some() {
|
||||
write!(f, [space()])?;
|
||||
true
|
||||
};
|
||||
let upper_is_simple = if let SliceIndexKind::Index { value } = &upper.node {
|
||||
is_simple_slice(value)
|
||||
} else {
|
||||
true
|
||||
};
|
||||
let step_is_simple = step.map_or(true, |step| {
|
||||
if let SliceIndexKind::Index { value } = &step.node {
|
||||
is_simple_slice(value)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
});
|
||||
let is_simple = lower_is_simple && upper_is_simple && step_is_simple;
|
||||
|
||||
write!(
|
||||
f,
|
||||
[group(&format_with(|f| {
|
||||
if let SliceIndexKind::Index { value } = &lower.node {
|
||||
write!(f, [value.format()])?;
|
||||
}
|
||||
|
||||
// Apply any dangling comments.
|
||||
for trivia in &lower.trivia {
|
||||
if matches!(trivia.relationship, Relationship::Dangling) {
|
||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||
write!(f, [expand_parent()])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
write!(f, [literal(range)])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if matches!(lower.node, SliceIndexKind::Index { .. }) {
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
}
|
||||
write!(f, [text(":")])?;
|
||||
|
||||
// Format any end-of-line comments.
|
||||
let mut first = true;
|
||||
for range in lower.trivia.iter().filter_map(|trivia| {
|
||||
if matches!(trivia.relationship, Relationship::Trailing) {
|
||||
if let TriviaKind::EndOfLineComment(range) = trivia.kind {
|
||||
Some(range)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
if std::mem::take(&mut first) {
|
||||
write!(f, [line_suffix(&text(" "))])?;
|
||||
}
|
||||
write!(f, [line_suffix(&literal(range))])?;
|
||||
}
|
||||
|
||||
if let SliceIndexKind::Index { value } = &upper.node {
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
write!(f, [if_group_breaks(&soft_line_break())])?;
|
||||
write!(f, [value.format()])?;
|
||||
}
|
||||
|
||||
// Apply any dangling comments.
|
||||
for trivia in &upper.trivia {
|
||||
if matches!(trivia.relationship, Relationship::Dangling) {
|
||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||
write!(f, [expand_parent()])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
write!(f, [literal(range)])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format any end-of-line comments.
|
||||
let mut first = true;
|
||||
for range in upper.trivia.iter().filter_map(|trivia| {
|
||||
if matches!(trivia.relationship, Relationship::Trailing) {
|
||||
if let TriviaKind::EndOfLineComment(range) = trivia.kind {
|
||||
Some(range)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
if std::mem::take(&mut first) {
|
||||
write!(f, [line_suffix(&text(" "))])?;
|
||||
}
|
||||
write!(f, [line_suffix(&literal(range))])?;
|
||||
}
|
||||
|
||||
if let Some(step) = step {
|
||||
if matches!(upper.node, SliceIndexKind::Index { .. }) {
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
}
|
||||
write!(f, [text(":")])?;
|
||||
|
||||
if let SliceIndexKind::Index { value } = &step.node {
|
||||
if !is_simple {
|
||||
write!(f, [space()])?;
|
||||
}
|
||||
write!(f, [if_group_breaks(&soft_line_break())])?;
|
||||
write!(f, [value.format()])?;
|
||||
}
|
||||
|
||||
// Apply any dangling comments.
|
||||
for trivia in &step.trivia {
|
||||
if matches!(trivia.relationship, Relationship::Dangling) {
|
||||
if let TriviaKind::OwnLineComment(range) = trivia.kind {
|
||||
write!(f, [expand_parent()])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
write!(f, [literal(range)])?;
|
||||
write!(f, [hard_line_break()])?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format any end-of-line comments.
|
||||
let mut first = true;
|
||||
for range in step.trivia.iter().filter_map(|trivia| {
|
||||
if matches!(trivia.relationship, Relationship::Trailing) {
|
||||
if let TriviaKind::EndOfLineComment(range) = trivia.kind {
|
||||
Some(range)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
if std::mem::take(&mut first) {
|
||||
write!(f, [line_suffix(&text(" "))])?;
|
||||
}
|
||||
write!(f, [line_suffix(&literal(range))])?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}))]
|
||||
)?;
|
||||
|
||||
// Format any end-of-line comments.
|
||||
let mut first = true;
|
||||
for range in expr.trivia.iter().filter_map(|trivia| {
|
||||
if matches!(trivia.relationship, Relationship::Trailing) {
|
||||
if let TriviaKind::EndOfLineComment(range) = trivia.kind {
|
||||
Some(range)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}) {
|
||||
if std::mem::take(&mut first) {
|
||||
write!(f, [line_suffix(&text(" "))])?;
|
||||
}
|
||||
write!(f, [line_suffix(&literal(range))])?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -973,13 +1120,9 @@ impl Format<ASTFormatContext<'_>> for FormatExpr<'_> {
|
|||
ExprKind::Name { id, .. } => format_name(f, self.item, id),
|
||||
ExprKind::List { elts, .. } => format_list(f, self.item, elts),
|
||||
ExprKind::Tuple { elts, .. } => format_tuple(f, self.item, elts),
|
||||
ExprKind::Slice { lower, upper, step } => format_slice(
|
||||
f,
|
||||
self.item,
|
||||
lower.as_deref(),
|
||||
upper.as_deref(),
|
||||
step.as_deref(),
|
||||
),
|
||||
ExprKind::Slice { lower, upper, step } => {
|
||||
format_slice(f, self.item, lower, upper, step.as_ref())
|
||||
}
|
||||
_ => {
|
||||
unimplemented!("Implement ExprKind: {:?}", self.item.node)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue