16
16
//! A few exceptions are allowed as there's known bugs in rustdoc, but this
17
17
//! should catch the majority of "broken link" cases.
18
18
19
- use std:: cell:: RefCell ;
19
+ use std:: cell:: { Cell , RefCell } ;
20
20
use std:: collections:: { HashMap , HashSet } ;
21
21
use std:: io:: ErrorKind ;
22
22
use std:: path:: { Component , Path , PathBuf } ;
@@ -544,7 +544,7 @@ fn parse_html<Sink: TokenSink>(source: &str, sink: Sink) -> Sink {
544
544
let mut input = BufferQueue :: default ( ) ;
545
545
input. push_back ( tendril. try_reinterpret ( ) . unwrap ( ) ) ;
546
546
547
- let mut tok = Tokenizer :: new ( sink, TokenizerOpts :: default ( ) ) ;
547
+ let tok = Tokenizer :: new ( sink, TokenizerOpts :: default ( ) ) ;
548
548
let _ = tok. feed ( & mut input) ;
549
549
assert ! ( input. is_empty( ) ) ;
550
550
tok. end ( ) ;
@@ -554,8 +554,8 @@ fn parse_html<Sink: TokenSink>(source: &str, sink: Sink) -> Sink {
554
554
#[ derive( Default ) ]
555
555
struct AttrCollector {
556
556
attr_name : & ' static [ u8 ] ,
557
- base : Option < String > ,
558
- found_attrs : Vec < ( u64 , String ) > ,
557
+ base : Cell < Option < String > > ,
558
+ found_attrs : RefCell < Vec < ( u64 , String ) > > ,
559
559
/// Tracks whether or not it is inside a <script> tag.
560
560
///
561
561
/// A lot of our sources have JSON script tags which have HTML embedded
@@ -564,34 +564,34 @@ struct AttrCollector {
564
564
/// `TokenSinkResult::Script(…)` (and then maybe switch parser?), but I
565
565
/// don't fully understand the best way to use that, and this seems good
566
566
/// enough for now.
567
- in_script : bool ,
567
+ in_script : Cell < bool > ,
568
568
}
569
569
570
570
impl TokenSink for AttrCollector {
571
571
type Handle = ( ) ;
572
572
573
- fn process_token ( & mut self , token : Token , line_number : u64 ) -> TokenSinkResult < ( ) > {
573
+ fn process_token ( & self , token : Token , line_number : u64 ) -> TokenSinkResult < ( ) > {
574
574
match token {
575
575
TagToken ( tag) => {
576
576
let tag_name = tag. name . as_bytes ( ) ;
577
577
if tag_name == b"base" {
578
578
if let Some ( href) =
579
579
tag. attrs . iter ( ) . find ( |attr| attr. name . local . as_bytes ( ) == b"href" )
580
580
{
581
- self . base = Some ( href. value . to_string ( ) ) ;
581
+ self . base . set ( Some ( href. value . to_string ( ) ) ) ;
582
582
}
583
583
return TokenSinkResult :: Continue ;
584
584
} else if tag_name == b"script" {
585
- self . in_script = !self . in_script ;
585
+ self . in_script . set ( !self . in_script . get ( ) ) ;
586
586
}
587
- if self . in_script {
587
+ if self . in_script . get ( ) {
588
588
return TokenSinkResult :: Continue ;
589
589
}
590
590
for attr in tag. attrs . iter ( ) {
591
591
let name = attr. name . local . as_bytes ( ) ;
592
592
if name == self . attr_name {
593
593
let url = attr. value . to_string ( ) ;
594
- self . found_attrs . push ( ( line_number, url) ) ;
594
+ self . found_attrs . borrow_mut ( ) . push ( ( line_number, url) ) ;
595
595
}
596
596
}
597
597
}
@@ -607,7 +607,7 @@ impl TokenSink for AttrCollector {
607
607
fn get_urls ( source : & str ) -> ( Option < String > , Vec < ( u64 , String ) > ) {
608
608
let collector = AttrCollector { attr_name : b"href" , ..AttrCollector :: default ( ) } ;
609
609
let sink = parse_html ( source, collector) ;
610
- ( sink. base , sink. found_attrs )
610
+ ( sink. base . into_inner ( ) , sink. found_attrs . into_inner ( ) )
611
611
}
612
612
613
613
/// Retrieves id="..." attributes from HTML elements.
@@ -619,7 +619,7 @@ fn parse_ids(ids: &mut HashSet<String>, file: &str, source: &str, report: &mut R
619
619
620
620
let collector = AttrCollector { attr_name : b"id" , ..AttrCollector :: default ( ) } ;
621
621
let sink = parse_html ( source, collector) ;
622
- for ( line_number, id) in sink. found_attrs {
622
+ for ( line_number, id) in sink. found_attrs . into_inner ( ) {
623
623
let encoded = small_url_encode ( & id) ;
624
624
if let Some ( id) = ids. replace ( id) {
625
625
report. errors += 1 ;
0 commit comments