9
9
//! needs to read-after-write from a file, then it would be added to this
10
10
//! abstraction.
11
11
12
+ use errors;
13
+
14
+ use std:: cell:: RefCell ;
12
15
use std:: fs;
13
16
use std:: io;
14
17
use std:: path:: Path ;
18
+ use std:: sync:: Arc ;
19
+ use std:: sync:: mpsc:: { channel, Receiver , Sender } ;
15
20
16
21
macro_rules! try_err {
17
22
( $e: expr, $file: expr) => { {
@@ -26,14 +31,45 @@ pub trait PathError {
26
31
fn new < P : AsRef < Path > > ( e : io:: Error , path : P ) -> Self ;
27
32
}
28
33
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
+
29
63
pub struct DocFS {
30
64
sync_only : bool ,
65
+ errors : Arc < ErrorStorage > ,
31
66
}
32
67
33
68
impl DocFS {
34
- pub fn new ( ) -> DocFS {
69
+ pub fn new ( errors : & Arc < ErrorStorage > ) -> DocFS {
35
70
DocFS {
36
71
sync_only : false ,
72
+ errors : Arc :: clone ( errors) ,
37
73
}
38
74
}
39
75
@@ -59,16 +95,19 @@ impl DocFS {
59
95
// be to create the file sync so errors are reported eagerly.
60
96
let contents = contents. as_ref ( ) . to_vec ( ) ;
61
97
let path = path. as_ref ( ) . to_path_buf ( ) ;
62
- rayon:: spawn ( move ||
98
+ let sender = self . errors . sender . clone ( ) ;
99
+ rayon:: spawn ( move || {
63
100
match fs:: write ( & path, & contents) {
64
- Ok ( _) => ( ) ,
101
+ Ok ( _) => {
102
+ sender. send ( None )
103
+ . expect ( & format ! ( "failed to send error on \" {}\" " , path. display( ) ) ) ;
104
+ }
65
105
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( ) ) ) ;
70
108
}
71
- } ) ;
109
+ }
110
+ } ) ;
72
111
Ok ( ( ) )
73
112
} else {
74
113
Ok ( try_err ! ( fs:: write( & path, contents) , path) )
0 commit comments