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