33
44use std:: {
55 process:: Command ,
6- sync:: { Arc , Mutex } ,
6+ sync:: { Arc , Mutex , MutexGuard } ,
77} ;
88
9+ use log:: Level ;
910// non-std crates
1011use serde:: Deserialize ;
1112use serde_xml_rs:: de:: Deserializer ;
1213
1314// project-specific crates/modules
15+ use super :: MakeSuggestions ;
1416use crate :: {
15- cli:: LinesChangedOnly ,
17+ cli:: ClangParams ,
1618 common_fs:: { get_line_cols_from_offset, FileObj } ,
1719} ;
1820
@@ -23,6 +25,18 @@ pub struct FormatAdvice {
2325 /// A list of [`Replacement`]s that clang-tidy wants to make.
2426 #[ serde( rename = "$value" ) ]
2527 pub replacements : Vec < Replacement > ,
28+
29+ pub patched : Option < Vec < u8 > > ,
30+ }
31+
32+ impl MakeSuggestions for FormatAdvice {
33+ fn get_suggestion_help ( & self , _start_line : u32 , _end_line : u32 ) -> String {
34+ String :: from ( "### clang-format suggestions\n " )
35+ }
36+
37+ fn get_tool_name ( & self ) -> String {
38+ "clang-format" . to_string ( )
39+ }
2640}
2741
2842/// A single replacement that clang-format wants to make.
@@ -79,24 +93,52 @@ pub fn tally_format_advice(files: &[Arc<Mutex<FileObj>>]) -> u64 {
7993
8094/// Run clang-tidy for a specific `file`, then parse and return it's XML output.
8195pub fn run_clang_format (
82- cmd : & mut Command ,
83- file : & mut Arc < Mutex < FileObj > > ,
84- style : & str ,
85- lines_changed_only : & LinesChangedOnly ,
96+ file : & mut MutexGuard < FileObj > ,
97+ clang_params : & ClangParams ,
8698) -> Vec < ( log:: Level , String ) > {
99+ let mut cmd = Command :: new ( clang_params. clang_format_command . as_ref ( ) . unwrap ( ) ) ;
87100 let mut logs = vec ! [ ] ;
88- let mut file = file. lock ( ) . unwrap ( ) ;
89- cmd. args ( [ "--style" , style, "--output-replacements-xml" ] ) ;
90- let ranges = file. get_ranges ( lines_changed_only) ;
101+ cmd. args ( [ "--style" , & clang_params. style ] ) ;
102+ let ranges = file. get_ranges ( & clang_params. lines_changed_only ) ;
91103 for range in & ranges {
92104 cmd. arg ( format ! ( "--lines={}:{}" , range. start( ) , range. end( ) ) ) ;
93105 }
94106 cmd. arg ( file. name . to_string_lossy ( ) . as_ref ( ) ) ;
107+ let mut patched = None ;
108+ if clang_params. format_review {
109+ logs. push ( (
110+ Level :: Info ,
111+ format ! (
112+ "Getting format fixes with \" {} {}\" " ,
113+ clang_params
114+ . clang_format_command
115+ . as_ref( )
116+ . unwrap( )
117+ . to_str( )
118+ . unwrap( ) ,
119+ cmd. get_args( )
120+ . map( |a| a. to_str( ) . unwrap( ) )
121+ . collect:: <Vec <& str >>( )
122+ . join( " " )
123+ ) ,
124+ ) ) ;
125+ patched = Some (
126+ cmd. output ( )
127+ . expect ( "Failed to get fixes from clang-format" )
128+ . stdout ,
129+ ) ;
130+ }
131+ cmd. arg ( "--output-replacements-xml" ) ;
95132 logs. push ( (
96133 log:: Level :: Info ,
97134 format ! (
98135 "Running \" {} {}\" " ,
99- cmd. get_program( ) . to_string_lossy( ) ,
136+ clang_params
137+ . clang_format_command
138+ . as_ref( )
139+ . unwrap( )
140+ . to_str( )
141+ . unwrap( ) ,
100142 cmd. get_args( )
101143 . map( |x| x. to_str( ) . unwrap( ) )
102144 . collect:: <Vec <& str >>( )
@@ -129,7 +171,9 @@ pub fn run_clang_format(
129171 let mut format_advice = FormatAdvice :: deserialize ( & mut Deserializer :: new ( event_reader) )
130172 . unwrap_or ( FormatAdvice {
131173 replacements : vec ! [ ] ,
174+ patched : None ,
132175 } ) ;
176+ format_advice. patched = patched;
133177 if !format_advice. replacements . is_empty ( ) {
134178 let mut filtered_replacements = Vec :: new ( ) ;
135179 for replacement in & mut format_advice. replacements {
@@ -201,6 +245,7 @@ mod tests {
201245 cols: None ,
202246 } ,
203247 ] ,
248+ patched : None ,
204249 } ;
205250 let config = serde_xml_rs:: ParserConfig :: new ( )
206251 . trim_whitespace ( false )
0 commit comments