-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add new too_long_first_doc_paragraph
first paragraph lint
#12993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
855a9d1
f455587
4969960
3c6e5ef
a203342
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
use rustc_ast::ast::Attribute; | ||
use rustc_errors::Applicability; | ||
use rustc_hir::{Item, ItemKind}; | ||
use rustc_lint::LateContext; | ||
|
||
use clippy_utils::diagnostics::{span_lint, span_lint_and_then}; | ||
use clippy_utils::source::snippet_opt; | ||
|
||
use super::TOO_LONG_FIRST_DOC_PARAGRAPH; | ||
|
||
pub(super) fn check( | ||
cx: &LateContext<'_>, | ||
item: &Item<'_>, | ||
attrs: &[Attribute], | ||
mut first_paragraph_len: usize, | ||
check_private_items: bool, | ||
) { | ||
if !check_private_items && !cx.effective_visibilities.is_exported(item.owner_id.def_id) { | ||
return; | ||
} | ||
if first_paragraph_len <= 200 | ||
|| !matches!( | ||
item.kind, | ||
// This is the list of items which can be documented AND are displayed on the module | ||
// page. So associated items or impl blocks are not part of this list. | ||
ItemKind::Static(..) | ||
| ItemKind::Const(..) | ||
| ItemKind::Fn(..) | ||
| ItemKind::Macro(..) | ||
| ItemKind::Mod(..) | ||
| ItemKind::TyAlias(..) | ||
| ItemKind::Enum(..) | ||
| ItemKind::Struct(..) | ||
| ItemKind::Union(..) | ||
| ItemKind::Trait(..) | ||
| ItemKind::TraitAlias(..) | ||
Centri3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) | ||
{ | ||
return; | ||
} | ||
|
||
let mut spans = Vec::new(); | ||
let mut should_suggest_empty_doc = false; | ||
|
||
for attr in attrs { | ||
if let Some(doc) = attr.doc_str() { | ||
spans.push(attr.span); | ||
let doc = doc.as_str(); | ||
let doc = doc.trim(); | ||
if spans.len() == 1 { | ||
// We make this suggestion only if the first doc line ends with a punctuation | ||
// because it might just need to add an empty line with `///`. | ||
should_suggest_empty_doc = doc.ends_with('.') || doc.ends_with('!') || doc.ends_with('?'); | ||
} | ||
let len = doc.chars().count(); | ||
if len >= first_paragraph_len { | ||
break; | ||
} | ||
first_paragraph_len -= len; | ||
} | ||
} | ||
|
||
let &[first_span, .., last_span] = spans.as_slice() else { | ||
return; | ||
}; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should call There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's a bit tricky here since it needs to check all attributes. Adding it though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it'd be simpler to just check if the item is from a proc macro instead. Gonna do that. |
||
if should_suggest_empty_doc | ||
&& let Some(second_span) = spans.get(1) | ||
&& let new_span = first_span.with_hi(second_span.lo()).with_lo(first_span.hi()) | ||
&& let Some(snippet) = snippet_opt(cx, new_span) | ||
{ | ||
span_lint_and_then( | ||
cx, | ||
TOO_LONG_FIRST_DOC_PARAGRAPH, | ||
first_span.with_hi(last_span.lo()), | ||
"first doc comment paragraph is too long", | ||
|diag| { | ||
diag.span_suggestion( | ||
new_span, | ||
"add an empty line", | ||
format!("{snippet}///\n"), | ||
Centri3 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Applicability::MachineApplicable, | ||
); | ||
}, | ||
); | ||
return; | ||
} | ||
span_lint( | ||
cx, | ||
TOO_LONG_FIRST_DOC_PARAGRAPH, | ||
first_span.with_hi(last_span.lo()), | ||
"first doc comment paragraph is too long", | ||
); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: This There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good idea! |
||
} |
Uh oh!
There was an error while loading. Please reload this page.