about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2020-10-09 14:48:45 +0200
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2020-10-12 21:32:36 +0200
commit861b8921c08e3cbe2ff8176679cc0cb3216bb2e3 (patch)
tree2f1198a325c7a9e6789573ef319a302ca4099232
parent0e022fc2b8eecbc16c090a99efbbd262c37ec962 (diff)
downloadrust-861b8921c08e3cbe2ff8176679cc0cb3216bb2e3.tar.gz
rust-861b8921c08e3cbe2ff8176679cc0cb3216bb2e3.zip
Clean up rustdoc HTML tags check pass
-rw-r--r--src/librustdoc/passes/html_tags.rs122
1 files changed, 68 insertions, 54 deletions
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index ae4eac89b45..872543d918c 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -4,6 +4,8 @@ use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::html::markdown::opts;
 use core::ops::Range;
+use std::iter::Peekable;
+use std::str::CharIndices;
 use pulldown_cmark::{Event, Parser};
 use rustc_feature::UnstableFeatures;
 use rustc_session::lint;
@@ -75,71 +77,83 @@ fn drop_tag(
     }
 }
 
-fn extract_tag(
+fn extract_html_tag(
     tags: &mut Vec<(String, Range<usize>)>,
     text: &str,
-    range: Range<usize>,
+    range: &Range<usize>,
+    start_pos: usize,
+    iter: &mut Peekable<CharIndices<'_>>,
     f: &impl Fn(&str, &Range<usize>),
 ) {
-    let mut iter = text.char_indices().peekable();
+    let mut tag_name = String::new();
+    let mut is_closing = false;
+    let mut prev_pos = start_pos;
 
-    while let Some((start_pos, c)) = iter.next() {
-        if c == '<' {
-            let mut tag_name = String::new();
-            let mut is_closing = false;
-            let mut prev_pos = start_pos;
-            loop {
-                let (pos, c) = match iter.peek() {
-                    Some((pos, c)) => (*pos, *c),
-                    // In case we reached the of the doc comment, we want to check that it's an
-                    // unclosed HTML tag. For example "/// <h3".
-                    None => (prev_pos, '\0'),
-                };
-                prev_pos = pos;
-                // Checking if this is a closing tag (like `</a>` for `<a>`).
-                if c == '/' && tag_name.is_empty() {
-                    is_closing = true;
-                } else if c.is_ascii_alphanumeric() {
-                    tag_name.push(c);
-                } else {
-                    if !tag_name.is_empty() {
-                        let mut r =
-                            Range { start: range.start + start_pos, end: range.start + pos };
-                        if c == '>' {
-                            // In case we have a tag without attribute, we can consider the span to
-                            // refer to it fully.
-                            r.end += 1;
+    loop {
+        let (pos, c) = match iter.peek() {
+            Some((pos, c)) => (*pos, *c),
+            // In case we reached the of the doc comment, we want to check that it's an
+            // unclosed HTML tag. For example "/// <h3".
+            None => (prev_pos, '\0'),
+        };
+        prev_pos = pos;
+        // Checking if this is a closing tag (like `</a>` for `<a>`).
+        if c == '/' && tag_name.is_empty() {
+            is_closing = true;
+        } else if c.is_ascii_alphanumeric() {
+            tag_name.push(c);
+        } else {
+            if !tag_name.is_empty() {
+                let mut r =
+                    Range { start: range.start + start_pos, end: range.start + pos };
+                if c == '>' {
+                    // In case we have a tag without attribute, we can consider the span to
+                    // refer to it fully.
+                    r.end += 1;
+                }
+                if is_closing {
+                    // In case we have "</div >" or even "</div         >".
+                    if c != '>' {
+                        if !c.is_whitespace() {
+                            // It seems like it's not a valid HTML tag.
+                            break;
                         }
-                        if is_closing {
-                            // In case we have "</div >" or even "</div         >".
-                            if c != '>' {
-                                if !c.is_whitespace() {
-                                    // It seems like it's not a valid HTML tag.
-                                    break;
-                                }
-                                let mut found = false;
-                                for (new_pos, c) in text[pos..].char_indices() {
-                                    if !c.is_whitespace() {
-                                        if c == '>' {
-                                            r.end = range.start + new_pos + 1;
-                                            found = true;
-                                        }
-                                        break;
-                                    }
-                                }
-                                if !found {
-                                    break;
+                        let mut found = false;
+                        for (new_pos, c) in text[pos..].char_indices() {
+                            if !c.is_whitespace() {
+                                if c == '>' {
+                                    r.end = range.start + new_pos + 1;
+                                    found = true;
                                 }
+                                break;
                             }
-                            drop_tag(tags, tag_name, r, f);
-                        } else {
-                            tags.push((tag_name, r));
+                        }
+                        if !found {
+                            break;
                         }
                     }
-                    break;
+                    drop_tag(tags, tag_name, r, f);
+                } else {
+                    tags.push((tag_name, r));
                 }
-                iter.next();
             }
+            break;
+        }
+        iter.next();
+    }
+}
+
+fn extract_tags(
+    tags: &mut Vec<(String, Range<usize>)>,
+    text: &str,
+    range: Range<usize>,
+    f: &impl Fn(&str, &Range<usize>),
+) {
+    let mut iter = text.char_indices().peekable();
+
+    while let Some((start_pos, c)) = iter.next() {
+        if c == '<' {
+            extract_html_tag(tags, text, &range, start_pos, &mut iter, f);
         }
     }
 }
@@ -172,7 +186,7 @@ impl<'a, 'tcx> DocFolder for InvalidHtmlTagsLinter<'a, 'tcx> {
 
             for (event, range) in p {
                 match event {
-                    Event::Html(text) => extract_tag(&mut tags, &text, range, &report_diag),
+                    Event::Html(text) => extract_tags(&mut tags, &text, range, &report_diag),
                     _ => {}
                 }
             }