///
/// **Examples:**
/// ```rust
-/// /// Do something with the foo_bar parameter. See also that::other::module::foo.
+/// /// Do something with the foo_bar parameter. See also
+/// that::other::module::foo.
/// // ^ `foo_bar` and `that::other::module::foo` should be ticked.
/// fn doit(foo_bar) { .. }
/// ```
/// Cleanup documentation decoration (`///` and such).
///
/// We can't use `syntax::attr::AttributeMethods::with_desugared_doc` or
-/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we need to keep track of
+/// `syntax::parse::lexer::comments::strip_doc_comment_decoration` because we
+/// need to keep track of
/// the spans but this function is inspired from the later.
#[allow(cast_possible_truncation)]
pub fn strip_doc_comment_decoration(comment: &str, span: Span) -> (String, Vec<(usize, Span)>) {
let doc = &comment[prefix.len()..];
let mut doc = doc.to_owned();
doc.push('\n');
- return (doc.to_owned(), vec![(doc.len(), Span { lo: span.lo + BytePos(prefix.len() as u32), ..span })]);
+ return (
+ doc.to_owned(),
+ vec![
+ (
+ doc.len(),
+ Span {
+ lo: span.lo + BytePos(prefix.len() as u32),
+ ..span
+ }
+ ),
+ ],
+ );
}
}
if comment.starts_with("/*") {
let doc = &comment[3..comment.len() - 2];
let mut sizes = vec![];
-
+ let mut contains_initial_stars = false;
for line in doc.lines() {
let offset = line.as_ptr() as usize - comment.as_ptr() as usize;
debug_assert_eq!(offset as u32 as usize, offset);
-
+ contains_initial_stars |= line.trim_left().starts_with('*');
// +1 for the newline
- sizes.push((line.len() + 1, Span { lo: span.lo + BytePos(offset as u32), ..span }));
+ sizes.push((
+ line.len() + 1,
+ Span {
+ lo: span.lo + BytePos(offset as u32),
+ ..span
+ },
+ ));
}
-
- return (doc.to_string(), sizes);
+ if !contains_initial_stars {
+ return (doc.to_string(), sizes);
+ }
+ // remove the initial '*'s if any
+ let mut no_stars = String::with_capacity(doc.len());
+ for line in doc.lines() {
+ let mut chars = line.chars();
+ while let Some(c) = chars.next() {
+ if c.is_whitespace() {
+ no_stars.push(c);
+ } else {
+ no_stars.push(if c == '*' { ' ' } else { c });
+ break;
+ }
+ }
+ no_stars.push_str(chars.as_str());
+ no_stars.push('\n');
+ }
+ return (no_stars, sizes);
}
panic!("not a doc-comment: {}", comment);
cx: &EarlyContext,
valid_idents: &[String],
docs: Events,
- spans: &[(usize, Span)]
+ spans: &[(usize, Span)],
) {
use pulldown_cmark::Event::*;
use pulldown_cmark::Tag::*;
let (begin, span) = spans[index];
// Adjust for the begining of the current `Event`
- let span = Span { lo: span.lo + BytePos::from_usize(offset - begin), ..span };
+ let span = Span {
+ lo: span.lo + BytePos::from_usize(offset - begin),
+ ..span
+ };
check_text(cx, valid_idents, &text, span);
}
}
fn check_word(cx: &EarlyContext, word: &str, span: Span) {
- /// Checks if a string is camel-case, ie. contains at least two uppercase letter (`Clippy` is
- /// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded (`IDs` is ok).
+ /// Checks if a string is camel-case, ie. contains at least two uppercase
+ /// letter (`Clippy` is
+ /// ok) and one lower-case letter (`NASA` is ok). Plural are also excluded
+ /// (`IDs` is ok).
fn is_camel_case(s: &str) -> bool {
if s.starts_with(|c: char| c.is_digit(10)) {
return false;
};
s.chars().all(char::is_alphanumeric) && s.chars().filter(|&c| c.is_uppercase()).take(2).count() > 1 &&
- s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0
+ s.chars().filter(|&c| c.is_lowercase()).take(1).count() > 0
}
fn has_underscore(s: &str) -> bool {
}
if has_underscore(word) || word.contains("::") || is_camel_case(word) {
- span_lint(cx,
- DOC_MARKDOWN,
- span,
- &format!("you should put `{}` between ticks in the documentation", word));
+ span_lint(
+ cx,
+ DOC_MARKDOWN,
+ span,
+ &format!("you should put `{}` between ticks in the documentation", word),
+ );
}
}