Add JoinCommaSeparatedBuilder (#5342)

This commit is contained in:
Micha Reiser
2023-06-23 23:03:05 +02:00
committed by GitHub
parent 6ba9d5d5a4
commit d3d69a031e
4 changed files with 164 additions and 128 deletions

View File

@@ -1,14 +1,12 @@
use crate::builders::use_magic_trailing_comma;
use crate::comments::{dangling_node_comments, leading_comments, Comments};
use crate::context::PyFormatContext;
use crate::expression::parentheses::{
default_expression_needs_parentheses, NeedsParentheses, Parentheses, Parenthesize,
};
use crate::prelude::*;
use crate::{FormatNodeRule, PyFormatter};
use ruff_formatter::format_args;
use ruff_formatter::{write, Buffer, FormatResult};
use crate::FormatNodeRule;
use ruff_formatter::{format_args, write};
use ruff_python_ast::prelude::Ranged;
use ruff_text_size::TextRange;
use rustpython_parser::ast::{Expr, ExprDict};
#[derive(Default)]
@@ -19,6 +17,16 @@ struct KeyValuePair<'a> {
value: &'a Expr,
}
impl Ranged for KeyValuePair<'_> {
fn range(&self) -> TextRange {
if let Some(key) = self.key {
TextRange::new(key.start(), self.value.end())
} else {
self.value.range()
}
}
}
impl Format<PyFormatContext<'_>> for KeyValuePair<'_> {
fn fmt(&self, f: &mut Formatter<PyFormatContext<'_>>) -> FormatResult<()> {
if let Some(key) = self.key {
@@ -54,57 +62,42 @@ impl FormatNodeRule<ExprDict> for FormatExprDict {
values,
} = item;
let last = match &values[..] {
[] => {
return write!(
f,
[
&text("{"),
block_indent(&dangling_node_comments(item)),
&text("}"),
]
);
}
[.., last] => last,
};
let magic_trailing_comma = use_magic_trailing_comma(f, last.range());
debug_assert_eq!(keys.len(), values.len());
let joined = format_with(|f| {
f.join_with(format_args!(text(","), soft_line_break_or_space()))
.entries(
keys.iter()
.zip(values)
.map(|(key, value)| KeyValuePair { key, value }),
)
.finish()
});
if values.is_empty() {
return write!(
f,
[
&text("{"),
block_indent(&dangling_node_comments(item)),
&text("}"),
]
);
}
let block = if magic_trailing_comma {
block_indent
} else {
soft_block_indent
};
let format_pairs = format_with(|f| {
let mut joiner = f.join_comma_separated();
for (key, value) in keys.iter().zip(values) {
let key_value_pair = KeyValuePair { key, value };
joiner.entry(&key_value_pair, &key_value_pair);
}
joiner.finish()
});
write!(
f,
[group(&format_args![
text("{"),
block(&format_args![joined, if_group_breaks(&text(",")),]),
soft_block_indent(&format_pairs),
text("}")
])]
)
}
fn fmt_dangling_comments(&self, _node: &ExprDict, _f: &mut PyFormatter) -> FormatResult<()> {
// TODO(konstin): Reactivate when string formatting works, currently a source of unstable
// formatting, e.g.
// ```python
// coverage_ignore_c_items = {
// # 'cfunction': [...]
// }
// ```
// Handled by `fmt_fields`
Ok(())
}
}