Skip to content

Commit 2bcc3a9

Browse files
scampitopecongiro
authored andcommitted
do not format a code block in documentation if it is annotated with ignore or text (rust-lang#3058)
1 parent 90692a5 commit 2bcc3a9

File tree

5 files changed

+161
-13
lines changed

5 files changed

+161
-13
lines changed

src/comment.rs

+50-13
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,31 @@ fn light_rewrite_block_comment_with_bare_lines(
407407
Some(format!("{}\n{}{}", first_line, indent_str, rest))
408408
}
409409

410+
/// Attributes for code blocks in rustdoc.
411+
/// See https://doc.rust-lang.org/rustdoc/print.html#attributes
412+
enum CodeBlockAttribute {
413+
Rust,
414+
Ignore,
415+
Text,
416+
ShouldPanic,
417+
NoRun,
418+
CompileFail,
419+
}
420+
421+
impl CodeBlockAttribute {
422+
fn new(attribute: &str) -> CodeBlockAttribute {
423+
match attribute {
424+
"rust" | "" => CodeBlockAttribute::Rust,
425+
"ignore" => CodeBlockAttribute::Ignore,
426+
"text" => CodeBlockAttribute::Text,
427+
"should_panic" => CodeBlockAttribute::ShouldPanic,
428+
"no_run" => CodeBlockAttribute::NoRun,
429+
"compile_fail" => CodeBlockAttribute::CompileFail,
430+
_ => CodeBlockAttribute::Text,
431+
}
432+
}
433+
}
434+
410435
fn rewrite_comment_inner(
411436
orig: &str,
412437
block_style: bool,
@@ -466,7 +491,7 @@ fn rewrite_comment_inner(
466491
result.push_str(opener);
467492
let mut code_block_buffer = String::with_capacity(128);
468493
let mut is_prev_line_multi_line = false;
469-
let mut inside_code_block = false;
494+
let mut code_block_attr = None;
470495
let comment_line_separator = format!("{}{}", indent_str, line_start);
471496
let join_code_block_with_comment_line_separator = |s: &str| {
472497
let mut result = String::with_capacity(s.len() + 128);
@@ -485,28 +510,36 @@ fn rewrite_comment_inner(
485510
for (i, (line, has_leading_whitespace)) in lines.enumerate() {
486511
let is_last = i == count_newlines(orig);
487512

488-
if inside_code_block {
513+
if let Some(ref attr) = code_block_attr {
489514
if line.starts_with("```") {
490-
inside_code_block = false;
491-
result.push_str(&comment_line_separator);
492-
let code_block = {
493-
let mut config = config.clone();
494-
config.set().wrap_comments(false);
495-
match ::format_code_block(&code_block_buffer, &config) {
496-
Some(ref s) => trim_custom_comment_prefix(s),
497-
None => trim_custom_comment_prefix(&code_block_buffer),
515+
let code_block = match attr {
516+
CodeBlockAttribute::Ignore | CodeBlockAttribute::Text => {
517+
trim_custom_comment_prefix(&code_block_buffer)
518+
}
519+
_ if code_block_buffer.is_empty() => String::new(),
520+
_ => {
521+
let mut config = config.clone();
522+
config.set().wrap_comments(false);
523+
match ::format_code_block(&code_block_buffer, &config) {
524+
Some(ref s) => trim_custom_comment_prefix(s),
525+
None => trim_custom_comment_prefix(&code_block_buffer),
526+
}
498527
}
499528
};
500-
result.push_str(&join_code_block_with_comment_line_separator(&code_block));
529+
if !code_block.is_empty() {
530+
result.push_str(&comment_line_separator);
531+
result.push_str(&join_code_block_with_comment_line_separator(&code_block));
532+
}
501533
code_block_buffer.clear();
502534
result.push_str(&comment_line_separator);
503535
result.push_str(line);
536+
code_block_attr = None;
504537
} else {
505538
code_block_buffer.push_str(&hide_sharp_behind_comment(line));
506539
code_block_buffer.push('\n');
507540

508541
if is_last {
509-
// There is an code block that is not properly enclosed by backticks.
542+
// There is a code block that is not properly enclosed by backticks.
510543
// We will leave them untouched.
511544
result.push_str(&comment_line_separator);
512545
result.push_str(&join_code_block_with_comment_line_separator(
@@ -517,7 +550,11 @@ fn rewrite_comment_inner(
517550

518551
continue;
519552
} else {
520-
inside_code_block = line.starts_with("```");
553+
code_block_attr = if line.starts_with("```") {
554+
Some(CodeBlockAttribute::new(&line[3..]))
555+
} else {
556+
None
557+
};
521558

522559
if result == opener {
523560
let force_leading_whitespace = opener == "/* " && count_newlines(orig) == 0;

tests/source/issue-3055/original.rs

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// rustfmt-wrap_comments: true
2+
3+
/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc commodo ultricies dui.
4+
///
5+
/// Should not format with text attribute
6+
/// ```text
7+
/// .--------------.
8+
/// | v
9+
/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot
10+
/// ^ ^ ' ' '
11+
/// ' ' ' ' '
12+
/// ' `--------' ' '
13+
/// `---------------' ' '
14+
/// `--------------------------' '
15+
/// `-------------------------------------'
16+
/// ```
17+
///
18+
/// Should not format with ignore attribute
19+
/// ```ignore
20+
/// .--------------.
21+
/// | v
22+
/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot
23+
/// ^ ^ ' ' '
24+
/// ' ' ' ' '
25+
/// ' `--------' ' '
26+
/// `---------------' ' '
27+
/// `--------------------------' '
28+
/// `-------------------------------------'
29+
/// ```
30+
///
31+
/// Should format with rust attribute
32+
/// ```rust
33+
/// let x =
34+
/// 42;
35+
/// ```
36+
///
37+
/// Should format with no attribute as it defaults to rust
38+
/// ```
39+
/// let x =
40+
/// 42;
41+
/// ```
42+
fn func() {}

tests/target/issue-3055/backtick.rs

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// rustfmt-wrap_comments: true
2+
3+
/// Simple block
4+
///
5+
/// ```text
6+
/// `
7+
/// ```
8+
fn main() {
9+
println!("Hello, world!");
10+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// rustfmt-wrap_comments: true
2+
3+
/// Simple block
4+
///
5+
/// ```
6+
/// ```
7+
///
8+
/// ```no_run
9+
/// ```
10+
///
11+
/// ```should_panic
12+
/// ```
13+
///
14+
/// ```compile_fail
15+
/// ```
16+
fn main() {
17+
println!("Hello, world!");
18+
}

tests/target/issue-3055/original.rs

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
// rustfmt-wrap_comments: true
2+
3+
/// Vestibulum elit nibh, rhoncus non, euismod sit amet, pretium eu, enim. Nunc
4+
/// commodo ultricies dui.
5+
///
6+
/// Should not format with text attribute
7+
/// ```text
8+
/// .--------------.
9+
/// | v
10+
/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot
11+
/// ^ ^ ' ' '
12+
/// ' ' ' ' '
13+
/// ' `--------' ' '
14+
/// `---------------' ' '
15+
/// `--------------------------' '
16+
/// `-------------------------------------'
17+
/// ```
18+
///
19+
/// Should not format with ignore attribute
20+
/// ```ignore
21+
/// .--------------.
22+
/// | v
23+
/// Park <- Idle -> Poll -> Probe -> Download -> Install -> Reboot
24+
/// ^ ^ ' ' '
25+
/// ' ' ' ' '
26+
/// ' `--------' ' '
27+
/// `---------------' ' '
28+
/// `--------------------------' '
29+
/// `-------------------------------------'
30+
/// ```
31+
///
32+
/// Should format with rust attribute
33+
/// ```rust
34+
/// let x = 42;
35+
/// ```
36+
///
37+
/// Should format with no attribute as it defaults to rust
38+
/// ```
39+
/// let x = 42;
40+
/// ```
41+
fn func() {}

0 commit comments

Comments
 (0)