Skip to content

Commit fd96bab

Browse files
committed
Add and use Macro.escape(ast, generated: true)
1 parent 71f7426 commit fd96bab

File tree

3 files changed

+22
-7
lines changed

3 files changed

+22
-7
lines changed

lib/elixir/lib/kernel.ex

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3858,17 +3858,14 @@ defmodule Kernel do
38583858

38593859
defp do_at_escape(name, value) do
38603860
try do
3861-
:elixir_quote.escape(value, :none, false)
3861+
# mark module attrs as shallow-generated since the ast for their representation
3862+
# might contain opaque terms
3863+
Macro.escape(value, generated: true)
38623864
rescue
38633865
ex in [ArgumentError] ->
38643866
raise ArgumentError,
38653867
"cannot inject attribute @#{name} into function/macro because " <>
38663868
Exception.message(ex)
3867-
else
3868-
# mark module attrs as shallow-generated since the ast for their representation
3869-
# might contain opaque terms
3870-
{caller, meta, args} when is_list(meta) -> {caller, [generated: true] ++ meta, args}
3871-
ast -> ast
38723869
end
38733870
end
38743871

lib/elixir/lib/macro.ex

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -808,6 +808,10 @@ defmodule Macro do
808808
nodes. Note this option changes the semantics of escaped code and
809809
it should only be used when escaping ASTs. Defaults to `false`.
810810
811+
* `:generated` - (since v1.19.0) Whether the AST should be considered as generated
812+
by the compiler or not. This means the compiler and tools like Dialyzer may not
813+
emit certain warnings.
814+
811815
As an example for `:prune_metadata`, `ExUnit` stores the AST of every
812816
assertion, so when an assertion fails we can show code snippets to users.
813817
Without this option, each time the test module is compiled, we would get a
@@ -908,7 +912,17 @@ defmodule Macro do
908912
def escape(expr, opts \\ []) do
909913
unquote = Keyword.get(opts, :unquote, false)
910914
kind = if Keyword.get(opts, :prune_metadata, false), do: :prune_metadata, else: :none
911-
:elixir_quote.escape(expr, kind, unquote)
915+
generated = Keyword.get(opts, :generated, false)
916+
917+
case :elixir_quote.escape(expr, kind, unquote) do
918+
# mark module attrs as shallow-generated since the ast for their representation
919+
# might contain opaque terms
920+
{caller, meta, args} when generated and is_list(meta) ->
921+
{caller, [generated: true] ++ meta, args}
922+
923+
ast ->
924+
ast
925+
end
912926
end
913927

914928
# TODO: Deprecate me on Elixir v1.22

lib/elixir/test/elixir/macro_test.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,10 @@ defmodule MacroTest do
8484
assert Macro.escape(contents, unquote: true) == {:x, [], MacroTest}
8585
end
8686

87+
test "with generated" do
88+
assert Macro.escape(%{a: {}}, generated: true) == {:%{}, [generated: true], [{:{}, [], []}]}
89+
end
90+
8791
defp eval_escaped(contents) do
8892
{eval, []} = Code.eval_quoted(Macro.escape(contents, unquote: true))
8993
eval

0 commit comments

Comments
 (0)