Skip to content

Commit 9ee79a1

Browse files
author
José Valim
committed
Deprecate Macro.extract_args/1
1 parent bbc0fe0 commit 9ee79a1

File tree

8 files changed

+49
-84
lines changed

8 files changed

+49
-84
lines changed

lib/elixir/lib/behaviour.ex

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,19 +66,19 @@ defmodule Behaviour do
6666
end
6767

6868
defp do_defcallback(fun, spec, caller) do
69-
case Macro.extract_args(fun) do
69+
case Macro.decompose_call(fun) do
7070
{ name, args } ->
7171
do_callback(:def, name, args, name, length(args), spec, caller)
72-
:error ->
72+
_ ->
7373
raise ArgumentError, message: "invalid syntax in defcallback #{Macro.to_string(fun)}"
7474
end
7575
end
7676

7777
defp do_defmacrocallback(fun, spec, caller) do
78-
case Macro.extract_args(fun) do
78+
case Macro.decompose_call(fun) do
7979
{ name, args } ->
8080
do_callback(:defmacro, :"MACRO-#{name}", [quote(do: env :: Macro.Env.t)|args], name, length(args), spec, caller)
81-
:error ->
81+
_ ->
8282
raise ArgumentError, message: "invalid syntax in defmacrocallback #{Macro.to_string(fun)}"
8383
end
8484
end

lib/elixir/lib/kernel.ex

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3518,9 +3518,9 @@ defmodule Kernel do
35183518
append_first = Keyword.get(opts, :append_first, false)
35193519

35203520
lc fun inlist List.wrap(funs) do
3521-
case Macro.extract_args(fun) do
3521+
case Macro.decompose_call(fun) do
35223522
{ name, args } -> :ok
3523-
:error -> raise ArgumentError, message: "invalid syntax in defdelegate #{Macro.to_string(fun)}"
3523+
_ -> raise ArgumentError, message: "invalid syntax in defdelegate #{Macro.to_string(fun)}"
35243524
end
35253525

35263526
actual_args =

lib/elixir/lib/kernel/special_forms.ex

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ defmodule Kernel.SpecialForms do
3434
{ :{}, [], [1,2,3] }
3535
3636
"""
37-
defmacro :{}.(args)
37+
defmacro unquote(:{})(args)
3838

3939
@doc """
4040
Defines a new bitstring.
@@ -171,7 +171,7 @@ defmodule Kernel.SpecialForms do
171171
For floats, unit * size must result in 32 or 64, corresponding
172172
to binary32 and binary64, respectively.
173173
"""
174-
defmacro :<<>>.(args)
174+
defmacro unquote(:<<>>)(args)
175175

176176
@doc """
177177
Defines a remote call or an alias.
@@ -284,7 +284,7 @@ defmodule Kernel.SpecialForms do
284284
[{:__aliases__, [alias: false], [:String]}, Sample]}
285285
286286
"""
287-
defmacro (:.).(left, right)
287+
defmacro unquote(:.)(left, right)
288288

289289
@doc """
290290
`alias` is used to setup aliases, often useful with modules names.
@@ -943,8 +943,7 @@ defmodule Kernel.SpecialForms do
943943
#=> { :sum, [], [1, 13, 3] }
944944
945945
"""
946-
name = :unquote
947-
defmacro unquote(name)(expr)
946+
defmacro unquote(:unquote)(expr)
948947

949948
@doc """
950949
Unquotes the given list expanding its arguments. Similar
@@ -957,8 +956,7 @@ defmodule Kernel.SpecialForms do
957956
#=> { :sum, [], [1, 2, 3, 4, 5] }
958957
959958
"""
960-
name = :unquote_splicing
961-
defmacro unquote(name)(expr)
959+
defmacro unquote(:unquote_splicing)(expr)
962960

963961
@doc """
964962
List comprehensions allow you to quickly build a list from another list:
@@ -1042,8 +1040,7 @@ defmodule Kernel.SpecialForms do
10421040
3
10431041
10441042
"""
1045-
name = :fn
1046-
defmacro unquote(name)(clauses)
1043+
defmacro unquote(:fn)(clauses)
10471044

10481045
@doc """
10491046
Internal special form for block expressions.
@@ -1133,8 +1130,7 @@ defmodule Kernel.SpecialForms do
11331130
&(foo(&1, &2); &3 + &4)
11341131
11351132
"""
1136-
name = :&
1137-
defmacro unquote(name)(expr)
1133+
defmacro unquote(:&)(expr)
11381134

11391135
@doc """
11401136
Internal special form to hold aliases information.

lib/elixir/lib/macro.ex

Lines changed: 28 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -81,52 +81,44 @@ defmodule Macro do
8181
message: "cannot pipe #{to_string expr} into #{to_string call_args}"
8282
end
8383

84-
@doc """
85-
Receives an expression representing a possible definition
86-
and extracts its arguments. It returns a tuple with the
87-
function name and the arguments list or `:error` if not
88-
a valid call syntax.
89-
90-
This is useful for macros that want to provide the same
91-
argument syntax available in def/defp/defmacro and friends.
92-
93-
## Examples
94-
95-
extract_args(quote do: foo) == { :foo, [] }
96-
extract_args(quote do: foo()) == { :foo, [] }
97-
extract_args(quote do: foo(1, 2, 3)) == { :foo, [1, 2, 3] }
98-
extract_args(quote do: 1.(1, 2, 3)) == :error
99-
100-
"""
101-
@spec extract_args(Macro.t) :: { atom, [Macro.t] } | :error
84+
@doc false
10285
def extract_args(expr) do
103-
:elixir_clauses.extract_args(expr)
86+
IO.write "Macro.extract_args/1 is deprecated, use Macro.decompose_call/1 instead\n#{Exception.format_stacktrace}"
87+
decompose_call(expr)
10488
end
10589

10690
@doc """
107-
Decomposes a local or remote call into its module alias (when a remote
108-
call is provided), function name and argument list.
109-
Returns :error when an invalid call syntax is provied.
91+
Decomposes a local or remote call into its remote part (when provided),
92+
function name and argument list.
93+
94+
Returns `:error` when an invalid call syntax is provided.
11095
11196
## Examples
11297
113-
decompose_call(quote do: foo) == { :foo, [] }
114-
decompose_call(quote do: foo()) == { :foo, [] }
115-
decompose_call(quote do: foo(1, 2, 3)) == { :foo, [1, 2, 3] }
116-
decompose_call(quote do: M.N.foo(1, 2, 3)) ==
117-
{ { :__aliases__, [alias: false], [:M, :N] }, :foo, [1, 2, 3] }
118-
decompose_call(quote do: 42) == :error
98+
iex> Macro.decompose_call(quote do: foo)
99+
{ :foo, [] }
100+
iex> Macro.decompose_call(quote do: foo())
101+
{ :foo, [] }
102+
iex> Macro.decompose_call(quote do: foo(1, 2, 3))
103+
{ :foo, [1, 2, 3] }
104+
iex> Macro.decompose_call(quote do: M.N.foo(1, 2, 3))
105+
{ { :__aliases__, [alias: false], [:M, :N] }, :foo, [1, 2, 3] }
106+
iex> Macro.decompose_call(quote do: 42)
107+
:error
119108
120109
"""
121110
@spec decompose_call(Macro.t) :: { atom, [Macro.t] } | { Macro.t, atom, [Macro.t] } | :error
122-
def decompose_call(expr) do
123-
case expr do
124-
{ { :., _, [{ :__aliases__, meta, atoms }, f] }, _, args } ->
125-
{ { :__aliases__, meta, atoms }, f, args }
126-
_local ->
127-
:elixir_clauses.extract_args(expr)
128-
end
129-
end
111+
def decompose_call({ { :., _, [remote, function] }, _, args }) when is_tuple(remote) or is_atom(remote),
112+
do: { remote, function, args }
113+
114+
def decompose_call({ name, _, args }) when is_atom(name) and is_atom(args),
115+
do: { name, [] }
116+
117+
def decompose_call({ name, _, args }) when is_atom(name) and is_list(args),
118+
do: { name, args }
119+
120+
def decompose_call(_),
121+
do: :error
130122

131123
@doc """
132124
Recursively escapes a value so it can be inserted

lib/elixir/src/elixir_clauses.erl

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
-module(elixir_clauses).
44
-export([
55
assigns/3, assigns_block/5, assigns_block/6, extract_splat_guards/1,
6-
get_pairs/4, get_pairs/5, match/3, extract_args/1, extract_guards/1]).
6+
get_pairs/4, get_pairs/5, match/3, extract_guards/1]).
77
-include("elixir.hrl").
88

99
%% Get pairs from a clause.
@@ -73,13 +73,6 @@ extract_guards(Else) -> { Else, [] }.
7373
extract_or_clauses({ 'when', _, [Left, Right] }) -> [Left|extract_or_clauses(Right)];
7474
extract_or_clauses(Term) -> [Term].
7575

76-
% Extract name and args from the given expression.
77-
78-
extract_args({ { '.', _, [Name] }, _, Args }) when is_atom(Name), is_list(Args) -> { Name, Args };
79-
extract_args({ Name, _, Args }) when is_atom(Name), is_atom(Args) -> { Name, [] };
80-
extract_args({ Name, _, Args }) when is_atom(Name), is_list(Args) -> { Name, Args };
81-
extract_args(_) -> error.
82-
8376
% Extract guards when multiple left side args are allowed.
8477

8578
extract_splat_guards([{ 'when', _, [_,_|_] = Args }]) ->

lib/elixir/src/elixir_def.erl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,12 @@ store_definition(Kind, CheckClauses, Call, Body, ExEnv) ->
5353
S = elixir_env:env_to_scope(Env),
5454
{ NameAndArgs, Guards } = elixir_clauses:extract_guards(Call),
5555

56-
{ Name, Args } = case elixir_clauses:extract_args(NameAndArgs) of
57-
error ->
56+
{ Name, Args } = case NameAndArgs of
57+
{ N, _, A } when is_atom(N), is_atom(A) -> { N, [] };
58+
{ N, _, A } when is_atom(N), is_list(A) -> { N, A };
59+
_ ->
5860
Format = [Kind, 'Elixir.Macro':to_string(NameAndArgs)],
59-
elixir_errors:syntax_error(Line, S#elixir_scope.file, "invalid syntax in ~ts ~ts", Format);
60-
Tuple ->
61-
Tuple
61+
elixir_errors:syntax_error(Line, S#elixir_scope.file, "invalid syntax in ~ts ~ts", Format)
6262
end,
6363

6464
%% Now that we have verified the call format,

lib/elixir/test/elixir/macro_test.exs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -396,25 +396,16 @@ defmodule MacroTest do
396396
assert Macro.safe_term(quote do: {1+1}) == { :unsafe, quote do: 1 + 1 }
397397
end
398398

399-
## extract_args
400-
401-
test :extract_args do
402-
assert Macro.extract_args(quote do: foo) == { :foo, [] }
403-
assert Macro.extract_args(quote do: foo()) == { :foo, [] }
404-
assert Macro.extract_args(quote do: :foo.()) == { :foo, [] }
405-
assert Macro.extract_args(quote do: foo(1, 2, 3)) == { :foo, [1, 2, 3] }
406-
assert Macro.extract_args(quote do: 1.(1, 2, 3)) == :error
407-
end
408-
409399
## decompose_call
410400

411401
test :decompose_call do
412402
assert Macro.decompose_call(quote do: foo) == { :foo, [] }
413403
assert Macro.decompose_call(quote do: foo()) == { :foo, [] }
414-
assert Macro.decompose_call(quote do: :foo.()) == { :foo, [] }
415404
assert Macro.decompose_call(quote do: foo(1, 2, 3)) == { :foo, [1, 2, 3] }
416405
assert Macro.decompose_call(quote do: M.N.foo(1, 2, 3)) ==
417406
{ { :__aliases__, [alias: false], [:M, :N] }, :foo, [1, 2, 3] }
407+
assert Macro.decompose_call(quote do: :foo.foo(1, 2, 3)) ==
408+
{ :foo, :foo, [1, 2, 3] }
418409
assert Macro.decompose_call(quote do: 1.(1, 2, 3)) == :error
419410
assert Macro.decompose_call(quote do: "some string") == :error
420411
end

lib/elixir/test/erlang/module_test.erl

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,6 @@ function_test() ->
2424
end,
2525
test_helper:run_and_remove(F, ['Elixir.Foo.Bar.Baz']).
2626

27-
dynamic_function_test() ->
28-
F = fun() ->
29-
eval("defmodule Foo.Bar.Baz do\ndef :sum.(a, b) do\na + b\nend\nend"),
30-
3 = 'Elixir.Foo.Bar.Baz':sum(1, 2)
31-
end,
32-
test_helper:run_and_remove(F, ['Elixir.Foo.Bar.Baz']).
33-
3427
quote_unquote_splicing_test() ->
3528
{ { '{}', [], [1,2,3,4,5] }, _ } = eval("x = [2,3,4]\nquote do: { 1, unquote_splicing(x), 5}").
3629

0 commit comments

Comments
 (0)