Skip to content

Commit 81bbcca

Browse files
committed
port upstream changes
1 parent ef364ac commit 81bbcca

File tree

1 file changed

+29
-25
lines changed
  • lib/elixir_sense/core/compiler

1 file changed

+29
-25
lines changed

lib/elixir_sense/core/compiler/fn.ex

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -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
253257
end

0 commit comments

Comments
 (0)