-
Notifications
You must be signed in to change notification settings - Fork 11
/
gen.ex
67 lines (65 loc) · 2.58 KB
/
gen.ex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
defmodule GenX.Gen do
def defhandler(callback, send, f, options) do
defhandler(callback, send, f, options, [])
end
def defhandler(callback, send, {function, meta, nil}, options, extras) do
defhandler(callback, send, {function, meta, []}, options, extras)
end
def defhandler(callback, {m,f}, {function, _meta, arguments} = name, options, extras) do
if is_atom(arguments), do: arguments = []
state = options[:state] || (quote do: _)
{export_option, no_export} = case options[:export] do
nil -> {[], false}
false -> {[],true}
keyword when is_list(keyword) -> {keyword, false}
value -> {[server: value], false}
end
export = Keyword.merge [server: :server, name: name], export_option
{function_name, _, _} = export[:name]
export = Keyword.put export, :name, function_name
request =
case arguments do
[] -> function
_ -> (quote do: {unquote_splicing([function|arguments])})
end
arguments_stub =
lc argn inlist :lists.seq(1, length(arguments)) do
quote do: var!(unquote(binary_to_atom("arg_#{argn}")), __MODULE__)
end
full_arguments =
case export[:server] do
:server -> [(quote do: server)]
_ -> []
end ++ arguments_stub
arity = length(full_arguments)
message_request =
case arguments_stub do
[] -> function
_ -> (quote do: {unquote_splicing([function|arguments_stub])})
end
server =
case export[:server] do
:server -> (quote do: server)
val -> val
end
extra_handle_arguments = lc e inlist (extras[:handle] || []), do: options[e] || (quote do: _)
before_request_send_arguments = extras[:before_request] || []
extra_send_arguments = extras[:send] || []
args = Enum.concat [server|before_request_send_arguments],
[message_request|extra_send_arguments]
quote do
def unquote(callback)(unquote(request),
unquote_splicing(extra_handle_arguments),
unquote(state)), do: unquote(options[:do])
unless Module.defines?(__MODULE__,
{unquote(export[:name]),
unquote(arity)}) or
unquote(no_export) do
def unquote(export[:name])(unquote_splicing(full_arguments)) do
unquote(m).unquote(f)(unquote_splicing(args))
end
defoverridable [{unquote(export[:name]), unquote(arity)}]
end
end
end
end