mirror of
https://github.com/ash-project/ash.git
synced 2024-09-20 13:33:20 +12:00
fix: add lexical scope to DSL for imports
This commit is contained in:
parent
fdc427f20f
commit
0e373f69a6
1 changed files with 79 additions and 74 deletions
|
@ -632,100 +632,105 @@ defmodule Ash.Dsl.Extension do
|
||||||
arg_values = unquote(args)
|
arg_values = unquote(args)
|
||||||
|
|
||||||
quote do
|
quote do
|
||||||
section_path = unquote(section_path)
|
# This `try do` block scopes the imports/unimports properly
|
||||||
entity_name = unquote(entity_name)
|
try do
|
||||||
extension = unquote(extension)
|
section_path = unquote(section_path)
|
||||||
|
entity_name = unquote(entity_name)
|
||||||
|
extension = unquote(extension)
|
||||||
|
|
||||||
current_sections = Process.get({__MODULE__, :ash_sections}, [])
|
current_sections = Process.get({__MODULE__, :ash_sections}, [])
|
||||||
|
|
||||||
Process.put(
|
Process.put(
|
||||||
{:builder_opts, unquote(nested_entity_path)},
|
{:builder_opts, unquote(nested_entity_path)},
|
||||||
Keyword.merge(
|
Keyword.merge(
|
||||||
unquote(Keyword.delete(opts, :do)),
|
unquote(Keyword.delete(opts, :do)),
|
||||||
Enum.zip(unquote(entity_args), unquote(arg_values))
|
Enum.zip(unquote(entity_args), unquote(arg_values))
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
import unquote(options_mod_name)
|
|
||||||
|
|
||||||
Ash.Dsl.Extension.import_mods(unquote(nested_entity_mods))
|
|
||||||
|
|
||||||
unquote(opts[:do])
|
|
||||||
|
|
||||||
current_config =
|
|
||||||
Process.get(
|
|
||||||
{__MODULE__, :ash, section_path ++ unquote(nested_entity_path)},
|
|
||||||
%{entities: [], opts: []}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
import unquote(options_mod_name), only: []
|
import unquote(options_mod_name)
|
||||||
|
|
||||||
Ash.Dsl.Extension.unimport_mods(unquote(nested_entity_mods))
|
Ash.Dsl.Extension.import_mods(unquote(nested_entity_mods))
|
||||||
|
|
||||||
opts = Process.delete({:builder_opts, unquote(nested_entity_path)})
|
unquote(opts[:do])
|
||||||
|
|
||||||
alias Ash.Dsl.Entity
|
current_config =
|
||||||
|
Process.get(
|
||||||
|
{__MODULE__, :ash, section_path ++ unquote(nested_entity_path)},
|
||||||
|
%{entities: [], opts: []}
|
||||||
|
)
|
||||||
|
|
||||||
nested_entities =
|
import unquote(options_mod_name), only: []
|
||||||
unquote(Macro.escape(entity.entities))
|
|
||||||
|> Enum.map(&elem(&1, 0))
|
|
||||||
|> Enum.uniq()
|
|
||||||
|> Enum.reduce(%{}, fn key, acc ->
|
|
||||||
nested_path = section_path ++ unquote(nested_entity_path) ++ [key]
|
|
||||||
|
|
||||||
entities =
|
Ash.Dsl.Extension.unimport_mods(unquote(nested_entity_mods))
|
||||||
{__MODULE__, :ash, nested_path}
|
|
||||||
|> Process.get(%{entities: []})
|
|
||||||
|> Map.get(:entities, [])
|
|
||||||
|> Enum.reverse()
|
|
||||||
|
|
||||||
Map.update(acc, key, entities, fn current_nested_entities ->
|
opts = Process.delete({:builder_opts, unquote(nested_entity_path)})
|
||||||
(current_nested_entities || []) ++ entities
|
|
||||||
|
alias Ash.Dsl.Entity
|
||||||
|
|
||||||
|
nested_entities =
|
||||||
|
unquote(Macro.escape(entity.entities))
|
||||||
|
|> Enum.map(&elem(&1, 0))
|
||||||
|
|> Enum.uniq()
|
||||||
|
|> Enum.reduce(%{}, fn key, acc ->
|
||||||
|
nested_path = section_path ++ unquote(nested_entity_path) ++ [key]
|
||||||
|
|
||||||
|
entities =
|
||||||
|
{__MODULE__, :ash, nested_path}
|
||||||
|
|> Process.get(%{entities: []})
|
||||||
|
|> Map.get(:entities, [])
|
||||||
|
|> Enum.reverse()
|
||||||
|
|
||||||
|
Map.update(acc, key, entities, fn current_nested_entities ->
|
||||||
|
(current_nested_entities || []) ++ entities
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
|
||||||
|
|
||||||
built =
|
built =
|
||||||
case Entity.build(unquote(Macro.escape(entity)), opts, nested_entities) do
|
case Entity.build(unquote(Macro.escape(entity)), opts, nested_entities) do
|
||||||
{:ok, built} ->
|
{:ok, built} ->
|
||||||
built
|
built
|
||||||
|
|
||||||
{:error, error} ->
|
{:error, error} ->
|
||||||
additional_path =
|
additional_path =
|
||||||
if opts[:name] do
|
if opts[:name] do
|
||||||
[unquote(entity.name), opts[:name]]
|
[unquote(entity.name), opts[:name]]
|
||||||
else
|
else
|
||||||
[unquote(entity.name)]
|
[unquote(entity.name)]
|
||||||
end
|
end
|
||||||
|
|
||||||
message =
|
message =
|
||||||
cond do
|
cond do
|
||||||
Exception.exception?(error) ->
|
Exception.exception?(error) ->
|
||||||
Exception.message(error)
|
Exception.message(error)
|
||||||
|
|
||||||
is_binary(error) ->
|
is_binary(error) ->
|
||||||
error
|
error
|
||||||
|
|
||||||
true ->
|
true ->
|
||||||
inspect(error)
|
inspect(error)
|
||||||
end
|
end
|
||||||
|
|
||||||
raise Ash.Error.Dsl.DslError,
|
raise Ash.Error.Dsl.DslError,
|
||||||
message: message,
|
message: message,
|
||||||
path: section_path ++ additional_path
|
path: section_path ++ additional_path
|
||||||
|
end
|
||||||
|
|
||||||
|
new_config = %{current_config | entities: current_config.entities ++ [built]}
|
||||||
|
|
||||||
|
unless {extension, section_path} in current_sections do
|
||||||
|
Process.put({__MODULE__, :ash_sections}, [
|
||||||
|
{extension, section_path} | current_sections
|
||||||
|
])
|
||||||
end
|
end
|
||||||
|
|
||||||
new_config = %{current_config | entities: current_config.entities ++ [built]}
|
Process.put(
|
||||||
|
{__MODULE__, :ash, section_path ++ unquote(nested_entity_path)},
|
||||||
unless {extension, section_path} in current_sections do
|
new_config
|
||||||
Process.put({__MODULE__, :ash_sections}, [
|
)
|
||||||
{extension, section_path} | current_sections
|
rescue
|
||||||
])
|
e -> reraise e, __STACKTRACE__
|
||||||
end
|
end
|
||||||
|
|
||||||
Process.put(
|
|
||||||
{__MODULE__, :ash, section_path ++ unquote(nested_entity_path)},
|
|
||||||
new_config
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end,
|
end,
|
||||||
|
|
Loading…
Reference in a new issue