/home/runner/work/klsn/klsn/_build/test/cover/aggregate/klsn_code.html

1 -module(klsn_code).
2
3 -export([
4 type/1
5 , spec/1
6 , function/1
7 ]).
8
9 %% Retrieve the type definition for a given type name and arity.
10 -spec type({module(), atom(), non_neg_integer()}) -> {atom(), term(), [term()]}.
11 type({Module, Name, Arity}) when is_atom(Module), is_atom(Name), is_integer(Arity) ->
12 5 Forms = abstract_code(Module),
13 4 Types = [ {TName, TExpr, Vars}
14 4 || {attribute, _, type, {TName, TExpr, Vars}} <- Forms,
15 12 TName == Name,
16 12 length(Vars) =:= Arity ],
17 4 case Types of
18 1 [] -> erlang:error(undefined_type, [{Module, Name, Arity}]);
19 3 [Result|_] -> Result
20 end.
21
22 %% Retrieve the spec (type signatures) for a given function name and arity.
23 -spec spec({module(), atom(), non_neg_integer()}) -> [term()].
24 spec({Module, Name, Arity}) when is_atom(Module), is_atom(Name), is_integer(Arity) ->
25 3 Forms = abstract_code(Module),
26 3 SpecsList = [ Specs
27 3 || {attribute, _, spec, {{FName, FArity}, Specs}} <- Forms,
28 6 FName == Name,
29 6 FArity =:= Arity ],
30 3 case SpecsList of
31 1 [] -> erlang:error(undefined_spec, [{Module, Name, Arity}]);
32 2 [Specs|_] -> Specs
33 end.
34
35 %% Retrieve the clauses (implementations) for a given function name and arity.
36 -spec function({module(), atom(), non_neg_integer()}) -> [term()].
37 function({Module, Name, Arity}) when is_atom(Module), is_atom(Name), is_integer(Arity) ->
38 3 Forms = abstract_code(Module),
39 3 ClausesList = [ Clauses
40 3 || {function, _, FName, FArity, Clauses} <- Forms,
41 18 FName == Name,
42 6 FArity =:= Arity ],
43 3 case ClausesList of
44 1 [] -> erlang:error(undefined_function, [{Module, Name, Arity}]);
45 2 [Clauses|_] -> Clauses
46 end.
47
48 %% Internal: load and return the raw abstract code forms for a module.
49 -spec abstract_code(module()) -> [term()].
50 abstract_code(Module) when is_atom(Module) ->
51 11 case code:get_object_code(Module) of
52 {_, Bin, _} ->
53 10 case beam_lib:chunks(Bin, [abstract_code]) of
54 {ok, {_, [{abstract_code, Data}]}} ->
55 10 case Data of
56 {raw_abstract_v1, Forms} when is_list(Forms) ->
57 10 Forms;
58 Forms when is_list(Forms) ->
59
:-(
Forms;
60 _ ->
61
:-(
erlang:error(no_abstract_code, [Module])
62 end;
63 _ ->
64
:-(
erlang:error(no_abstract_code, [Module])
65 end;
66 _ ->
67 1 erlang:error(no_abstract_code, [Module])
68 end.
69
Line Hits Source