-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #12770 - notriddle:notriddle/doc-lazy-continuation, r=l…
…logiq Add new lint `doc_lazy_continuation` changelog: [`doc_lazy_continuation`]: add lint that warns on so-called "lazy paragraph continuations" This is a follow-up for rust-lang/rust#121659, since most cases of unintended block quotes are lazy continuations. The lint is designed to be more generally useful than that, though, because it will also catch unintended list items and unintended block quotes that didn't coincidentally hit a pulldown-cmark bug. The second commit is the result of running `cargo dev dogfood --fix`, and manually fixing anything that seems wrong. NOTE: this lint's suggestions should never change the parser's interpretation of the markdown, but in many cases, it seems that doc comments in clippy were written without regard for this feature of Markdown (which, I suppose, is why this lint should exist).
- Loading branch information
Showing
19 changed files
with
597 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
use clippy_utils::diagnostics::span_lint_and_then; | ||
use itertools::Itertools; | ||
use rustc_errors::{Applicability, SuggestionStyle}; | ||
use rustc_lint::LateContext; | ||
use rustc_span::{BytePos, Span}; | ||
use std::ops::Range; | ||
|
||
use super::DOC_LAZY_CONTINUATION; | ||
|
||
fn map_container_to_text(c: &super::Container) -> &'static str { | ||
match c { | ||
super::Container::Blockquote => "> ", | ||
// numbered list can have up to nine digits, plus the dot, plus four spaces on either side | ||
super::Container::List(indent) => &" "[0..*indent], | ||
} | ||
} | ||
|
||
// TODO: Adjust the parameters as necessary | ||
pub(super) fn check( | ||
cx: &LateContext<'_>, | ||
doc: &str, | ||
range: Range<usize>, | ||
mut span: Span, | ||
containers: &[super::Container], | ||
) { | ||
if doc[range.clone()].contains('\t') { | ||
// We don't do tab stops correctly. | ||
return; | ||
} | ||
|
||
let ccount = doc[range.clone()].chars().filter(|c| *c == '>').count(); | ||
let blockquote_level = containers | ||
.iter() | ||
.filter(|c| matches!(c, super::Container::Blockquote)) | ||
.count(); | ||
let lcount = doc[range.clone()].chars().filter(|c| *c == ' ').count(); | ||
let list_indentation = containers | ||
.iter() | ||
.map(|c| { | ||
if let super::Container::List(indent) = c { | ||
*indent | ||
} else { | ||
0 | ||
} | ||
}) | ||
.sum(); | ||
if ccount < blockquote_level || lcount < list_indentation { | ||
let msg = if ccount < blockquote_level { | ||
"doc quote missing `>` marker" | ||
} else { | ||
"doc list item missing indentation" | ||
}; | ||
span_lint_and_then(cx, DOC_LAZY_CONTINUATION, span, msg, |diag| { | ||
if ccount == 0 && blockquote_level == 0 { | ||
// simpler suggestion style for indentation | ||
let indent = list_indentation - lcount; | ||
diag.span_suggestion_with_style( | ||
span.shrink_to_hi(), | ||
"indent this line", | ||
std::iter::repeat(" ").take(indent).join(""), | ||
Applicability::MaybeIncorrect, | ||
SuggestionStyle::ShowAlways, | ||
); | ||
diag.help("if this is supposed to be its own paragraph, add a blank line"); | ||
return; | ||
} | ||
let mut doc_start_range = &doc[range]; | ||
let mut suggested = String::new(); | ||
for c in containers { | ||
let text = map_container_to_text(c); | ||
if doc_start_range.starts_with(text) { | ||
doc_start_range = &doc_start_range[text.len()..]; | ||
span = span | ||
.with_lo(span.lo() + BytePos(u32::try_from(text.len()).expect("text is not 2**32 or bigger"))); | ||
} else if matches!(c, super::Container::Blockquote) | ||
&& let Some(i) = doc_start_range.find('>') | ||
{ | ||
doc_start_range = &doc_start_range[i + 1..]; | ||
span = | ||
span.with_lo(span.lo() + BytePos(u32::try_from(i).expect("text is not 2**32 or bigger") + 1)); | ||
} else { | ||
suggested.push_str(text); | ||
} | ||
} | ||
diag.span_suggestion_with_style( | ||
span, | ||
"add markers to start of line", | ||
suggested, | ||
Applicability::MachineApplicable, | ||
SuggestionStyle::ShowAlways, | ||
); | ||
diag.help("if this not intended to be a quote at all, escape it with `\\>`"); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.