Skip to content

Commit f9c418d

Browse files
committed
remove extra
use one param
1 parent 884e989 commit f9c418d

File tree

2 files changed

+75
-34
lines changed

2 files changed

+75
-34
lines changed

lib/elixir/lib/macro/env.ex

Lines changed: 67 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,10 +96,9 @@ defmodule Macro.Env do
9696
]
9797

9898
@type expand_import_opts :: [
99-
allow_locals: boolean(),
99+
allow_locals: boolean() | (Macro.metadata(), atom(), arity(), [atom()], t() -> any()),
100100
check_deprecations: boolean(),
101-
trace: boolean(),
102-
local_for_callback: (Macro.metadata(), atom(), arity(), [atom()], t() -> any())
101+
trace: boolean()
103102
]
104103

105104
@type expand_require_opts :: [
@@ -557,17 +556,15 @@ defmodule Macro.Env do
557556
## Options
558557
559558
* `:allow_locals` - when set to `false`, it does not attempt to capture
560-
local macros defined in the current module in `env`
559+
local macros defined in the current module in `env`.
560+
When set to `true`, it uses a default resolver that looks for public macros.
561+
When set to a function, it uses the function as a local resolver.
562+
The function must have the following signature:
563+
`fn meta, name, arity, kinds, env -> function() | false`.
561564
562565
* `:check_deprecations` - when set to `false`, does not check for deprecations
563566
when expanding macros
564567
565-
* `:local_for_callback` - a function that receives the metadata, name, arity,
566-
kinds list, and environment, and returns the local macro expansion or `false`.
567-
The expansion can be a function or any other value. Non-function values will
568-
cause the macro expansion to be skipped and return `:ok`.
569-
Defaults to calling `:elixir_def.local_for/5`
570-
571568
* #{trace_option}
572569
573570
"""
@@ -578,36 +575,80 @@ defmodule Macro.Env do
578575
| {:error, :not_found | {:conflict, module()} | {:ambiguous, [module()]}}
579576
def expand_import(env, meta, name, arity, opts \\ [])
580577
when is_list(meta) and is_atom(name) and is_integer(arity) and is_list(opts) do
581-
local_for_callback = Keyword.get(opts, :local_for_callback)
582-
583578
case :elixir_import.special_form(name, arity) do
584579
true ->
585580
{:error, :not_found}
586581

587582
false ->
588-
allow_locals = Keyword.get(opts, :allow_locals, true)
589-
trace = Keyword.get(opts, :trace, true)
590583
module = env.module
591584

592-
# When local_for_callback is provided, we don't need to pass module macros as extra
593-
# because the callback will handle local macro resolution
594-
extra =
595-
if local_for_callback do
596-
[]
597-
else
598-
case allow_locals and function_exported?(module, :__info__, 1) do
599-
true -> [{module, module.__info__(:macros)}]
600-
false -> []
601-
end
585+
allow_locals =
586+
case Keyword.get(opts, :allow_locals, true) do
587+
false ->
588+
false
589+
590+
true ->
591+
macros =
592+
if function_exported?(module, :__info__, 1) do
593+
module.__info__(:macros)
594+
else
595+
[]
596+
end
597+
598+
fn _meta, name, arity, kinds, _e ->
599+
IO.puts(
600+
"Resolving local macro #{name}/#{arity} in #{module} with kinds: #{inspect(kinds)}"
601+
)
602+
603+
IO.puts("Macros defined in #{module}: #{inspect(macros)}")
604+
605+
# by default use a resolver looking for public macros
606+
cond do
607+
:lists.any(
608+
fn
609+
:defmacro -> true
610+
:defmacrop -> true
611+
_ -> false
612+
end,
613+
kinds
614+
) and macro_exported?(module, name, arity) ->
615+
# public macro found - return the expander
616+
proper_name = :"MACRO-#{name}"
617+
proper_arity = arity + 1
618+
Function.capture(module, proper_name, proper_arity)
619+
620+
:lists.any(
621+
fn
622+
:def -> true
623+
:defp -> true
624+
_ -> false
625+
end,
626+
kinds
627+
) and function_exported?(module, name, arity) ->
628+
Function.capture(module, name, arity)
629+
630+
true ->
631+
IO.puts(
632+
"No local macro found for #{name}/#{arity} in #{module} with kinds: #{inspect(kinds)}"
633+
)
634+
635+
false
636+
end
637+
end
638+
639+
fun when is_function(fun, 5) ->
640+
# If we have a custom local resolver, use it.
641+
fun
602642
end
603643

644+
trace = Keyword.get(opts, :trace, true)
645+
604646
case :elixir_dispatch.expand_import(
605647
meta,
606648
name,
607649
arity,
608650
env,
609-
extra,
610-
local_for_callback || allow_locals,
651+
allow_locals,
611652
trace
612653
) do
613654
{:macro, receiver, expander} ->

lib/elixir/src/elixir_dispatch.erl

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
-module(elixir_dispatch).
99
-export([dispatch_import/6, dispatch_require/7,
1010
require_function/5, import_function/4,
11-
expand_import/7, expand_require/6, check_deprecated/6,
11+
expand_import/6, expand_require/6, check_deprecated/6,
1212
default_functions/0, default_macros/0, default_requires/0,
1313
find_import/4, find_imports/3, format_error/1]).
1414
-include("elixir.hrl").
@@ -29,7 +29,7 @@ default_requires() ->
2929
find_import(Meta, Name, Arity, E) ->
3030
Tuple = {Name, Arity},
3131

32-
case find_import_by_name_arity(Meta, Tuple, [], E) of
32+
case find_import_by_name_arity(Meta, Tuple, E) of
3333
{function, Receiver} ->
3434
elixir_env:trace({imported_function, Meta, Receiver, Name, Arity}, E),
3535
Receiver;
@@ -56,7 +56,7 @@ find_imports(Meta, Name, E) ->
5656

5757
import_function(Meta, Name, Arity, E) ->
5858
Tuple = {Name, Arity},
59-
case find_import_by_name_arity(Meta, Tuple, [], E) of
59+
case find_import_by_name_arity(Meta, Tuple, E) of
6060
{function, Receiver} ->
6161
elixir_env:trace({imported_function, Meta, Receiver, Name, Arity}, E),
6262
elixir_import:record(Tuple, Receiver, ?key(E, module), ?key(E, function)),
@@ -115,7 +115,7 @@ dispatch_import(Meta, Name, Args, S, E, Callback) ->
115115
_ -> false
116116
end,
117117

118-
case expand_import(Meta, Name, Arity, E, [], AllowLocals, true) of
118+
case expand_import(Meta, Name, Arity, E, AllowLocals, true) of
119119
{macro, Receiver, Expander} ->
120120
check_deprecated(macro, Meta, Receiver, Name, Arity, E),
121121
Caller = {?line(Meta), S, E},
@@ -159,10 +159,10 @@ dispatch_require(_Meta, Receiver, Name, _Args, _S, _E, Callback) ->
159159

160160
%% Macros expansion
161161

162-
expand_import(Meta, Name, Arity, E, Extra, AllowLocals, Trace) ->
162+
expand_import(Meta, Name, Arity, E, AllowLocals, Trace) ->
163163
Tuple = {Name, Arity},
164164
Module = ?key(E, module),
165-
Dispatch = find_import_by_name_arity(Meta, Tuple, Extra, E),
165+
Dispatch = find_import_by_name_arity(Meta, Tuple, E),
166166

167167
case Dispatch of
168168
{ambiguous, Ambiguous} ->
@@ -303,13 +303,13 @@ find_imports_by_name(Name, [{ImportName, _} | Imports], Acc, Mod, Meta, E) when
303303
find_imports_by_name(_Name, _Imports, Acc, _Mod, _Meta, _E) ->
304304
Acc.
305305

306-
find_import_by_name_arity(Meta, {_Name, Arity} = Tuple, Extra, E) ->
306+
find_import_by_name_arity(Meta, {_Name, Arity} = Tuple, E) ->
307307
case is_import(Meta, Arity) of
308308
{import, _} = Import ->
309309
Import;
310310
false ->
311311
Funs = ?key(E, functions),
312-
Macs = Extra ++ ?key(E, macros),
312+
Macs = ?key(E, macros),
313313
FunMatch = find_import_by_name_arity(Tuple, Funs),
314314
MacMatch = find_import_by_name_arity(Tuple, Macs),
315315

0 commit comments

Comments
 (0)