8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- use std:: cell:: Cell ;
12
11
use std:: env;
13
12
use std:: ffi:: OsString ;
14
13
use std:: io:: prelude:: * ;
@@ -23,7 +22,8 @@ use std::sync::{Arc, Mutex};
23
22
use testing;
24
23
use rustc_lint;
25
24
use rustc:: dep_graph:: DepGraph ;
26
- use rustc:: hir:: map as hir_map;
25
+ use rustc:: hir;
26
+ use rustc:: hir:: intravisit;
27
27
use rustc:: session:: { self , config} ;
28
28
use rustc:: session:: config:: { OutputType , OutputTypes , Externs } ;
29
29
use rustc:: session:: search_paths:: { SearchPaths , PathKind } ;
@@ -33,18 +33,15 @@ use rustc_driver::{driver, Compilation};
33
33
use rustc_driver:: driver:: phase_2_configure_and_expand;
34
34
use rustc_metadata:: cstore:: CStore ;
35
35
use rustc_resolve:: MakeGlobMap ;
36
+ use rustc_trans:: back:: link;
37
+ use syntax:: ast;
36
38
use syntax:: codemap:: CodeMap ;
37
39
use syntax:: feature_gate:: UnstableFeatures ;
38
40
use errors;
39
41
use errors:: emitter:: ColorConfig ;
40
42
41
- use core;
42
- use clean;
43
- use clean:: Clean ;
44
- use fold:: DocFolder ;
43
+ use clean:: Attributes ;
45
44
use html:: markdown;
46
- use passes;
47
- use visit_ast:: RustdocVisitor ;
48
45
49
46
#[ derive( Clone , Default ) ]
50
47
pub struct TestOptions {
@@ -87,48 +84,36 @@ pub fn run(input: &str,
87
84
config:: build_configuration ( & sess, config:: parse_cfgspecs ( cfgs. clone ( ) ) ) ;
88
85
89
86
let krate = panictry ! ( driver:: phase_1_parse_input( & sess, & input) ) ;
90
- let driver:: ExpansionResult { defs, mut hir_forest, analysis , .. } = {
87
+ let driver:: ExpansionResult { defs, mut hir_forest, .. } = {
91
88
phase_2_configure_and_expand (
92
89
& sess, & cstore, krate, None , "rustdoc-test" , None , MakeGlobMap :: No , |_| Ok ( ( ) )
93
90
) . expect ( "phase_2_configure_and_expand aborted in rustdoc!" )
94
91
} ;
95
92
96
- let dep_graph = DepGraph :: new ( false ) ;
93
+ let crate_name = crate_name. unwrap_or_else ( || {
94
+ link:: find_crate_name ( None , & hir_forest. krate ( ) . attrs , & input)
95
+ } ) ;
97
96
let opts = scrape_test_config ( hir_forest. krate ( ) ) ;
98
- let _ignore = dep_graph. in_ignore ( ) ;
99
- let map = hir_map:: map_crate ( & mut hir_forest, defs) ;
100
-
101
- let ctx = core:: DocContext {
102
- map : & map,
103
- maybe_typed : core:: NotTyped ( & sess) ,
104
- input : input,
105
- populated_all_crate_impls : Cell :: new ( false ) ,
106
- external_traits : Default :: default ( ) ,
107
- deref_trait_did : Cell :: new ( None ) ,
108
- deref_mut_trait_did : Cell :: new ( None ) ,
109
- access_levels : Default :: default ( ) ,
110
- renderinfo : Default :: default ( ) ,
111
- ty_substs : Default :: default ( ) ,
112
- lt_substs : Default :: default ( ) ,
113
- export_map : analysis. export_map ,
114
- } ;
115
-
116
- let mut v = RustdocVisitor :: new ( & ctx) ;
117
- v. visit ( ctx. map . krate ( ) ) ;
118
- let mut krate = v. clean ( & ctx) ;
119
- if let Some ( name) = crate_name {
120
- krate. name = name;
121
- }
122
- let krate = passes:: collapse_docs ( krate) ;
123
- let krate = passes:: unindent_comments ( krate) ;
124
-
125
- let mut collector = Collector :: new ( krate. name . to_string ( ) ,
97
+ let mut collector = Collector :: new ( crate_name,
126
98
cfgs,
127
99
libs,
128
100
externs,
129
101
false ,
130
102
opts) ;
131
- collector. fold_crate ( krate) ;
103
+
104
+ {
105
+ let dep_graph = DepGraph :: new ( false ) ;
106
+ let _ignore = dep_graph. in_ignore ( ) ;
107
+ let map = hir:: map:: map_crate ( & mut hir_forest, defs) ;
108
+ let krate = map. krate ( ) ;
109
+ let mut hir_collector = HirCollector {
110
+ collector : & mut collector,
111
+ map : & map
112
+ } ;
113
+ hir_collector. visit_testable ( "" . to_string ( ) , & krate. attrs , |this| {
114
+ intravisit:: walk_crate ( this, krate) ;
115
+ } ) ;
116
+ }
132
117
133
118
test_args. insert ( 0 , "rustdoctest" . to_string ( ) ) ;
134
119
@@ -472,56 +457,84 @@ impl Collector {
472
457
}
473
458
}
474
459
475
- impl DocFolder for Collector {
476
- fn fold_item ( & mut self , item : clean:: Item ) -> Option < clean:: Item > {
477
- let current_name = match item. name {
478
- Some ( ref name) if !name. is_empty ( ) => Some ( name. clone ( ) ) ,
479
- _ => typename_if_impl ( & item)
480
- } ;
460
+ struct HirCollector < ' a , ' hir : ' a > {
461
+ collector : & ' a mut Collector ,
462
+ map : & ' a hir:: map:: Map < ' hir >
463
+ }
481
464
482
- let pushed = current_name. map ( |name| self . names . push ( name) ) . is_some ( ) ;
465
+ impl < ' a , ' hir > HirCollector < ' a , ' hir > {
466
+ fn visit_testable < F : FnOnce ( & mut Self ) > ( & mut self ,
467
+ name : String ,
468
+ attrs : & [ ast:: Attribute ] ,
469
+ nested : F ) {
470
+ let has_name = !name. is_empty ( ) ;
471
+ if has_name {
472
+ self . collector . names . push ( name) ;
473
+ }
483
474
484
- if let Some ( doc) = item. doc_value ( ) {
485
- self . cnt = 0 ;
486
- markdown:: find_testable_code ( doc, & mut * self ) ;
475
+ let mut attrs = Attributes :: from_ast ( attrs) ;
476
+ attrs. collapse_doc_comments ( ) ;
477
+ attrs. unindent_doc_comments ( ) ;
478
+ if let Some ( doc) = attrs. doc_value ( ) {
479
+ self . collector . cnt = 0 ;
480
+ markdown:: find_testable_code ( doc, self . collector ) ;
487
481
}
488
482
489
- let ret = self . fold_item_recur ( item) ;
490
- if pushed {
491
- self . names . pop ( ) ;
483
+ nested ( self ) ;
484
+
485
+ if has_name {
486
+ self . collector . names . pop ( ) ;
492
487
}
488
+ }
489
+ }
490
+
491
+ impl < ' a , ' hir > intravisit:: Visitor < ' hir > for HirCollector < ' a , ' hir > {
492
+ fn nested_visit_map ( & mut self ) -> Option < & hir:: map:: Map < ' hir > > {
493
+ Some ( self . map )
494
+ }
495
+
496
+ fn visit_item ( & mut self , item : & ' hir hir:: Item ) {
497
+ let name = if let hir:: ItemImpl ( .., ref ty, _) = item. node {
498
+ hir:: print:: ty_to_string ( ty)
499
+ } else {
500
+ item. name . to_string ( )
501
+ } ;
493
502
494
- return ret;
503
+ self . visit_testable ( name, & item. attrs , |this| {
504
+ intravisit:: walk_item ( this, item) ;
505
+ } ) ;
506
+ }
495
507
496
- // FIXME: it would be better to not have the escaped version in the first place
497
- fn unescape_for_testname ( mut s : String ) -> String {
498
- // for refs `&foo`
499
- if s . contains ( "&" ) {
500
- s = s . replace ( "&" , "&" ) ;
508
+ fn visit_trait_item ( & mut self , item : & ' hir hir :: TraitItem ) {
509
+ self . visit_testable ( item . name . to_string ( ) , & item . attrs , |this| {
510
+ intravisit :: walk_trait_item ( this , item ) ;
511
+ } ) ;
512
+ }
501
513
502
- // `::&'a mut Foo::` looks weird, let's make it `::<&'a mut Foo>`::
503
- if let Some ( '&' ) = s . chars ( ) . nth ( 0 ) {
504
- s = format ! ( "<{}>" , s ) ;
505
- }
506
- }
514
+ fn visit_impl_item ( & mut self , item : & ' hir hir :: ImplItem ) {
515
+ self . visit_testable ( item . name . to_string ( ) , & item . attrs , |this| {
516
+ intravisit :: walk_impl_item ( this , item ) ;
517
+ } ) ;
518
+ }
507
519
508
- // either `<..>` or `->`
509
- if s. contains ( ">" ) {
510
- s. replace ( ">" , ">" )
511
- . replace ( "<" , "<" )
512
- } else {
513
- s
514
- }
515
- }
520
+ fn visit_foreign_item ( & mut self , item : & ' hir hir:: ForeignItem ) {
521
+ self . visit_testable ( item. name . to_string ( ) , & item. attrs , |this| {
522
+ intravisit:: walk_foreign_item ( this, item) ;
523
+ } ) ;
524
+ }
516
525
517
- fn typename_if_impl ( item : & clean:: Item ) -> Option < String > {
518
- if let clean:: ItemEnum :: ImplItem ( ref impl_) = item. inner {
519
- let path = impl_. for_ . to_string ( ) ;
520
- let unescaped_path = unescape_for_testname ( path) ;
521
- Some ( unescaped_path)
522
- } else {
523
- None
524
- }
525
- }
526
+ fn visit_variant ( & mut self ,
527
+ v : & ' hir hir:: Variant ,
528
+ g : & ' hir hir:: Generics ,
529
+ item_id : ast:: NodeId ) {
530
+ self . visit_testable ( v. node . name . to_string ( ) , & v. node . attrs , |this| {
531
+ intravisit:: walk_variant ( this, v, g, item_id) ;
532
+ } ) ;
533
+ }
534
+
535
+ fn visit_struct_field ( & mut self , f : & ' hir hir:: StructField ) {
536
+ self . visit_testable ( f. name . to_string ( ) , & f. attrs , |this| {
537
+ intravisit:: walk_struct_field ( this, f) ;
538
+ } ) ;
526
539
}
527
540
}
0 commit comments