11use super :: watch:: WatchArgs ;
22use clap:: { Parser , ValueHint } ;
3- use eyre:: { Context , Result } ;
3+ use eyre:: Result ;
44use foundry_cli:: utils:: { FoundryPathExt , LoadConfig } ;
5- use foundry_common:: fs ;
5+ use foundry_common:: { errors :: convert_solar_errors , fs } ;
66use foundry_compilers:: { compilers:: solc:: SolcLanguage , solc:: SOLC_EXTENSIONS } ;
77use foundry_config:: { filter:: expand_globs, impl_figment_convert_basic} ;
88use rayon:: prelude:: * ;
@@ -11,7 +11,7 @@ use solar::sema::Compiler;
1111use std:: {
1212 fmt:: { self , Write } ,
1313 io,
14- io:: { Read , Write as _} ,
14+ io:: Write as _,
1515 path:: { Path , PathBuf } ,
1616 sync:: Arc ,
1717} ;
@@ -69,11 +69,7 @@ impl FmtArgs {
6969 . collect ( ) ;
7070 Input :: Paths ( project_paths)
7171 }
72- [ one] if one == Path :: new ( "-" ) => {
73- let mut s = String :: new ( ) ;
74- io:: stdin ( ) . read_to_string ( & mut s) . wrap_err ( "failed to read from stdin" ) ?;
75- Input :: Stdin ( s)
76- }
72+ [ one] if one == Path :: new ( "-" ) => Input :: Stdin ,
7773 paths => {
7874 let mut inputs = Vec :: with_capacity ( paths. len ( ) ) ;
7975 for path in paths {
@@ -99,88 +95,67 @@ impl FmtArgs {
9995 }
10096 } ;
10197
102- // Handle stdin on its own
103- if let Input :: Stdin ( original) = input {
104- let formatted = forge_fmt:: format ( & original, config. fmt )
105- . into_result ( )
106- . map_err ( |_| eyre:: eyre!( "failed to format stdin" ) ) ?;
107-
108- let diff = TextDiff :: from_lines ( & original, & formatted) ;
109- if diff. ratio ( ) < 1.0 {
110- if self . raw {
111- sh_print ! ( "{formatted}" ) ?;
112- } else {
113- sh_print ! ( "{}" , format_diff_summary( "stdin" , & diff) ) ?;
114- }
115- if self . check {
116- std:: process:: exit ( 1 ) ;
117- }
118- }
119- return Ok ( ( ) ) ;
120- }
98+ let mut compiler = Compiler :: new (
99+ solar:: interface:: Session :: builder ( ) . with_buffer_emitter ( Default :: default ( ) ) . build ( ) ,
100+ ) ;
121101
122- // Unwrap and check input paths
123- let paths_to_fmt = match input {
124- Input :: Paths ( paths) => {
125- if paths. is_empty ( ) {
102+ // Parse, format, and check the diffs.
103+ compiler. enter_mut ( |compiler| {
104+ let mut pcx = compiler. parse ( ) ;
105+ pcx. set_resolve_imports ( false ) ;
106+ match input {
107+ Input :: Paths ( paths) if paths. is_empty ( ) => {
126108 sh_warn ! (
127109 "Nothing to format.\n \
128- HINT: If you are working outside of the project, \
129- try providing paths to your source files: `forge fmt <paths>`"
110+ HINT: If you are working outside of the project, \
111+ try providing paths to your source files: `forge fmt <paths>`"
130112 ) ?;
131113 return Ok ( ( ) ) ;
132114 }
133- paths
115+ Input :: Paths ( paths) => _ = pcx. par_load_files ( paths) ,
116+ Input :: Stdin => _ = pcx. load_stdin ( ) ,
134117 }
135- Input :: Stdin ( _) => unreachable ! ( ) ,
136- } ;
137-
138- let mut compiler = Compiler :: new (
139- solar:: interface:: Session :: builder ( ) . with_buffer_emitter ( Default :: default ( ) ) . build ( ) ,
140- ) ;
141-
142- // Parse, format, and check the diffs.
143- let res = compiler. enter_mut ( |c| -> Result < ( ) > {
144- let mut pcx = c. parse ( ) ;
145- pcx. set_resolve_imports ( false ) ;
146- let _ = pcx. par_load_files ( paths_to_fmt) ;
147118 pcx. parse ( ) ;
148119
149- let gcx = c . gcx ( ) ;
120+ let gcx = compiler . gcx ( ) ;
150121 let fmt_config = Arc :: new ( config. fmt ) ;
151122 let diffs: Vec < String > = gcx
152123 . sources
153124 . raw
154125 . par_iter ( )
155126 . filter_map ( |source_unit| {
156- let path = source_unit. file . name . as_real ( ) ? ;
157- let original = & source_unit. file . src ;
127+ let path = source_unit. file . name . as_real ( ) ;
128+ let original = source_unit. file . src . as_str ( ) ;
158129 let formatted = forge_fmt:: format_ast ( gcx, source_unit, fmt_config. clone ( ) ) ?;
159130
160- if original. as_str ( ) == formatted {
131+ if original == formatted {
161132 return None ;
162133 }
163134
164- if self . check {
165- let name =
166- path. strip_prefix ( & config. root ) . unwrap_or ( path) . display ( ) . to_string ( ) ;
167- let summary = format_diff_summary (
168- & name,
169- & TextDiff :: from_lines ( original. as_str ( ) , & formatted) ,
170- ) ;
135+ if self . check || path. is_none ( ) {
136+ let summary = if self . raw {
137+ formatted
138+ } else {
139+ let name = match path {
140+ Some ( path) => path
141+ . strip_prefix ( & config. root )
142+ . unwrap_or ( path)
143+ . display ( )
144+ . to_string ( ) ,
145+ None => "stdin" . to_string ( ) ,
146+ } ;
147+ format_diff_summary ( & name, & TextDiff :: from_lines ( original, & formatted) )
148+ } ;
171149 Some ( Ok ( summary) )
172- } else {
150+ } else if let Some ( path ) = path {
173151 match fs:: write ( path, formatted) {
174- Ok ( _) => {
175- let _ = sh_println ! ( "Formatted {}" , path. display( ) ) ;
176- None
177- }
178- Err ( e) => Some ( Err ( eyre:: eyre!(
179- "Failed to write to {}: {}" ,
180- path. display( ) ,
181- e
182- ) ) ) ,
152+ Ok ( ( ) ) => { }
153+ Err ( e) => return Some ( Err ( e. into ( ) ) ) ,
183154 }
155+ let _ = sh_println ! ( "Formatted {}" , path. display( ) ) ;
156+ None
157+ } else {
158+ unreachable ! ( )
184159 }
185160 } )
186161 . collect :: < Result < _ > > ( ) ?;
@@ -194,15 +169,13 @@ impl FmtArgs {
194169 }
195170 let _ = stdout. write_all ( diff. as_bytes ( ) ) ;
196171 }
197- std:: process:: exit ( 1 ) ;
172+ if self . check {
173+ std:: process:: exit ( 1 ) ;
174+ }
198175 }
199- Ok ( ( ) )
200- } ) ;
201- res?;
202176
203- // TODO(dani): convert solar errors
204-
205- Ok ( ( ) )
177+ convert_solar_errors ( compiler. dcx ( ) )
178+ } )
206179 }
207180
208181 /// Returns whether `FmtArgs` was configured with `--watch`
@@ -211,14 +184,14 @@ impl FmtArgs {
211184 }
212185}
213186
214- struct Line ( Option < usize > ) ;
215-
216187#[ derive( Debug ) ]
217188enum Input {
218- Stdin ( String ) ,
189+ Stdin ,
219190 Paths ( Vec < PathBuf > ) ,
220191}
221192
193+ struct Line ( Option < usize > ) ;
194+
222195impl fmt:: Display for Line {
223196 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
224197 match self . 0 {
0 commit comments