@@ -19,9 +19,13 @@ use stack_graphs::stitching::Database;
1919use stack_graphs:: stitching:: DatabaseCandidates ;
2020use stack_graphs:: stitching:: ForwardPartialPathStitcher ;
2121use stack_graphs:: stitching:: StitcherConfig ;
22+ use std:: collections:: hash_map:: Entry ;
23+ use std:: collections:: HashMap ;
24+ use std:: collections:: HashSet ;
2225use std:: path:: Path ;
2326use std:: path:: PathBuf ;
2427use std:: time:: Duration ;
28+ use tree_sitter:: Language ;
2529use tree_sitter_graph:: Variables ;
2630
2731use crate :: cli:: util:: duration_from_seconds_str;
@@ -176,10 +180,16 @@ impl TestArgs {
176180 pub fn run ( self , mut loader : Loader ) -> anyhow:: Result < ( ) > {
177181 let reporter = self . get_reporter ( ) ;
178182 let mut total_result = TestResult :: new ( ) ;
183+ let mut cache = HashMap :: new ( ) ;
179184 for ( test_root, test_path, _) in iter_files_and_directories ( self . test_paths . clone ( ) ) {
180185 let mut file_status = CLIFileReporter :: new ( & reporter, & test_path) ;
181- let test_result =
182- self . run_test ( & test_root, & test_path, & mut loader, & mut file_status) ?;
186+ let test_result = self . run_test (
187+ & test_root,
188+ & test_path,
189+ & mut loader,
190+ & mut file_status,
191+ & mut cache,
192+ ) ?;
183193 file_status. assert_reported ( ) ;
184194 total_result. absorb ( test_result) ;
185195 }
@@ -211,14 +221,15 @@ impl TestArgs {
211221 }
212222
213223 /// Run test file. Takes care of the output when an error is returned.
214- fn run_test (
224+ fn run_test < ' a > (
215225 & self ,
216226 test_root : & Path ,
217227 test_path : & Path ,
218- loader : & mut Loader ,
228+ loader : & ' a mut Loader ,
219229 file_status : & mut CLIFileReporter ,
230+ cache : & mut HashMap < Language , stack_graphs:: serde:: Database > ,
220231 ) -> anyhow:: Result < TestResult > {
221- match self . run_test_inner ( test_root, test_path, loader, file_status) {
232+ match self . run_test_inner ( test_root, test_path, loader, file_status, cache ) {
222233 ok @ Ok ( _) => ok,
223234 err @ Err ( _) => {
224235 file_status. failure_if_processing ( "error" , None ) ;
@@ -227,12 +238,13 @@ impl TestArgs {
227238 }
228239 }
229240
230- fn run_test_inner (
241+ fn run_test_inner < ' a > (
231242 & self ,
232243 test_root : & Path ,
233244 test_path : & Path ,
234- loader : & mut Loader ,
245+ loader : & ' a mut Loader ,
235246 file_status : & mut CLIFileReporter ,
247+ cache : & mut HashMap < Language , stack_graphs:: serde:: Database > ,
236248 ) -> anyhow:: Result < TestResult > {
237249 let cancellation_flag = CancelAfterDuration :: from_option ( self . max_test_time ) ;
238250
@@ -263,11 +275,24 @@ impl TestArgs {
263275
264276 file_status. processing ( ) ;
265277
278+ let stitcher_config =
279+ StitcherConfig :: default ( ) . with_detect_similar_paths ( !lc. no_similar_paths_in_file ) ;
280+ let mut partials = PartialPaths :: new ( ) ;
281+ let mut db = Database :: new ( ) ;
282+
266283 let source = file_reader. get ( test_path) ?;
267284 let default_fragment_path = test_path. strip_prefix ( test_root) . unwrap ( ) ;
268285 let mut test = Test :: from_source ( test_path, source, default_fragment_path) ?;
269286 if !self . no_builtins {
270- self . load_builtins_into ( & lc, & mut test. graph ) ?;
287+ self . load_builtins_into (
288+ & lc,
289+ & mut test. graph ,
290+ & mut partials,
291+ & mut db,
292+ stitcher_config,
293+ cancellation_flag. as_ref ( ) ,
294+ cache,
295+ ) ?;
271296 }
272297 let mut globals = Variables :: new ( ) ;
273298 for test_fragment in & test. fragments {
@@ -325,15 +350,11 @@ impl TestArgs {
325350 Ok ( _) => { }
326351 }
327352 }
328- let stitcher_config =
329- StitcherConfig :: default ( ) . with_detect_similar_paths ( !lc. no_similar_paths_in_file ) ;
330- let mut partials = PartialPaths :: new ( ) ;
331- let mut db = Database :: new ( ) ;
332- for file in test. graph . iter_files ( ) {
353+ for fragment in & test. fragments {
333354 ForwardPartialPathStitcher :: find_minimal_partial_path_set_in_file (
334355 & test. graph ,
335356 & mut partials,
336- file,
357+ fragment . file ,
337358 stitcher_config,
338359 & cancellation_flag. as_ref ( ) ,
339360 |g, ps, p| {
@@ -387,14 +408,45 @@ impl TestArgs {
387408 Ok ( result)
388409 }
389410
390- fn load_builtins_into (
411+ fn load_builtins_into < ' a > (
391412 & self ,
392- lc : & LanguageConfiguration ,
413+ lc : & ' a LanguageConfiguration ,
393414 graph : & mut StackGraph ,
415+ partials : & mut PartialPaths ,
416+ db : & mut Database ,
417+ stitcher_config : StitcherConfig ,
418+ cancellation_flag : & dyn CancellationFlag ,
419+ cache : & mut HashMap < Language , stack_graphs:: serde:: Database > ,
394420 ) -> anyhow:: Result < ( ) > {
395- if let Err ( h) = graph. add_from_graph ( & lc. builtins ) {
396- return Err ( anyhow ! ( "Duplicate builtin file {}" , & graph[ h] ) ) ;
397- }
421+ let files = graph
422+ . add_from_graph ( & lc. builtins )
423+ . map_err ( |h| anyhow ! ( "Duplicate builtin file {}" , & graph[ h] ) ) ?;
424+ let files = files. into_iter ( ) . collect :: < HashSet < _ > > ( ) ;
425+ match cache. entry ( lc. language ) {
426+ Entry :: Occupied ( o) => {
427+ o. get ( ) . load_into ( graph, partials, db) ?;
428+ }
429+ Entry :: Vacant ( v) => {
430+ for file in & files {
431+ ForwardPartialPathStitcher :: find_minimal_partial_path_set_in_file (
432+ graph,
433+ partials,
434+ * file,
435+ stitcher_config,
436+ & cancellation_flag,
437+ |g, ps, p| {
438+ db. add_partial_path ( g, ps, p. clone ( ) ) ;
439+ } ,
440+ ) ?;
441+ }
442+ v. insert ( db. to_serializable_filter (
443+ graph,
444+ partials,
445+ & |_: & StackGraph , f : & Handle < File > | files. contains ( f) ,
446+ ) ) ;
447+ }
448+ } ;
449+
398450 Ok ( ( ) )
399451 }
400452
0 commit comments