Skip to content

Commit

Permalink
Update pulldown_cmark to 0.5
Browse files Browse the repository at this point in the history
We now no longer have to use our own wrapper around `Parser` and can use
the new `OffsetIter`.
  • Loading branch information
phansch committed Apr 24, 2019
1 parent 9897442 commit 05ec485
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 41 deletions.
2 changes: 1 addition & 1 deletion clippy_lints/Cargo.toml
Expand Up @@ -28,7 +28,7 @@ serde = "1.0"
serde_derive = "1.0"
toml = "0.4"
unicode-normalization = "0.1"
pulldown-cmark = "0.2"
pulldown-cmark = "0.5.0"
url = "1.7.0"
if_chain = "0.1.3"
smallvec = { version = "0.6.5", features = ["union"] }
Expand Down
63 changes: 23 additions & 40 deletions clippy_lints/src/doc.rs
Expand Up @@ -8,6 +8,7 @@ use syntax::ast;
use syntax::source_map::{BytePos, Span};
use syntax_pos::Pos;
use url::Url;
use std::ops::Range;

declare_clippy_lint! {
/// **What it does:** Checks for the presence of `_`, `::` or camel-case words
Expand Down Expand Up @@ -57,25 +58,6 @@ impl EarlyLintPass for DocMarkdown {
}
}

struct Parser<'a> {
parser: pulldown_cmark::Parser<'a>,
}

impl<'a> Parser<'a> {
fn new(parser: pulldown_cmark::Parser<'a>) -> Self {
Self { parser }
}
}

impl<'a> Iterator for Parser<'a> {
type Item = (usize, pulldown_cmark::Event<'a>);

fn next(&mut self) -> Option<Self::Item> {
let offset = self.parser.get_offset();
self.parser.next().map(|event| (offset, event))
}
}

/// Cleanup documentation decoration (`///` and such).
///
/// We can't use `syntax::attr::AttributeMethods::with_desugared_doc` or
Expand Down Expand Up @@ -159,30 +141,31 @@ pub fn check_attrs<'a>(cx: &EarlyContext<'_>, valid_idents: &FxHashSet<String>,
}

if !doc.is_empty() {
let parser = Parser::new(pulldown_cmark::Parser::new(&doc));
let parser = parser.coalesce(|x, y| {
let parser = pulldown_cmark::Parser::new(&doc).into_offset_iter();
// Iterate over all `Events` and combine consecutive events into one
let events = parser.coalesce(|previous, current| {
use pulldown_cmark::Event::*;

let x_offset = x.0;
let y_offset = y.0;
let previous_range = previous.1;
let current_range = current.1;

match (x.1, y.1) {
(Text(x), Text(y)) => {
let mut x = x.into_owned();
x.push_str(&y);
Ok((x_offset, Text(x.into())))
match (previous.0, current.0) {
(Text(previous), Text(current)) => {
let mut previous = previous.to_string();
previous.push_str(&current);
Ok((Text(previous.into()), previous_range))
},
(x, y) => Err(((x_offset, x), (y_offset, y))),
(previous, current) => Err(((previous, previous_range), (current, current_range))),
}
});
check_doc(cx, valid_idents, parser, &spans);
check_doc(cx, valid_idents, events, &spans);
}
}

fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
cx: &EarlyContext<'_>,
valid_idents: &FxHashSet<String>,
docs: Events,
events: Events,
spans: &[(usize, Span)],
) {
use pulldown_cmark::Event::*;
Expand All @@ -191,15 +174,15 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
let mut in_code = false;
let mut in_link = None;

for (offset, event) in docs {
for (event, range) in events {
match event {
Start(CodeBlock(_)) | Start(Code) => in_code = true,
End(CodeBlock(_)) | End(Code) => in_code = false,
Start(Link(link, _)) => in_link = Some(link),
End(Link(_, _)) => in_link = None,
Start(CodeBlock(_)) => in_code = true,
End(CodeBlock(_)) => in_code = false,
Start(Link(_, url, _)) => in_link = Some(url),
End(Link(..)) => in_link = None,
Start(_tag) | End(_tag) => (), // We don't care about other tags
Html(_html) | InlineHtml(_html) => (), // HTML is weird, just ignore it
SoftBreak | HardBreak => (),
SoftBreak | HardBreak | TaskListMarker(_) | Code(_) => (),
FootnoteReference(text) | Text(text) => {
if Some(&text) == in_link.as_ref() {
// Probably a link of the form `<http://example.com>`
Expand All @@ -209,15 +192,15 @@ fn check_doc<'a, Events: Iterator<Item = (usize, pulldown_cmark::Event<'a>)>>(
}

if !in_code {
let index = match spans.binary_search_by(|c| c.0.cmp(&offset)) {
let index = match spans.binary_search_by(|c| c.0.cmp(&range.start)) {
Ok(o) => o,
Err(e) => e - 1,
};

let (begin, span) = spans[index];

// Adjust for the beginning of the current `Event`
let span = span.with_lo(span.lo() + BytePos::from_usize(offset - begin));
let span = span.with_lo(span.lo() + BytePos::from_usize(range.start - begin));

check_text(cx, valid_idents, &text, span);
}
Expand Down

0 comments on commit 05ec485

Please sign in to comment.