@@ -273,7 +273,7 @@ defmodule ElixirSense.Core.TypeInfo do
273
273
274
274
defp get_param_type_specs ( func_specs , npar ) do
275
275
for func_spec <- func_specs ,
276
- params_types = extract_params_types ( func_spec ) ,
276
+ params_types <- extract_params_types_variants ( func_spec ) ,
277
277
length ( params_types ) > npar do
278
278
params_types |> Enum . at ( npar )
279
279
end
@@ -341,6 +341,31 @@ defmodule ElixirSense.Core.TypeInfo do
341
341
extract_tagged_tuple_name_and_type ( { mod , type } )
342
342
end
343
343
344
+ defp extract_union_options_name_and_type ( { mod , { _kind , { _ , { :atom , _ , name } , _ } } } ) do
345
+ [ { mod , name } ]
346
+ end
347
+
348
+ defp extract_union_options_name_and_type (
349
+ { mod , { _kind , { _name , { :remote_type , _ , _ } = type , _ } } }
350
+ ) do
351
+ extract_tagged_tuple_name_and_type ( { mod , type } )
352
+ end
353
+
354
+ defp extract_union_options_name_and_type (
355
+ { mod , { _kind , { _name , { :user_type , _ , _ , _ } = type , _ } } }
356
+ ) do
357
+ extract_tagged_tuple_name_and_type ( { mod , type } )
358
+ end
359
+
360
+ defp extract_union_options_name_and_type ( { mod , { :atom , _ , atom } } ) when is_atom ( atom ) do
361
+ [ { mod , atom } ]
362
+ end
363
+
364
+ # skip unknown type
365
+ defp extract_union_options_name_and_type ( _ ) do
366
+ [ ]
367
+ end
368
+
344
369
defp extract_tagged_tuple_name_and_type ( { mod , { :type , _ , :tuple , [ { :atom , _ , name } , type ] } } ) do
345
370
[ { mod , name , type } ]
346
371
end
@@ -350,6 +375,9 @@ defmodule ElixirSense.Core.TypeInfo do
350
375
{ _mod , { _kind , { _name , { :type , _ , :union , _ } , _ } } } = expanded_type ->
351
376
extract_union_options_name_and_type ( expanded_type )
352
377
378
+ { mod , { :atom , _ , name } } ->
379
+ [ { mod , name } ]
380
+
353
381
_ ->
354
382
[ ]
355
383
end
@@ -395,13 +423,16 @@ defmodule ElixirSense.Core.TypeInfo do
395
423
false
396
424
end
397
425
398
- defp extract_params_types (
399
- { :spec , { _ , [ { :type , _ , :fun , [ { :type , _ , :product , params_types } , _ ] } ] } }
400
- ) do
426
+ defp extract_params_types_variants ( { :spec , { _ , list } } ) do
427
+ list
428
+ |> Enum . map ( & extract_params_types / 1 )
429
+ end
430
+
431
+ defp extract_params_types ( { :type , _ , :fun , [ { :type , _ , :product , params_types } , _ ] } ) do
401
432
params_types
402
433
end
403
434
404
- defp extract_params_types ( { :spec , { _ , [ { : type, _ , :bounded_fun , [ type , constraints ] } ] } } ) do
435
+ defp extract_params_types ( { :type , _ , :bounded_fun , [ type , constraints ] } ) do
405
436
{ :type , _ , :fun , [ { :type , _ , :product , params } , _ ] } = type
406
437
407
438
vars_types =
@@ -411,16 +442,41 @@ defmodule ElixirSense.Core.TypeInfo do
411
442
{ var , var_type }
412
443
end
413
444
414
- Enum . map ( params , fn
415
- { :var , _ , name } ->
416
- vars_types [ name ]
445
+ params
446
+ |> Enum . map ( & expand_var_types ( & 1 , vars_types , [ ] ) )
447
+ # reject failed expansions
448
+ |> Enum . reject ( & is_nil / 1 )
449
+ end
417
450
418
- { :type , l , :list , [ { :var , _ , name } ] } ->
419
- { :type , l , :list , [ vars_types [ name ] ] }
451
+ defp expand_var_types ( var_type , vars_types , expanded_types ) do
452
+ if var_type in expanded_types do
453
+ # break recursive type expansion
454
+ nil
455
+ else
456
+ do_expand_var_types ( var_type , vars_types , [ var_type | expanded_types ] )
457
+ end
458
+ end
420
459
421
- type ->
422
- type
423
- end )
460
+ defp do_expand_var_types ( { :var , _ , name } , vars_types , expanded_types ) do
461
+ expand_var_types ( vars_types [ name ] , vars_types , expanded_types )
462
+ end
463
+
464
+ defp do_expand_var_types ( { :type , l , kind , tuple_elements } , vars_types , expanded_types )
465
+ when kind in [ :list , :tuple , :union ] and is_list ( tuple_elements ) do
466
+ expanded =
467
+ for ( element <- tuple_elements , do: expand_var_types ( element , vars_types , expanded_types ) )
468
+ # reject failed expansions
469
+ |> Enum . reject ( & is_nil / 1 )
470
+
471
+ { :type , l , kind , expanded }
472
+ end
473
+
474
+ defp do_expand_var_types ( { :ann_type , _l , [ { :var , _ , _ } , type ] } , vars_types , expanded_types ) do
475
+ expand_var_types ( type , vars_types , expanded_types )
476
+ end
477
+
478
+ defp do_expand_var_types ( type , _vars_types , _expanded_types ) do
479
+ type
424
480
end
425
481
426
482
defp starts_with_type_def? ( str , kind ) do
0 commit comments