99//! needs to read-after-write from a file, then it would be added to this
1010//! abstraction.
1111
12+ use errors;
13+
14+ use std:: cell:: RefCell ;
1215use std:: fs;
1316use std:: io;
1417use std:: path:: Path ;
18+ use std:: sync:: Arc ;
19+ use std:: sync:: mpsc:: { channel, Receiver , Sender } ;
1520
1621macro_rules! try_err {
1722 ( $e: expr, $file: expr) => { {
@@ -26,14 +31,45 @@ pub trait PathError {
2631 fn new < P : AsRef < Path > > ( e : io:: Error , path : P ) -> Self ;
2732}
2833
34+ pub struct ErrorStorage {
35+ sender : Sender < Option < String > > ,
36+ receiver : Receiver < Option < String > > ,
37+ }
38+
39+ impl ErrorStorage {
40+ pub fn new ( ) -> ErrorStorage {
41+ let ( sender, receiver) = channel ( ) ;
42+ ErrorStorage {
43+ sender,
44+ receiver,
45+ }
46+ }
47+
48+ /// Prints all stored errors. Returns the number of printed errors.
49+ pub fn write_errors ( & self , diag : & errors:: Handler ) -> usize {
50+ let mut printed = 0 ;
51+ drop ( self . sender ) ;
52+
53+ for msg in self . receiver . iter ( ) {
54+ if let Some ( ref error) = msg {
55+ diag. struct_err ( & error) . emit ( ) ;
56+ printed += 1 ;
57+ }
58+ }
59+ printed
60+ }
61+ }
62+
2963pub struct DocFS {
3064 sync_only : bool ,
65+ errors : Arc < ErrorStorage > ,
3166}
3267
3368impl DocFS {
34- pub fn new ( ) -> DocFS {
69+ pub fn new ( errors : & Arc < ErrorStorage > ) -> DocFS {
3570 DocFS {
3671 sync_only : false ,
72+ errors : Arc :: clone ( errors) ,
3773 }
3874 }
3975
@@ -59,16 +95,19 @@ impl DocFS {
5995 // be to create the file sync so errors are reported eagerly.
6096 let contents = contents. as_ref ( ) . to_vec ( ) ;
6197 let path = path. as_ref ( ) . to_path_buf ( ) ;
62- rayon:: spawn ( move ||
98+ let sender = self . errors . sender . clone ( ) ;
99+ rayon:: spawn ( move || {
63100 match fs:: write ( & path, & contents) {
64- Ok ( _) => ( ) ,
101+ Ok ( _) => {
102+ sender. send ( None )
103+ . expect ( & format ! ( "failed to send error on \" {}\" " , path. display( ) ) ) ;
104+ }
65105 Err ( e) => {
66- // In principle these should get displayed at the top
67- // level, but just in case, send to stderr as well.
68- eprintln ! ( "\" {}\" : {}" , path. display( ) , e) ;
69- panic ! ( "\" {}\" : {}" , path. display( ) , e) ;
106+ sender. send ( Some ( format ! ( "\" {}\" : {}" , path. display( ) , e) ) )
107+ . expect ( & format ! ( "failed to send non-error on \" {}\" " , path. display( ) ) ) ;
70108 }
71- } ) ;
109+ }
110+ } ) ;
72111 Ok ( ( ) )
73112 } else {
74113 Ok ( try_err ! ( fs:: write( & path, contents) , path) )
0 commit comments