Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit ab7f4e1

Browse files
committed
rewrite_comment: fix block fallback when failing to rewrite an itemized block
Close rust-lang#3224
1 parent 43206f4 commit ab7f4e1

File tree

1 file changed

+35
-20
lines changed

1 file changed

+35
-20
lines changed

src/comment.rs

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,8 @@ impl CodeBlockAttribute {
416416
/// An item starts with either a star `*` or a dash `-`. Different level of indentation are
417417
/// handled by shrinking the shape accordingly.
418418
struct ItemizedBlock {
419+
/// the lines that are identified as part of an itemized block
420+
lines: Vec<String>,
419421
/// the number of whitespaces up to the item sigil
420422
indent: usize,
421423
/// the string that marks the start of an item
@@ -437,6 +439,7 @@ impl ItemizedBlock {
437439
let space_to_sigil = line.chars().take_while(|c| c.is_whitespace()).count();
438440
let indent = space_to_sigil + 2;
439441
ItemizedBlock {
442+
lines: vec![line[indent..].to_string()],
440443
indent,
441444
opener: line[..indent].to_string(),
442445
line_start: " ".repeat(indent),
@@ -456,10 +459,32 @@ impl ItemizedBlock {
456459
}
457460
}
458461

459-
/// Returns true if the line is part of the current itemized block
460-
fn in_block(&self, line: &str) -> bool {
461-
!ItemizedBlock::is_itemized_line(line)
462+
/// Returns true if the line is part of the current itemized block.
463+
/// If it is, then it is added to the internal lines vec.
464+
fn add_line(&mut self, line: &str) -> bool {
465+
if !ItemizedBlock::is_itemized_line(line)
462466
&& self.indent <= line.chars().take_while(|c| c.is_whitespace()).count()
467+
{
468+
self.lines.push(line.to_string());
469+
return true;
470+
}
471+
false
472+
}
473+
474+
/// Returns the block as a string, with each line trimmed at the start.
475+
fn trimmed_block_as_string(&self) -> String {
476+
self.lines
477+
.iter()
478+
.map(|line| format!("{} ", line.trim_start()))
479+
.collect::<String>()
480+
}
481+
482+
/// Returns the block as a string under its original form
483+
fn original_block_as_string(&self) -> String {
484+
self.lines
485+
.iter()
486+
.map(|line| format!("{}\n", line))
487+
.collect::<String>()
463488
}
464489
}
465490

@@ -468,7 +493,6 @@ struct CommentRewrite<'a> {
468493
code_block_buffer: String,
469494
is_prev_line_multi_line: bool,
470495
code_block_attr: Option<CodeBlockAttribute>,
471-
item_block_buffer: String,
472496
item_block: Option<ItemizedBlock>,
473497
comment_line_separator: String,
474498
indent_str: String,
@@ -506,7 +530,6 @@ impl<'a> CommentRewrite<'a> {
506530
code_block_buffer: String::with_capacity(128),
507531
is_prev_line_multi_line: false,
508532
code_block_attr: None,
509-
item_block_buffer: String::with_capacity(128),
510533
item_block: None,
511534
comment_line_separator: format!("{}{}", indent_str, line_start),
512535
max_chars,
@@ -556,17 +579,14 @@ impl<'a> CommentRewrite<'a> {
556579
));
557580
}
558581

559-
if !self.item_block_buffer.is_empty() {
582+
if let Some(ref ib) = self.item_block {
560583
// the last few lines are part of an itemized block
561584
self.fmt.shape = Shape::legacy(self.max_chars, self.fmt_indent);
562-
let mut ib = None;
563-
::std::mem::swap(&mut ib, &mut self.item_block);
564-
let ib = ib.unwrap();
565585
let item_fmt = ib.create_string_format(&self.fmt);
566586
self.result.push_str(&self.comment_line_separator);
567587
self.result.push_str(&ib.opener);
568588
match rewrite_string(
569-
&self.item_block_buffer.replace("\n", " "),
589+
&ib.trimmed_block_as_string(),
570590
&item_fmt,
571591
self.max_chars.saturating_sub(ib.indent),
572592
) {
@@ -575,7 +595,7 @@ impl<'a> CommentRewrite<'a> {
575595
&format!("{}{}", &self.comment_line_separator, ib.line_start),
576596
)),
577597
None => self.result.push_str(&Self::join_block(
578-
&self.item_block_buffer,
598+
&ib.original_block_as_string(),
579599
&self.comment_line_separator,
580600
)),
581601
};
@@ -599,10 +619,8 @@ impl<'a> CommentRewrite<'a> {
599619
) -> bool {
600620
let is_last = i == count_newlines(orig);
601621

602-
if let Some(ref ib) = self.item_block {
603-
if ib.in_block(&line) {
604-
self.item_block_buffer.push_str(line.trim_start());
605-
self.item_block_buffer.push('\n');
622+
if let Some(ref mut ib) = self.item_block {
623+
if ib.add_line(&line) {
606624
return false;
607625
}
608626
self.is_prev_line_multi_line = false;
@@ -611,7 +629,7 @@ impl<'a> CommentRewrite<'a> {
611629
self.result.push_str(&self.comment_line_separator);
612630
self.result.push_str(&ib.opener);
613631
match rewrite_string(
614-
&self.item_block_buffer.replace("\n", " "),
632+
&ib.trimmed_block_as_string(),
615633
&item_fmt,
616634
self.max_chars.saturating_sub(ib.indent),
617635
) {
@@ -620,11 +638,10 @@ impl<'a> CommentRewrite<'a> {
620638
&format!("{}{}", &self.comment_line_separator, ib.line_start),
621639
)),
622640
None => self.result.push_str(&Self::join_block(
623-
&self.item_block_buffer,
641+
&ib.original_block_as_string(),
624642
&self.comment_line_separator,
625643
)),
626644
};
627-
self.item_block_buffer.clear();
628645
} else if self.code_block_attr.is_some() {
629646
if line.starts_with("```") {
630647
let code_block = match self.code_block_attr.as_ref().unwrap() {
@@ -664,8 +681,6 @@ impl<'a> CommentRewrite<'a> {
664681
self.code_block_attr = Some(CodeBlockAttribute::new(&line[3..]))
665682
} else if self.fmt.config.wrap_comments() && ItemizedBlock::is_itemized_line(&line) {
666683
let ib = ItemizedBlock::new(&line);
667-
self.item_block_buffer.push_str(&line[ib.indent..]);
668-
self.item_block_buffer.push('\n');
669684
self.item_block = Some(ib);
670685
return false;
671686
}

0 commit comments

Comments
 (0)