/home/runner/work/klsn/klsn/_build/test/cover/ct/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
:-(
Forms = abstract_code(Module),
13
:-(
Types = [ {TName, TExpr, Vars}
14
:-(
|| {attribute, _, type, {TName, TExpr, Vars}} <- Forms,
15
:-(
TName == Name,
16
:-(
length(Vars) =:= Arity ],
17
:-(
case Types of
18
:-(
[] -> erlang:error(undefined_type, [{Module, Name, Arity}]);
19
:-(
[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
:-(
Forms = abstract_code(Module),
26
:-(
SpecsList = [ Specs
27
:-(
|| {attribute, _, spec, {{FName, FArity}, Specs}} <- Forms,
28
:-(
FName == Name,
29
:-(
FArity =:= Arity ],
30
:-(
case SpecsList of
31
:-(
[] -> erlang:error(undefined_spec, [{Module, Name, Arity}]);
32
:-(
[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
:-(
Forms = abstract_code(Module),
39
:-(
ClausesList = [ Clauses
40
:-(
|| {function, _, FName, FArity, Clauses} <- Forms,
41
:-(
FName == Name,
42
:-(
FArity =:= Arity ],
43
:-(
case ClausesList of
44
:-(
[] -> erlang:error(undefined_function, [{Module, Name, Arity}]);
45
:-(
[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
:-(
case code:get_object_code(Module) of
52 {_, Bin, _} ->
53
:-(
case beam_lib:chunks(Bin, [abstract_code]) of
54 {ok, {_, [{abstract_code, Data}]}} ->
55
:-(
case Data of
56 {raw_abstract_v1, Forms} when is_list(Forms) ->
57
:-(
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
:-(
erlang:error(no_abstract_code, [Module])
68 end.
69
Line Hits Source