7
7
8
8
use clap:: Args ;
9
9
use clap:: ValueHint ;
10
+ use stack_graphs:: arena:: Handle ;
11
+ use stack_graphs:: graph:: File ;
10
12
use stack_graphs:: graph:: StackGraph ;
11
13
use stack_graphs:: partial:: PartialPaths ;
12
14
use stack_graphs:: storage:: FileStatus ;
@@ -18,6 +20,7 @@ use std::time::Duration;
18
20
use thiserror:: Error ;
19
21
use tree_sitter_graph:: Variables ;
20
22
23
+ use crate :: loader:: FileLanguageConfigurations ;
21
24
use crate :: loader:: FileReader ;
22
25
use crate :: loader:: Loader ;
23
26
use crate :: BuildError ;
@@ -29,6 +32,7 @@ use super::util::duration_from_seconds_str;
29
32
use super :: util:: iter_files_and_directories;
30
33
use super :: util:: sha1;
31
34
use super :: util:: wait_for_input;
35
+ use super :: util:: BuildErrorWithSource ;
32
36
use super :: util:: ConsoleLogger ;
33
37
use super :: util:: ExistingPathBufValueParser ;
34
38
use super :: util:: FileLogger ;
@@ -219,23 +223,24 @@ impl<'a> Indexer<'a> {
219
223
}
220
224
221
225
let mut file_reader = FileReader :: new ( ) ;
222
- let lc = match self
226
+ let lcs = match self
223
227
. loader
224
228
. load_for_file ( source_path, & mut file_reader, & NoCancellation )
225
229
{
226
- Ok ( Some ( sgl) ) => sgl,
227
- Ok ( None ) => {
230
+ Ok ( lcs) if !lcs. has_some ( ) => {
228
231
if missing_is_error {
229
232
file_status. failure ( "not supported" , None ) ;
230
233
}
231
234
return Ok ( ( ) ) ;
232
235
}
236
+ Ok ( lcs) => lcs,
233
237
Err ( crate :: loader:: LoadError :: Cancelled ( _) ) => {
234
238
file_status. warning ( "language loading timed out" , None ) ;
235
239
return Ok ( ( ) ) ;
236
240
}
237
241
Err ( e) => return Err ( IndexError :: LoadError ( e) ) ,
238
242
} ;
243
+
239
244
let source = file_reader. get ( source_path) ?;
240
245
let tag = sha1 ( source) ;
241
246
@@ -264,64 +269,39 @@ impl<'a> Indexer<'a> {
264
269
let mut graph = StackGraph :: new ( ) ;
265
270
let file = graph
266
271
. add_file ( & source_path. to_string_lossy ( ) )
267
- . expect ( "file not present in emtpy graph" ) ;
272
+ . expect ( "file not present in empty graph" ) ;
268
273
269
- let relative_source_path = source_path. strip_prefix ( source_root) . unwrap ( ) ;
270
- let result = if let Some ( fa) = source_path
271
- . file_name ( )
272
- . and_then ( |f| lc. special_files . get ( & f. to_string_lossy ( ) ) )
273
- {
274
- fa. build_stack_graph_into (
275
- & mut graph,
276
- file,
277
- & relative_source_path,
278
- & source,
279
- & mut std:: iter:: empty ( ) ,
280
- & HashMap :: new ( ) ,
281
- & cancellation_flag,
282
- )
283
- } else {
284
- let globals = Variables :: new ( ) ;
285
- lc. sgl
286
- . build_stack_graph_into ( & mut graph, file, & source, & globals, & cancellation_flag)
287
- } ;
288
- match result {
289
- Err ( BuildError :: Cancelled ( _) ) => {
290
- file_status. warning ( "parsing timed out" , None ) ;
291
- self . db
292
- . store_error_for_file ( source_path, & tag, "parsing timed out" ) ?;
293
- return Ok ( ( ) ) ;
294
- }
295
- Err ( err @ BuildError :: ParseErrors ( _) ) => {
296
- file_status. failure (
297
- "parsing failed" ,
298
- Some ( & err. display_pretty (
299
- source_path,
300
- source,
301
- lc. sgl . tsg_path ( ) ,
302
- lc. sgl . tsg_source ( ) ,
303
- ) ) ,
304
- ) ;
305
- self . db . store_error_for_file (
306
- source_path,
307
- & tag,
308
- & format ! ( "parsing failed: {}" , err) ,
309
- ) ?;
310
- return Ok ( ( ) ) ;
311
- }
312
- Err ( err) => {
313
- file_status. failure (
314
- "failed to build stack graph" ,
315
- Some ( & err. display_pretty (
274
+ let result = Self :: build_stack_graph (
275
+ & mut graph,
276
+ file,
277
+ source_root,
278
+ source_path,
279
+ & source,
280
+ lcs,
281
+ & cancellation_flag,
282
+ ) ;
283
+ if let Err ( err) = result {
284
+ match err. inner {
285
+ BuildError :: Cancelled ( _) => {
286
+ file_status. warning ( "parsing timed out" , None ) ;
287
+ self . db
288
+ . store_error_for_file ( source_path, & tag, "parsing timed out" ) ?;
289
+ return Ok ( ( ) ) ;
290
+ }
291
+ BuildError :: ParseErrors { .. } => {
292
+ file_status. failure ( "parsing failed" , Some ( & err. display_pretty ( ) ) ) ;
293
+ self . db . store_error_for_file (
316
294
source_path,
317
- source,
318
- lc. sgl . tsg_path ( ) ,
319
- lc. sgl . tsg_source ( ) ,
320
- ) ) ,
321
- ) ;
322
- return Err ( IndexError :: StackGraph ) ;
295
+ & tag,
296
+ & format ! ( "parsing failed: {}" , err. inner) ,
297
+ ) ?;
298
+ return Ok ( ( ) ) ;
299
+ }
300
+ _ => {
301
+ file_status. failure ( "failed to build stack graph" , Some ( & err. display_pretty ( ) ) ) ;
302
+ return Err ( IndexError :: StackGraph ) ;
303
+ }
323
304
}
324
- Ok ( _) => true ,
325
305
} ;
326
306
327
307
let mut partials = PartialPaths :: new ( ) ;
@@ -354,6 +334,49 @@ impl<'a> Indexer<'a> {
354
334
Ok ( ( ) )
355
335
}
356
336
337
+ fn build_stack_graph < ' b > (
338
+ graph : & mut StackGraph ,
339
+ file : Handle < File > ,
340
+ source_root : & Path ,
341
+ source_path : & Path ,
342
+ source : & ' b str ,
343
+ lcs : FileLanguageConfigurations < ' b > ,
344
+ cancellation_flag : & dyn CancellationFlag ,
345
+ ) -> std:: result:: Result < ( ) , BuildErrorWithSource < ' b > > {
346
+ let relative_source_path = source_path. strip_prefix ( source_root) . unwrap ( ) ;
347
+ if let Some ( lc) = lcs. primary {
348
+ let globals = Variables :: new ( ) ;
349
+ lc. sgl
350
+ . build_stack_graph_into ( graph, file, source, & globals, cancellation_flag)
351
+ . map_err ( |inner| BuildErrorWithSource {
352
+ inner,
353
+ source_path : source_path. to_path_buf ( ) ,
354
+ source_str : source,
355
+ tsg_path : lc. sgl . tsg_path ( ) . to_path_buf ( ) ,
356
+ tsg_str : & lc. sgl . tsg_source ( ) ,
357
+ } ) ?;
358
+ }
359
+ for ( _, fa) in lcs. secondary {
360
+ fa. build_stack_graph_into (
361
+ graph,
362
+ file,
363
+ & relative_source_path,
364
+ & source,
365
+ & mut std:: iter:: empty ( ) ,
366
+ & HashMap :: new ( ) ,
367
+ cancellation_flag,
368
+ )
369
+ . map_err ( |inner| BuildErrorWithSource {
370
+ inner,
371
+ source_path : source_path. to_path_buf ( ) ,
372
+ source_str : & source,
373
+ tsg_path : PathBuf :: new ( ) ,
374
+ tsg_str : "" ,
375
+ } ) ?;
376
+ }
377
+ Ok ( ( ) )
378
+ }
379
+
357
380
/// Determines if a path should be skipped because we have not seen the
358
381
/// continue_from mark yet. If the mark is seen, it is cleared, after which
359
382
/// all paths are accepted.
0 commit comments