Skip to content

Commit 31206f2

Browse files
committed
WIP: improvments to linting
1 parent e9ad399 commit 31206f2

File tree

3 files changed

+63
-18
lines changed

3 files changed

+63
-18
lines changed

src/librustdoc/passes/lint/html_tags.rs

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
103103
});
104104
};
105105

106-
let mut tagp = TagParser{
107-
tags: Vec::new(),
108-
tag_name: String::with_capacity(8),
109-
is_closing: false,
110-
tag_start_pos: 0,
111-
};
106+
let mut tagp = TagParser::new();
112107
let mut is_in_comment = None;
113108
let mut in_code_block = false;
114109

@@ -257,6 +252,15 @@ struct TagParser {
257252
}
258253

259254
impl TagParser {
255+
fn new() -> Self {
256+
Self{
257+
tags: Vec::new(),
258+
tag_name: String::with_capacity(8),
259+
is_closing: false,
260+
tag_start_pos: 0,
261+
}
262+
}
263+
260264
fn drop_tag(
261265
&mut self,
262266
range: Range<usize>,
@@ -293,6 +297,19 @@ impl TagParser {
293297
}
294298
}
295299

300+
/// Handle a `<` that appeared while parsing a tag.
301+
fn handle_lt_in_tag(&mut self, range: Range<usize>, lt_pos: usize, f: &impl Fn(String, &Range<usize>, bool),) {
302+
let global_pos = range.start + lt_pos;
303+
// is this check needed?
304+
if global_pos == self.tag_start_pos {
305+
// `<` is in the tag because it is the start.
306+
return;
307+
}
308+
// tried to start a new tag while in a tag
309+
f(format!("incomplete HTML tag `{}`", &self.tag_name), &(self.tag_start_pos..global_pos), false);
310+
self.tag_parsed();
311+
}
312+
296313

297314
fn extract_html_tag(
298315
&mut self,
@@ -341,9 +358,7 @@ impl TagParser {
341358
r.end = range.start + new_pos + 1;
342359
found = true;
343360
} else if c == '<' {
344-
// tried to start a new tag while in a tag
345-
f(format!("incomplete HTML tag `{}`", &self.tag_name), &(self.tag_start_pos..range.start + start_pos + new_pos), false);
346-
self.tag_parsed();
361+
self.handle_lt_in_tag(range.clone(), pos + new_pos, f);
347362

348363
}
349364
break;
@@ -371,9 +386,7 @@ impl TagParser {
371386
} else if c == '>' {
372387
break;
373388
} else if c == '<' {
374-
// tried to start a new tag while in a tag
375-
f(format!("incomplete HTML tag `{}`", &self.tag_name), &(self.tag_start_pos..range.start + start_pos + i), false);
376-
self.tag_parsed();
389+
self.handle_lt_in_tag(range.clone(), pos + i, f);
377390
} else if c == '/' && !after_eq {
378391
is_self_closing = true;
379392
} else {
@@ -454,12 +467,15 @@ impl TagParser {
454467
end: range.start + start_pos + 3,
455468
});
456469
} else {
457-
if !self.tag_name.is_empty() {
470+
if self.tag_name.is_empty() {
471+
self.tag_start_pos = range.start + start_pos;
472+
}
473+
/*if !self.tag_name.is_empty() {
474+
458475
f(format!("incomplete HTML tag `{}`", &self.tag_name), &(self.tag_start_pos..range.start + start_pos), false);
459476
self.tag_parsed();
460477
461-
}
462-
self.tag_start_pos = range.start + start_pos;
478+
}*/
463479
self.extract_html_tag(text, &range, dox, start_pos, &mut iter, f);
464480
}
465481
} else if !self.tag_name.is_empty() {
@@ -470,3 +486,19 @@ impl TagParser {
470486
}
471487

472488
}
489+
490+
#[test]
491+
fn test_extract_tags_nested_unclosed() {
492+
use std::rc::Rc;
493+
use std::cell::RefCell;
494+
use std::ops::Deref;
495+
496+
let mut tagp = TagParser::new();
497+
let mut diags = RefCell::new(Vec::new());
498+
let dox = "<div>\n<br<div>";
499+
tagp.extract_tags(dox, 0..dox.len(), dox, &mut None, &|s, r, b| {
500+
diags.borrow_mut().push((s, r.clone(), b));
501+
});
502+
assert_eq!(diags.borrow().len(), 1, "did not get expected diagnostics: {diags:?}");
503+
assert_eq!(diags.borrow()[0].1, 6..9)
504+
}

tests/rustdoc-ui/lints/invalid-html-tags.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ pub fn r() {}
165165
//~^ ERROR incomplete HTML tag `img`
166166
pub fn s() {}
167167

168+
/// <br>
168169
/// <br<br>
169170
//~^ ERROR incomplete HTML tag `br`
170171
pub fn t() {}

tests/rustdoc-ui/lints/invalid-html-tags.stderr

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ error: incomplete HTML tag `img`
116116
--> $DIR/invalid-html-tags.rs:158:8
117117
|
118118
LL | /// <p><img</p>
119-
| ^
119+
| ^^^^
120120

121121
error: unclosed HTML tag ``
122122
--> $DIR/invalid-html-tags.rs:158:8
@@ -125,10 +125,22 @@ LL | /// <p><img</p>
125125
| ^^^^
126126

127127
error: incomplete HTML tag `br`
128-
--> $DIR/invalid-html-tags.rs:173:5
128+
--> $DIR/invalid-html-tags.rs:169:5
129+
|
130+
LL | /// <br<br>
131+
| ^^^
132+
133+
error: unclosed HTML tag ``
134+
--> $DIR/invalid-html-tags.rs:169:5
135+
|
136+
LL | /// <br<br>
137+
| ^^^
138+
139+
error: incomplete HTML tag `br`
140+
--> $DIR/invalid-html-tags.rs:174:5
129141
|
130142
LL | /// <br
131143
| ^^^
132144

133-
error: aborting due to 21 previous errors
145+
error: aborting due to 23 previous errors
134146

0 commit comments

Comments
 (0)