1
1
use std:: fs;
2
2
use std:: io:: { self , Write } ;
3
+ use std:: path:: Path ;
4
+
5
+ use syntax:: source_map:: SourceMap ;
3
6
4
7
use crate :: checkstyle:: output_checkstyle_file;
5
8
use crate :: config:: { Config , EmitMode , FileName , Verbosity } ;
26
29
write ! ( out, "{}" , crate :: checkstyle:: header( ) ) ?;
27
30
}
28
31
for & ( ref filename, ref text) in source_file {
29
- write_file ( text , filename, out, config) ?;
32
+ write_file ( None , filename, text , out, config) ?;
30
33
}
31
34
if config. emit_mode ( ) == EmitMode :: Checkstyle {
32
35
write ! ( out, "{}" , crate :: checkstyle:: footer( ) ) ?;
@@ -36,24 +39,46 @@ where
36
39
}
37
40
38
41
pub fn write_file < T > (
39
- formatted_text : & str ,
42
+ source_map : Option < & SourceMap > ,
40
43
filename : & FileName ,
44
+ formatted_text : & str ,
41
45
out : & mut T ,
42
46
config : & Config ,
43
47
) -> Result < bool , io:: Error >
44
48
where
45
49
T : Write ,
46
50
{
47
- let filename_to_path = || match * filename {
48
- FileName :: Real ( ref path) => path,
49
- _ => panic ! ( "cannot format `{}` and emit to files" , filename) ,
51
+ fn ensure_real_path ( filename : & FileName ) -> & Path {
52
+ match * filename {
53
+ FileName :: Real ( ref path) => path,
54
+ _ => panic ! ( "cannot format `{}` and emit to files" , filename) ,
55
+ }
56
+ }
57
+
58
+ impl From < & FileName > for syntax_pos:: FileName {
59
+ fn from ( filename : & FileName ) -> syntax_pos:: FileName {
60
+ match filename {
61
+ FileName :: Real ( path) => syntax_pos:: FileName :: Real ( path. to_owned ( ) ) ,
62
+ FileName :: Stdin => syntax_pos:: FileName :: Custom ( "stdin" . to_owned ( ) ) ,
63
+ }
64
+ }
65
+ }
66
+
67
+ // If parse session is around (cfg(not(test))) then try getting source from
68
+ // there instead of hitting the file system. This also supports getting
69
+ // original text for `FileName::Stdin`.
70
+ let original_text = source_map
71
+ . and_then ( |x| x. get_source_file ( & filename. into ( ) ) )
72
+ . and_then ( |x| x. src . as_ref ( ) . map ( |x| x. to_string ( ) ) ) ;
73
+ let original_text = match original_text {
74
+ Some ( ori) => ori,
75
+ None => fs:: read_to_string ( ensure_real_path ( filename) ) ?,
50
76
} ;
51
77
52
78
match config. emit_mode ( ) {
53
79
EmitMode :: Files if config. make_backup ( ) => {
54
- let filename = filename_to_path ( ) ;
55
- let ori = fs:: read_to_string ( filename) ?;
56
- if ori != formatted_text {
80
+ let filename = ensure_real_path ( filename) ;
81
+ if original_text != formatted_text {
57
82
// Do a little dance to make writing safer - write to a temp file
58
83
// rename the original to a .bk, then rename the temp file to the
59
84
// original.
67
92
}
68
93
EmitMode :: Files => {
69
94
// Write text directly over original file if there is a diff.
70
- let filename = filename_to_path ( ) ;
71
- let ori = fs :: read_to_string ( filename ) ? ;
72
- if ori != formatted_text {
95
+ let filename = ensure_real_path ( filename ) ;
96
+
97
+ if original_text != formatted_text {
73
98
fs:: write ( filename, formatted_text) ?;
74
99
}
75
100
}
@@ -80,27 +105,23 @@ where
80
105
write ! ( out, "{}" , formatted_text) ?;
81
106
}
82
107
EmitMode :: ModifiedLines => {
83
- let filename = filename_to_path ( ) ;
84
- let ori = fs:: read_to_string ( filename) ?;
85
- let mismatch = make_diff ( & ori, formatted_text, 0 ) ;
108
+ let mismatch = make_diff ( & original_text, formatted_text, 0 ) ;
86
109
let has_diff = !mismatch. is_empty ( ) ;
87
110
output_modified ( out, mismatch) ;
88
111
return Ok ( has_diff) ;
89
112
}
90
113
EmitMode :: Checkstyle => {
91
- let filename = filename_to_path ( ) ;
92
- let ori = fs :: read_to_string ( filename ) ? ;
93
- let diff = make_diff ( & ori , formatted_text, 3 ) ;
114
+ let filename = ensure_real_path ( filename ) ;
115
+
116
+ let diff = make_diff ( & original_text , formatted_text, 3 ) ;
94
117
output_checkstyle_file ( out, filename, diff) ?;
95
118
}
96
119
EmitMode :: Diff => {
97
- let filename = filename_to_path ( ) ;
98
- let ori = fs:: read_to_string ( filename) ?;
99
- let mismatch = make_diff ( & ori, formatted_text, 3 ) ;
120
+ let mismatch = make_diff ( & original_text, formatted_text, 3 ) ;
100
121
let has_diff = !mismatch. is_empty ( ) ;
101
122
print_diff (
102
123
mismatch,
103
- |line_num| format ! ( "Diff in {} at line {}:" , filename. display ( ) , line_num) ,
124
+ |line_num| format ! ( "Diff in {} at line {}:" , filename, line_num) ,
104
125
config,
105
126
) ;
106
127
return Ok ( has_diff) ;
0 commit comments