defmodule Blunt.Command.EventDerivation do alias Blunt.Command.Events defmacro __using__(_opts) do quote do Module.register_attribute(__MODULE__, :events, accumulate: true) import Blunt.Command.EventDerivation, only: :macros @before_compile Blunt.Command.EventDerivation @after_compile Blunt.Command.EventDerivation end end defmacro derive_event(name, opts \\ []) defmacro derive_event(name, do: body) do body = Macro.escape(body, unquote: true) body = quote do: unquote(body) Events.record(name, do: body) end defmacro derive_event(name, opts), do: Events.record(name, opts) defmacro derive_event(name, opts, do: body) do body = Macro.escape(body, unquote: true) body = quote do: unquote(body) Events.record(name, Keyword.put(opts, :do, body)) end defmacro __before_compile__(_env) do quote do def __events__, do: @events proxies = Enum.map(@events, &Events.generate_proxy/1) Module.eval_quoted(__MODULE__, proxies) Module.delete_attribute(__MODULE__, :events) end end defmacro __after_compile__(env, _bytecode), do: Events.generate_events(env) end