Introduce Token element (#7048)

This commit is contained in:
Micha Reiser 2023-09-02 10:05:47 +02:00 committed by GitHub
parent 2f3a950f6f
commit c05e4628b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
78 changed files with 733 additions and 723 deletions

View file

@ -104,8 +104,7 @@ impl Document {
expands = false;
continue;
}
FormatElement::StaticText { text } => text.contains('\n'),
FormatElement::DynamicText { text, .. } => text.contains('\n'),
FormatElement::Text { text, .. } => text.contains('\n'),
FormatElement::SourceCodeSlice {
contains_newlines, ..
} => *contains_newlines,
@ -249,20 +248,20 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
while let Some(element) = iter.next() {
if !first_element && !in_text && !element.is_end_tag() {
// Write a separator between every two elements
write!(f, [text(","), soft_line_break_or_space()])?;
write!(f, [token(","), soft_line_break_or_space()])?;
}
first_element = false;
match element {
element @ (FormatElement::Space
| FormatElement::StaticText { .. }
| FormatElement::DynamicText { .. }
| FormatElement::Token { .. }
| FormatElement::Text { .. }
| FormatElement::SourceCodeSlice { .. }) => {
fn write_escaped(element: &FormatElement, f: &mut Formatter<IrFormatContext>) {
let text = match element {
FormatElement::StaticText { text } => text,
FormatElement::DynamicText { text } => text.as_ref(),
FormatElement::Token { text } => text,
FormatElement::Text { text } => text.as_ref(),
FormatElement::SourceCodeSlice { slice, .. } => {
slice.text(f.context().source_code())
}
@ -270,7 +269,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
};
if text.contains('"') {
f.write_element(FormatElement::DynamicText {
f.write_element(FormatElement::Text {
text: text.replace('"', r#"\""#).into(),
});
} else {
@ -279,14 +278,14 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
}
if !in_text {
write!(f, [text("\"")])?;
write!(f, [token("\"")])?;
}
in_text = true;
match element {
FormatElement::Space => {
write!(f, [text(" ")])?;
write!(f, [token(" ")])?;
}
element if element.is_text() => {
write_escaped(element, f);
@ -297,45 +296,42 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
let is_next_text = iter.peek().is_some_and(|e| e.is_text() || e.is_space());
if !is_next_text {
write!(f, [text("\"")])?;
write!(f, [token("\"")])?;
in_text = false;
}
}
FormatElement::Line(mode) => match mode {
LineMode::SoftOrSpace => {
write!(f, [text("soft_line_break_or_space")])?;
write!(f, [token("soft_line_break_or_space")])?;
}
LineMode::Soft => {
write!(f, [text("soft_line_break")])?;
write!(f, [token("soft_line_break")])?;
}
LineMode::Hard => {
write!(f, [text("hard_line_break")])?;
write!(f, [token("hard_line_break")])?;
}
LineMode::Empty => {
write!(f, [text("empty_line")])?;
write!(f, [token("empty_line")])?;
}
},
FormatElement::ExpandParent => {
write!(f, [text("expand_parent")])?;
write!(f, [token("expand_parent")])?;
}
FormatElement::SourcePosition(position) => {
write!(
f,
[dynamic_text(
&std::format!("source_position({position:?})"),
None
)]
[text(&std::format!("source_position({position:?})"), None)]
)?;
}
FormatElement::LineSuffixBoundary => {
write!(f, [text("line_suffix_boundary")])?;
write!(f, [token("line_suffix_boundary")])?;
}
FormatElement::BestFitting { variants, mode } => {
write!(f, [text("best_fitting([")])?;
write!(f, [token("best_fitting([")])?;
f.write_elements([
FormatElement::Tag(StartIndent),
FormatElement::Line(LineMode::Hard),
@ -350,13 +346,13 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
FormatElement::Line(LineMode::Hard),
]);
write!(f, [text("]")])?;
write!(f, [token("]")])?;
if *mode != BestFittingMode::FirstLine {
write!(f, [dynamic_text(&std::format!(", mode: {mode:?}"), None),])?;
write!(f, [text(&std::format!(", mode: {mode:?}"), None),])?;
}
write!(f, [text(")")])?;
write!(f, [token(")")])?;
}
FormatElement::Interned(interned) => {
@ -370,7 +366,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
dynamic_text(&std::format!("<interned {index}>"), None),
text(&std::format!("<interned {index}>"), None),
space(),
&&**interned,
]
@ -379,10 +375,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
Some(reference) => {
write!(
f,
[dynamic_text(
&std::format!("<ref interned *{reference}>"),
None
)]
[text(&std::format!("<ref interned *{reference}>"), None)]
)?;
}
}
@ -401,9 +394,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
text("<END_TAG_WITHOUT_START<"),
dynamic_text(&std::format!("{:?}", tag.kind()), None),
text(">>"),
token("<END_TAG_WITHOUT_START<"),
text(&std::format!("{:?}", tag.kind()), None),
token(">>"),
]
)?;
first_element = false;
@ -414,13 +407,13 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
f,
[
ContentArrayEnd,
text(")"),
token(")"),
soft_line_break_or_space(),
text("ERROR<START_END_TAG_MISMATCH<start: "),
dynamic_text(&std::format!("{start_kind:?}"), None),
text(", end: "),
dynamic_text(&std::format!("{:?}", tag.kind()), None),
text(">>")
token("ERROR<START_END_TAG_MISMATCH<start: "),
text(&std::format!("{start_kind:?}"), None),
token(", end: "),
text(&std::format!("{:?}", tag.kind()), None),
token(">>")
]
)?;
first_element = false;
@ -434,7 +427,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
match tag {
StartIndent => {
write!(f, [text("indent(")])?;
write!(f, [token("indent(")])?;
}
StartDedent(mode) => {
@ -443,16 +436,16 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
DedentMode::Root => "dedentRoot",
};
write!(f, [text(label), text("(")])?;
write!(f, [token(label), token("(")])?;
}
StartAlign(tag::Align(count)) => {
write!(
f,
[
text("align("),
dynamic_text(&count.to_string(), None),
text(","),
token("align("),
text(&count.to_string(), None),
token(","),
space(),
]
)?;
@ -462,27 +455,27 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
text("line_suffix("),
dynamic_text(&std::format!("{reserved_width:?}"), None),
text(","),
token("line_suffix("),
text(&std::format!("{reserved_width:?}"), None),
token(","),
space(),
]
)?;
}
StartVerbatim(_) => {
write!(f, [text("verbatim(")])?;
write!(f, [token("verbatim(")])?;
}
StartGroup(group) => {
write!(f, [text("group(")])?;
write!(f, [token("group(")])?;
if let Some(group_id) = group.id() {
write!(
f,
[
dynamic_text(&std::format!("\"{group_id:?}\""), None),
text(","),
text(&std::format!("\"{group_id:?}\""), None),
token(","),
space(),
]
)?;
@ -491,10 +484,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
match group.mode() {
GroupMode::Flat => {}
GroupMode::Expand => {
write!(f, [text("expand: true,"), space()])?;
write!(f, [token("expand: true,"), space()])?;
}
GroupMode::Propagated => {
write!(f, [text("expand: propagated,"), space()])?;
write!(f, [token("expand: propagated,"), space()])?;
}
}
}
@ -503,10 +496,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
text("conditional_group(condition:"),
token("conditional_group(condition:"),
space(),
group.condition(),
text(","),
token(","),
space()
]
)?;
@ -514,10 +507,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
match group.mode() {
GroupMode::Flat => {}
GroupMode::Expand => {
write!(f, [text("expand: true,"), space()])?;
write!(f, [token("expand: true,"), space()])?;
}
GroupMode::Propagated => {
write!(f, [text("expand: propagated,"), space()])?;
write!(f, [token("expand: propagated,"), space()])?;
}
}
}
@ -526,9 +519,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
text("indent_if_group_breaks("),
dynamic_text(&std::format!("\"{id:?}\""), None),
text(","),
token("indent_if_group_breaks("),
text(&std::format!("\"{id:?}\""), None),
token(","),
space(),
]
)?;
@ -537,10 +530,10 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
StartConditionalContent(condition) => {
match condition.mode {
PrintMode::Flat => {
write!(f, [text("if_group_fits_on_line(")])?;
write!(f, [token("if_group_fits_on_line(")])?;
}
PrintMode::Expanded => {
write!(f, [text("if_group_breaks(")])?;
write!(f, [token("if_group_breaks(")])?;
}
}
@ -548,8 +541,8 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
dynamic_text(&std::format!("\"{group_id:?}\""), None),
text(","),
text(&std::format!("\"{group_id:?}\""), None),
token(","),
space(),
]
)?;
@ -560,36 +553,36 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
write!(
f,
[
text("label("),
dynamic_text(&std::format!("\"{label_id:?}\""), None),
text(","),
token("label("),
text(&std::format!("\"{label_id:?}\""), None),
token(","),
space(),
]
)?;
}
StartFill => {
write!(f, [text("fill(")])?;
write!(f, [token("fill(")])?;
}
StartFitsExpanded(tag::FitsExpanded {
condition,
propagate_expand,
}) => {
write!(f, [text("fits_expanded(propagate_expand:"), space()])?;
write!(f, [token("fits_expanded(propagate_expand:"), space()])?;
if propagate_expand.get() {
write!(f, [text("true")])?;
write!(f, [token("true")])?;
} else {
write!(f, [text("false")])?;
write!(f, [token("false")])?;
}
write!(f, [text(","), space()])?;
write!(f, [token(","), space()])?;
if let Some(condition) = condition {
write!(
f,
[text("condition:"), space(), condition, text(","), space()]
[token("condition:"), space(), condition, token(","), space()]
)?;
}
}
@ -611,7 +604,7 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
| EndDedent
| EndFitsExpanded
| EndVerbatim => {
write!(f, [ContentArrayEnd, text(")")])?;
write!(f, [ContentArrayEnd, token(")")])?;
}
};
@ -627,9 +620,9 @@ impl Format<IrFormatContext<'_>> for &[FormatElement] {
f,
[
ContentArrayEnd,
text(")"),
token(")"),
soft_line_break_or_space(),
dynamic_text(&std::format!("<START_WITHOUT_END<{top:?}>>"), None),
text(&std::format!("<START_WITHOUT_END<{top:?}>>"), None),
]
)?;
}
@ -644,7 +637,7 @@ impl Format<IrFormatContext<'_>> for ContentArrayStart {
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
use Tag::{StartGroup, StartIndent};
write!(f, [text("[")])?;
write!(f, [token("[")])?;
f.write_elements([
FormatElement::Tag(StartGroup(tag::Group::new())),
@ -667,7 +660,7 @@ impl Format<IrFormatContext<'_>> for ContentArrayEnd {
FormatElement::Tag(EndGroup),
]);
write!(f, [text("]")])
write!(f, [token("]")])
}
}
@ -767,22 +760,22 @@ impl FormatElements for [FormatElement] {
impl Format<IrFormatContext<'_>> for Condition {
fn fmt(&self, f: &mut Formatter<IrFormatContext>) -> FormatResult<()> {
match (self.mode, self.group_id) {
(PrintMode::Flat, None) => write!(f, [text("if_fits_on_line")]),
(PrintMode::Flat, None) => write!(f, [token("if_fits_on_line")]),
(PrintMode::Flat, Some(id)) => write!(
f,
[
text("if_group_fits_on_line("),
dynamic_text(&std::format!("\"{id:?}\""), None),
text(")")
token("if_group_fits_on_line("),
text(&std::format!("\"{id:?}\""), None),
token(")")
]
),
(PrintMode::Expanded, None) => write!(f, [text("if_breaks")]),
(PrintMode::Expanded, None) => write!(f, [token("if_breaks")]),
(PrintMode::Expanded, Some(id)) => write!(
f,
[
text("if_group_breaks("),
dynamic_text(&std::format!("\"{id:?}\""), None),
text(")")
token("if_group_breaks("),
text(&std::format!("\"{id:?}\""), None),
token(")")
]
),
}
@ -805,11 +798,11 @@ mod tests {
write!(
f,
[group(&format_args![
text("("),
token("("),
soft_block_indent(&format_args![
text("Some longer content"),
token("Some longer content"),
space(),
text("That should ultimately break"),
token("That should ultimately break"),
])
])]
)
@ -838,7 +831,7 @@ mod tests {
fn escapes_quotes() {
let formatted = format!(
SimpleFormatContext::default(),
[text(r#""""Python docstring""""#)]
[token(r#""""Python docstring""""#)]
)
.unwrap();
@ -859,7 +852,7 @@ mod tests {
write!(
f,
[group(&format_args![
text("("),
token("("),
soft_block_indent(&format_args![
source_text_slice(
TextRange::at(TextSize::new(0), TextSize::new(19)),
@ -899,16 +892,16 @@ mod tests {
use Tag::*;
let document = Document::from(vec![
FormatElement::StaticText { text: "[" },
FormatElement::Token { text: "[" },
FormatElement::Tag(StartGroup(tag::Group::new())),
FormatElement::Tag(StartIndent),
FormatElement::Line(LineMode::Soft),
FormatElement::StaticText { text: "a" },
FormatElement::Token { text: "a" },
// Close group instead of indent
FormatElement::Tag(EndGroup),
FormatElement::Line(LineMode::Soft),
FormatElement::Tag(EndIndent),
FormatElement::StaticText { text: "]" },
FormatElement::Token { text: "]" },
// End tag without start
FormatElement::Tag(EndIndent),
// Start tag without an end