Add tests for allow_locals option

This commit is contained in:
José Valim
2025-07-10 17:30:36 +02:00
parent 802ecdd4a0
commit a6844bf725
3 changed files with 24 additions and 7 deletions
+4 -4
View File
@@ -558,13 +558,13 @@ defmodule Macro.Env do
* `:allow_locals` - controls how local macros are resolved.
Defaults to `true`.
- When `false`, does not attempt to capture local macros defined in the
current module in `env`
- When `true`, uses a default resolver that looks for public macros in
the current module
- When a function, uses the function as a custom local resolver. The function
must have the signature: `(meta, name, arity, env) -> function() | false`
- When a function, it will be invoked to lazily compute a local function
(or return false). It has signature `(-> function() | false)`
* `:check_deprecations` - when set to `false`, does not check for deprecations
when expanding macros
@@ -591,7 +591,7 @@ defmodule Macro.Env do
# When allow_locals is a callback, we don't need to pass module macros as extra
# because the callback will handle local macro resolution
extra =
if is_function(allow_locals, 4) do
if is_function(allow_locals, 0) do
[]
else
case allow_locals and function_exported?(module, :__info__, 1) do
+1 -3
View File
@@ -175,9 +175,7 @@ expand_import(Meta, Name, Arity, E, Extra, AllowLocals, Trace) ->
Local = case AllowLocals of
false -> false;
true -> elixir_def:local_for(Meta, Name, Arity, [defmacro, defmacrop], E);
Fun when is_function(Fun, 4) ->
%% If we have a custom local resolver, use it.
Fun(Meta, Name, Arity, E)
Fun when is_function(Fun, 0) -> Fun()
end,
case Dispatch of
+19
View File
@@ -207,6 +207,25 @@ defmodule Macro.EnvTest do
assert fun.([generated: true], [quote(do: hello())]) == quote(generated: true, do: hello())
end
defmacro allow_locals_example, do: :ok
test "allow_locals" do
{:macro, Macro.EnvTest, fun} =
expand_import(env(), meta(), :allow_locals_example, 0)
assert fun.([], []) == :ok
assert expand_import(env(), meta(), :allow_locals_example, 0, allow_locals: false) ==
{:error, :not_found}
assert expand_import(env(), meta(), :allow_locals_example, 0,
allow_locals: fn -> send(self(), false) end
) ==
{:error, :not_found}
assert_received false
end
test "with tracing and deprecations" do
message = "MacroEnvMacros.my_deprecated_macro/1 is deprecated"