8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
+ use std:: collections:: HashMap ;
11
12
use std:: env;
12
13
use std:: ffi:: OsString ;
14
+ use std:: fs:: File ;
13
15
use std:: io:: prelude:: * ;
14
16
use std:: io;
15
17
use std:: path:: PathBuf ;
@@ -96,13 +98,24 @@ pub fn run(input: &str,
96
98
link:: find_crate_name ( None , & hir_forest. krate ( ) . attrs , & input)
97
99
} ) ;
98
100
let opts = scrape_test_config ( hir_forest. krate ( ) ) ;
101
+ let filename = input_path. to_str ( ) . unwrap_or ( "" ) . to_owned ( ) ;
102
+ let mut f = match File :: open ( input_path) {
103
+ Ok ( f) => f,
104
+ _ => return 1 ,
105
+ } ;
106
+ let mut file_content = String :: new ( ) ;
107
+ if let Err ( _) = f. read_to_string ( & mut file_content) {
108
+ return 1 ;
109
+ }
99
110
let mut collector = Collector :: new ( crate_name,
100
111
cfgs,
101
112
libs,
102
113
externs,
103
114
false ,
104
115
opts,
105
- maybe_sysroot) ;
116
+ maybe_sysroot,
117
+ & file_content,
118
+ filename) ;
106
119
107
120
{
108
121
let dep_graph = DepGraph :: new ( false ) ;
@@ -162,11 +175,12 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
162
175
should_panic : bool , no_run : bool , as_test_harness : bool ,
163
176
compile_fail : bool , mut error_codes : Vec < String > , opts : & TestOptions ,
164
177
maybe_sysroot : Option < PathBuf > ,
165
- original : & str ) {
178
+ original : & str , line_number : u32 , filename : & str ) {
166
179
// the test harness wants its own `main` & top level functions, so
167
180
// never wrap the test in `fn main() { ... }`
168
181
let new_test = maketest ( test, Some ( cratename) , as_test_harness, opts) ;
169
- let test = format ! ( "```{}\n {}\n ```\n " , original, test) ;
182
+ let test = format ! ( "Error on {}:{}\n \n ```{}\n {}\n ```\n " ,
183
+ filename, line_number, original, test) ;
170
184
let input = config:: Input :: Str {
171
185
name : driver:: anon_src ( ) ,
172
186
input : new_test. to_owned ( ) ,
@@ -389,11 +403,27 @@ pub struct Collector {
389
403
cratename : String ,
390
404
opts : TestOptions ,
391
405
maybe_sysroot : Option < PathBuf > ,
406
+ code_blocks : HashMap < String , Vec < u32 > > ,
407
+ filename : String ,
392
408
}
393
409
394
410
impl Collector {
395
411
pub fn new ( cratename : String , cfgs : Vec < String > , libs : SearchPaths , externs : Externs ,
396
- use_headers : bool , opts : TestOptions , maybe_sysroot : Option < PathBuf > ) -> Collector {
412
+ use_headers : bool , opts : TestOptions , maybe_sysroot : Option < PathBuf > ,
413
+ file_content : & str , filename : String ) -> Collector {
414
+ let mut line_number = 1 ;
415
+ let mut block_lines = HashMap :: new ( ) ;
416
+ for ( pos, block) in file_content. split ( "```" ) . enumerate ( ) {
417
+ if ( pos & 1 ) != 0 {
418
+ let key = format ! ( "{}" , block. replace( "/// " , "" ) . replace( "//!" , "" ) ) ;
419
+ if !block_lines. contains_key ( & key) {
420
+ block_lines. insert ( key. clone ( ) , Vec :: new ( ) ) ;
421
+ }
422
+ block_lines. get_mut ( & key) . unwrap ( ) . push ( line_number) ;
423
+ }
424
+ line_number += block. lines ( ) . count ( ) as u32 - 1 ;
425
+ }
426
+
397
427
Collector {
398
428
tests : Vec :: new ( ) ,
399
429
names : Vec :: new ( ) ,
@@ -406,7 +436,22 @@ impl Collector {
406
436
cratename : cratename,
407
437
opts : opts,
408
438
maybe_sysroot : maybe_sysroot,
439
+ code_blocks : block_lines,
440
+ filename : filename,
441
+ }
442
+ }
443
+
444
+ fn get_line_from_key ( & mut self , key : & String ) -> u32 {
445
+ let ( line, need_removal) = if let Some ( l) = self . code_blocks . get_mut ( key) {
446
+ let need_removal = l. len ( ) > 1 ;
447
+ ( l. pop ( ) . unwrap_or ( 1 ) , need_removal)
448
+ } else {
449
+ return 1 ;
450
+ } ;
451
+ if need_removal {
452
+ self . code_blocks . remove ( key) ;
409
453
}
454
+ line
410
455
}
411
456
412
457
pub fn add_test ( & mut self , test : String ,
@@ -427,6 +472,8 @@ impl Collector {
427
472
let opts = self . opts . clone ( ) ;
428
473
let maybe_sysroot = self . maybe_sysroot . clone ( ) ;
429
474
debug ! ( "Creating test {}: {}" , name, test) ;
475
+ let line_number = self . get_line_from_key ( & format ! ( "{}\n {}\n " , original, test) ) ;
476
+ let filename = self . filename . clone ( ) ;
430
477
self . tests . push ( testing:: TestDescAndFn {
431
478
desc : testing:: TestDesc {
432
479
name : testing:: DynTestName ( name) ,
@@ -453,7 +500,9 @@ impl Collector {
453
500
error_codes,
454
501
& opts,
455
502
maybe_sysroot,
456
- & original)
503
+ & original,
504
+ line_number,
505
+ & filename)
457
506
} )
458
507
} {
459
508
Ok ( ( ) ) => ( ) ,
0 commit comments