@@ -4,6 +4,7 @@ use figment::{
44 value:: { Dict , Map } ,
55} ;
66use foundry_compilers:: artifacts:: remappings:: { RelativeRemapping , Remapping } ;
7+ use rayon:: prelude:: * ;
78use std:: {
89 borrow:: Cow ,
910 collections:: { BTreeMap , HashSet , btree_map:: Entry } ,
@@ -207,19 +208,16 @@ impl RemappingsProvider<'_> {
207208 // TODO: if a lib specifies contexts for remappings manually, we need to figure out how to
208209 // resolve that
209210 if self . auto_detect_remappings {
211+ let ( nested_foundry_remappings, auto_detected_remappings) = rayon:: join (
212+ || self . find_nested_foundry_remappings ( ) ,
213+ || self . auto_detect_remappings ( ) ,
214+ ) ;
215+
210216 let mut lib_remappings = BTreeMap :: new ( ) ;
211- // find all remappings of from libs that use a foundry.toml
212- for r in self . lib_foundry_toml_remappings ( ) {
217+ for r in nested_foundry_remappings {
213218 insert_closest ( & mut lib_remappings, r. context , r. name , r. path . into ( ) ) ;
214219 }
215- // use auto detection for all libs
216- for r in self
217- . lib_paths
218- . iter ( )
219- . map ( |lib| self . root . join ( lib) )
220- . inspect ( |lib| trace ! ( ?lib, "find all remappings" ) )
221- . flat_map ( |lib| Remapping :: find_many ( & lib) )
222- {
220+ for r in auto_detected_remappings {
223221 // this is an additional safety check for weird auto-detected remappings
224222 if [ "lib/" , "src/" , "contracts/" ] . contains ( & r. name . as_str ( ) ) {
225223 trace ! ( target: "forge" , "- skipping the remapping" ) ;
@@ -246,50 +244,67 @@ impl RemappingsProvider<'_> {
246244 }
247245
248246 /// Returns all remappings declared in foundry.toml files of libraries
249- fn lib_foundry_toml_remappings ( & self ) -> impl Iterator < Item = Remapping > + ' _ {
247+ fn find_nested_foundry_remappings ( & self ) -> impl Iterator < Item = Remapping > + ' _ {
250248 self . lib_paths
251- . iter ( )
249+ . par_iter ( )
252250 . map ( |p| if p. is_absolute ( ) { self . root . join ( "lib" ) } else { self . root . join ( p) } )
253251 . flat_map ( foundry_toml_dirs)
254- . inspect ( |lib| {
255- trace ! ( "find all remappings of nested foundry.toml lib: {:?}" , lib) ;
252+ . flat_map_iter ( |lib| {
253+ trace ! ( ?lib, "find all remappings of nested foundry.toml" ) ;
254+ self . nested_foundry_remappings ( & lib)
256255 } )
257- . flat_map ( |lib : PathBuf | {
258- // load config, of the nested lib if it exists
259- let Ok ( config) = Config :: load_with_root ( & lib) else { return vec ! [ ] } ;
260- let config = config. sanitized ( ) ;
261-
262- // if the configured _src_ directory is set to something that
263- // [Remapping::find_many()] doesn't classify as a src directory (src, contracts,
264- // lib), then we need to manually add a remapping here
265- let mut src_remapping = None ;
266- if ![ Path :: new ( "src" ) , Path :: new ( "contracts" ) , Path :: new ( "lib" ) ]
267- . contains ( & config. src . as_path ( ) )
268- && let Some ( name) = lib. file_name ( ) . and_then ( |s| s. to_str ( ) )
269- {
270- let mut r = Remapping {
271- context : None ,
272- name : format ! ( "{name}/" ) ,
273- path : format ! ( "{}" , lib. join( & config. src) . display( ) ) ,
274- } ;
275- if !r. path . ends_with ( '/' ) {
276- r. path . push ( '/' )
277- }
278- src_remapping = Some ( r) ;
279- }
256+ . collect :: < Vec < _ > > ( )
257+ . into_iter ( )
258+ }
280259
281- // Eventually, we could set context for remappings at this location,
282- // taking into account the OS platform. We'll need to be able to handle nested
283- // contexts depending on dependencies for this to work.
284- // For now, we just leave the default context (none).
285- let mut remappings =
286- config. remappings . into_iter ( ) . map ( Remapping :: from) . collect :: < Vec < Remapping > > ( ) ;
260+ fn nested_foundry_remappings ( & self , lib : & Path ) -> Vec < Remapping > {
261+ // load config, of the nested lib if it exists
262+ let Ok ( config) = Config :: load_with_root ( lib) else { return vec ! [ ] } ;
263+ let config = config. sanitized ( ) ;
264+
265+ // if the configured _src_ directory is set to something that
266+ // `Remapping::find_many` doesn't classify as a src directory (src, contracts,
267+ // lib), then we need to manually add a remapping here
268+ let mut src_remapping = None ;
269+ if ![ Path :: new ( "src" ) , Path :: new ( "contracts" ) , Path :: new ( "lib" ) ]
270+ . contains ( & config. src . as_path ( ) )
271+ && let Some ( name) = lib. file_name ( ) . and_then ( |s| s. to_str ( ) )
272+ {
273+ let mut r = Remapping {
274+ context : None ,
275+ name : format ! ( "{name}/" ) ,
276+ path : format ! ( "{}" , lib. join( & config. src) . display( ) ) ,
277+ } ;
278+ if !r. path . ends_with ( '/' ) {
279+ r. path . push ( '/' )
280+ }
281+ src_remapping = Some ( r) ;
282+ }
287283
288- if let Some ( r) = src_remapping {
289- remappings. push ( r) ;
290- }
291- remappings
284+ // Eventually, we could set context for remappings at this location,
285+ // taking into account the OS platform. We'll need to be able to handle nested
286+ // contexts depending on dependencies for this to work.
287+ // For now, we just leave the default context (none).
288+ let mut remappings =
289+ config. remappings . into_iter ( ) . map ( Remapping :: from) . collect :: < Vec < Remapping > > ( ) ;
290+
291+ if let Some ( r) = src_remapping {
292+ remappings. push ( r) ;
293+ }
294+ remappings
295+ }
296+
297+ /// Auto detect remappings from the lib paths
298+ fn auto_detect_remappings ( & self ) -> impl Iterator < Item = Remapping > + ' _ {
299+ self . lib_paths
300+ . par_iter ( )
301+ . flat_map_iter ( |lib| {
302+ let lib = self . root . join ( lib) ;
303+ trace ! ( ?lib, "find all remappings" ) ;
304+ Remapping :: find_many ( & lib)
292305 } )
306+ . collect :: < Vec < _ > > ( )
307+ . into_iter ( )
293308 }
294309}
295310
0 commit comments