@@ -29,22 +29,22 @@ defmodule ElixirSense.Core.Compiler.Fn do
2929 when is_atom ( f ) and is_integer ( a ) do
3030 args = args_from_arity ( meta , a )
3131
32- capture_require ( { dot , require_meta , args } , s , e , true )
32+ capture_require ( { dot , require_meta , args } , s , e , :arity )
3333 end
3434
3535 def capture ( meta , { :/ , _ , [ { f , import_meta , c } , a ] } , s , e )
3636 when is_atom ( f ) and is_integer ( a ) and is_atom ( c ) do
3737 args = args_from_arity ( meta , a )
38- capture_import ( { f , import_meta , args } , s , e , true )
38+ capture_import ( { f , import_meta , args } , s , e , :arity )
3939 end
4040
4141 def capture ( _meta , { { :. , _ , [ _ , fun ] } , _ , args } = expr , s , e )
4242 when is_atom ( fun ) and is_list ( args ) do
43- capture_require ( expr , s , e , is_sequential_and_not_empty ( args ) )
43+ capture_require ( expr , s , e , check_sequential_and_not_empty ( args ) )
4444 end
4545
4646 def capture ( meta , { { :. , _ , [ _ ] } , _ , args } = expr , s , e ) when is_list ( args ) do
47- capture_expr ( meta , expr , s , e , false )
47+ capture_expr ( meta , expr , s , e , :non_sequential )
4848 end
4949
5050 def capture ( meta , { :__block__ , _ , [ expr ] } , s , e ) do
@@ -67,15 +67,15 @@ defmodule ElixirSense.Core.Compiler.Fn do
6767 end
6868
6969 def capture ( _meta , { atom , _ , args } = expr , s , e ) when is_atom ( atom ) and is_list ( args ) do
70- capture_import ( expr , s , e , is_sequential_and_not_empty ( args ) )
70+ capture_import ( expr , s , e , check_sequential_and_not_empty ( args ) )
7171 end
7272
7373 def capture ( meta , { left , right } , s , e ) do
7474 capture ( meta , { :{} , meta , [ left , right ] } , s , e )
7575 end
7676
7777 def capture ( meta , list , s , e ) when is_list ( list ) do
78- capture_expr ( meta , list , s , e , is_sequential_and_not_empty ( list ) )
78+ capture_expr ( meta , list , s , e , check_sequential_and_not_empty ( list ) )
7979 end
8080
8181 def capture ( meta , integer , s , e ) when is_integer ( integer ) do
@@ -97,24 +97,27 @@ defmodule ElixirSense.Core.Compiler.Fn do
9797 end
9898 end
9999
100- defp capture_import ( { atom , import_meta , args } = expr , s , e , sequential ) do
100+ defp capture_import ( { atom , import_meta , args } = expr , s , e , args_type ) do
101101 res =
102- if sequential do
102+ if args_type != :non_sequential do
103103 Dispatch . import_function ( import_meta , atom , length ( args ) , s , e )
104104 else
105105 false
106106 end
107107
108- handle_capture ( res , import_meta , import_meta , expr , s , e , sequential )
108+ handle_capture ( res , import_meta , import_meta , expr , s , e , args_type )
109109 end
110110
111- defp capture_require ( { { :. , dot_meta , [ left , right ] } , require_meta , args } , s , e , sequential ) do
111+ defp capture_require ( { { :. , dot_meta , [ left , right ] } , require_meta , args } , s , e , args_type ) do
112112 case escape ( left , [ ] ) do
113113 { esc_left , [ ] } ->
114114 { e_left , se , ee } = Compiler . expand ( esc_left , s , e )
115115
116+ # elixir emits complex_module_capture warning for complex module expressions in &mod.fun/arity
117+ # when args_type == :arity and e_left is not atom or variable
118+
116119 res =
117- if sequential do
120+ if args_type != :non_sequential do
118121 case e_left do
119122 { name , _ , context } when is_atom ( name ) and is_atom ( context ) ->
120123 { :remote , e_left , right , length ( args ) }
@@ -137,34 +140,35 @@ defmodule ElixirSense.Core.Compiler.Fn do
137140 end
138141
139142 dot = { { :. , dot_meta , [ e_left , right ] } , require_meta , args }
140- handle_capture ( res , require_meta , dot_meta , dot , se , ee , sequential )
143+ handle_capture ( res , require_meta , dot_meta , dot , se , ee , args_type )
141144
142145 { esc_left , escaped } ->
143146 dot = { { :. , dot_meta , [ esc_left , right ] } , require_meta , args }
144- capture_expr ( require_meta , dot , s , e , escaped , sequential )
147+ capture_expr ( require_meta , dot , s , e , escaped , args_type )
145148 end
146149 end
147150
148- defp handle_capture ( false , meta , _dot_meta , expr , s , e , sequential ) do
149- capture_expr ( meta , expr , s , e , sequential )
151+ defp handle_capture ( false , meta , _dot_meta , expr , s , e , args_type ) do
152+ capture_expr ( meta , expr , s , e , args_type )
150153 end
151154
152- defp handle_capture ( local_or_remote , meta , dot_meta , _expr , s , e , _sequential ) do
155+ defp handle_capture ( local_or_remote , meta , dot_meta , _expr , s , e , _args_type ) do
153156 { local_or_remote , meta , dot_meta , s , e }
154157 end
155158
156- defp capture_expr ( meta , expr , s , e , sequential ) do
157- capture_expr ( meta , expr , s , e , [ ] , sequential )
159+ defp capture_expr ( meta , expr , s , e , args_type ) do
160+ capture_expr ( meta , expr , s , e , [ ] , args_type )
158161 end
159162
160- defp capture_expr ( meta , expr , s , e , escaped , sequential ) do
163+ defp capture_expr ( meta , expr , s , e , escaped , args_type ) do
161164 case escape ( expr , escaped ) do
162- { e_expr , [ ] } when not sequential ->
165+ { e_expr , [ ] } when args_type == :non_sequential ->
163166 # elixir raises here invalid_args_for_capture
164167 # we emit fn without args
165168 fn_expr = { :fn , meta , [ { :-> , meta , [ [ ] , e_expr ] } ] }
166169 { :expand , fn_expr , s , e }
167170
171+ # elixir will remove this clause once complex module captures raise
168172 { { { :. , _ , [ _ , _ ] } = dot , _ , args } , [ ] } ->
169173 meta = Keyword . delete ( meta , :no_parens )
170174 fn_expr = { :fn , meta , [ { :-> , meta , [ [ ] , { dot , meta , args } ] } ] }
@@ -244,10 +248,10 @@ defmodule ElixirSense.Core.Compiler.Fn do
244248 [ ]
245249 end
246250
247- defp is_sequential_and_not_empty ( [ ] ) , do: false
248- defp is_sequential_and_not_empty ( list ) , do: is_sequential ( list , 1 )
251+ defp check_sequential_and_not_empty ( [ ] ) , do: :non_sequential
252+ defp check_sequential_and_not_empty ( list ) , do: check_sequential ( list , 1 )
249253
250- defp is_sequential ( [ { :& , _ , [ int ] } | t ] , int ) , do: is_sequential ( t , int + 1 )
251- defp is_sequential ( [ ] , _int ) , do: true
252- defp is_sequential ( _ , _int ) , do: false
254+ defp check_sequential ( [ { :& , _ , [ int ] } | t ] , int ) , do: check_sequential ( t , int + 1 )
255+ defp check_sequential ( [ ] , _int ) , do: :sequential
256+ defp check_sequential ( _ , _int ) , do: :non_sequential
253257end
0 commit comments