@@ -273,13 +273,13 @@ fn collect_call(
273
273
274
274
match fun_symbol. as_str ( ) {
275
275
"test_that" => collect_call_test_that ( node, contents, symbols) ?,
276
- _ => collect_call_methods ( node, contents, symbols) ?,
276
+ _ => collect_call_arguments ( node, contents, symbols) ?,
277
277
}
278
278
279
279
Ok ( ( ) )
280
280
}
281
281
282
- fn collect_call_methods (
282
+ fn collect_call_arguments (
283
283
node : & Node ,
284
284
contents : & Rope ,
285
285
symbols : & mut Vec < DocumentSymbol > ,
@@ -297,42 +297,57 @@ fn collect_call_methods(
297
297
let Some ( arg_value) = arg. child_by_field_name ( "value" ) else {
298
298
continue ;
299
299
} ;
300
- if arg_value. kind ( ) != "function_definition" {
301
- continue ;
300
+
301
+ // Recurse into arguments. They might be a braced list, another call
302
+ // that might contain functions, etc.
303
+ collect_symbols ( & arg_value, contents, 0 , symbols) ?;
304
+
305
+ if arg_value. kind ( ) == "function_definition" {
306
+ // Functions are not collected by `collect_symbols()` so we deal
307
+ // with them here by processing the function body to extract child
308
+ // symbols. We do this even if it's not a "method", i.e. if it's not
309
+ // named.
310
+ let body = arg_value. child_by_field_name ( "body" ) . into_result ( ) ?;
311
+ let mut children = Vec :: new ( ) ;
312
+ collect_symbols ( & body, contents, 0 , & mut children) ?;
313
+
314
+ // If there is a name node, collect it as a method
315
+ if let Some ( arg_fun) = arg. child_by_field_name ( "name" ) {
316
+ collect_method ( & arg_fun, & arg_value, contents, symbols) ?;
317
+ } ;
302
318
}
319
+ }
303
320
304
- // Process the function body to extract child symbols.
305
- // We do this even if it's not a "method", i.e. if it's not named.
306
- let body = arg_value. child_by_field_name ( "body" ) . into_result ( ) ?;
307
- let mut children = Vec :: new ( ) ;
308
- collect_symbols ( & body, contents, 0 , & mut children) ?;
321
+ Ok ( ( ) )
322
+ }
309
323
310
- // There must be a name node, we're only collecting named functions as methods
311
- let Some ( arg_name) = arg. child_by_field_name ( "name" ) else {
312
- continue ;
313
- } ;
314
- if !arg_name. is_identifier_or_string ( ) {
315
- continue ;
316
- }
317
- let arg_name_str = contents. node_slice ( & arg_name) ?. to_string ( ) ;
324
+ fn collect_method (
325
+ arg_fun : & Node ,
326
+ arg_value : & Node ,
327
+ contents : & Rope ,
328
+ symbols : & mut Vec < DocumentSymbol > ,
329
+ ) -> anyhow:: Result < ( ) > {
330
+ if !arg_fun. is_identifier_or_string ( ) {
331
+ return Ok ( ( ) ) ;
332
+ }
333
+ let arg_name_str = contents. node_slice ( & arg_fun) ?. to_string ( ) ;
318
334
319
- let start = convert_point_to_position ( contents, arg_value. start_position ( ) ) ;
320
- let end = convert_point_to_position ( contents, arg_value. end_position ( ) ) ;
335
+ let start = convert_point_to_position ( contents, arg_value. start_position ( ) ) ;
336
+ let end = convert_point_to_position ( contents, arg_value. end_position ( ) ) ;
321
337
322
- let mut symbol = new_symbol_node (
323
- arg_name_str,
324
- SymbolKind :: METHOD ,
325
- Range { start, end } ,
326
- vec ! [ ] ,
327
- ) ;
338
+ let mut symbol = new_symbol_node (
339
+ arg_name_str,
340
+ SymbolKind :: METHOD ,
341
+ Range { start, end } ,
342
+ vec ! [ ] ,
343
+ ) ;
328
344
329
- // Don't include whole function as detail as the body often doesn't
330
- // provide useful information and only make the outline more busy (with
331
- // curly braces, newline characters, etc).
332
- symbol. detail = Some ( String :: from ( "function()" ) ) ;
345
+ // Don't include whole function as detail as the body often doesn't
346
+ // provide useful information and only make the outline more busy (with
347
+ // curly braces, newline characters, etc).
348
+ symbol. detail = Some ( String :: from ( "function()" ) ) ;
333
349
334
- symbols. push ( symbol) ;
335
- }
350
+ symbols. push ( symbol) ;
336
351
337
352
Ok ( ( ) )
338
353
}
@@ -765,11 +780,18 @@ list(
765
780
"
766
781
) ) ;
767
782
}
768
- }
769
783
770
- // chat <- r6::r6class(
771
- // "chat",
772
- // public = list(
773
- // initialize = function() "initialize",
774
- // )
775
- // )
784
+ #[ test]
785
+ fn test_symbol_call_arguments ( ) {
786
+ insta:: assert_debug_snapshot!( test_symbol(
787
+ "
788
+ # section ----
789
+ local({
790
+ a <- function() {
791
+ 1
792
+ }
793
+ })
794
+ "
795
+ ) ) ;
796
+ }
797
+ }
0 commit comments