diff options
author | Hans Bolinder <[email protected]> | 2010-06-22 09:42:44 +0200 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2011-03-10 12:57:37 +0100 |
commit | 8052b98f596db048467c0c57cbaac1d3a27687ad (patch) | |
tree | 144fcf14894c8a5c7df3778d7b1d91fa6a72a1cb /lib/edoc/src/edoc_types.erl | |
parent | cc5885e81da81dc52bd7890ff3612a48d2f4a9f2 (diff) | |
download | otp-8052b98f596db048467c0c57cbaac1d3a27687ad.tar.gz otp-8052b98f596db048467c0c57cbaac1d3a27687ad.tar.bz2 otp-8052b98f596db048467c0c57cbaac1d3a27687ad.zip |
Make Erlang specifications and types available in EDoc
It is now possible to use Erlang specifications and types in EDoc
documentation. Erlang specifications and types will be used unless
there is also a function specification (@spec) or a type alias (@type)
with the same name. In the current implementation the placement of
-spec matters: it should be placed where the @spec would otherwise
have been placed.
Not all Erlang types are included in the documentation, but only those
exported by some export_type declaration or used by some documented
Erlang specification (-spec).
There is currently no support for overloaded Erlang specifications.
The syntax definitions of EDoc have been augmented to cope with most
of the Erlang types. (But we recommend that Erlang types should be
used instead.)
edoc:read_source() takes one new option, report_missing_types.
edoc_layout:module() takes one new option, pretty_printer.
Diffstat (limited to 'lib/edoc/src/edoc_types.erl')
-rw-r--r-- | lib/edoc/src/edoc_types.erl | 107 |
1 files changed, 82 insertions, 25 deletions
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl index b0255f793d..1ded63dffe 100644 --- a/lib/edoc/src/edoc_types.erl +++ b/lib/edoc/src/edoc_types.erl @@ -14,6 +14,8 @@ %% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 %% USA %% +%% $Id$ +%% %% @private %% @copyright 2001-2003 Richard Carlsson %% @author Richard Carlsson <[email protected]> @@ -25,8 +27,9 @@ -module(edoc_types). --export([is_predefined/1, to_ref/1, to_xml/2, to_label/1, arg_names/1, - set_arg_names/2, arg_descs/1, range_desc/1]). +-export([is_predefined/2, is_new_predefined/2, is_predefined_otp_type/2, + to_ref/1, to_xml/2, to_label/1, arg_names/1, set_arg_names/2, + arg_descs/1, range_desc/1]). %% @headerfile "edoc_types.hrl" @@ -34,27 +37,63 @@ -include("xmerl.hrl"). -is_predefined(any) -> true; -is_predefined(atom) -> true; -is_predefined(binary) -> true; -is_predefined(bool) -> true; -is_predefined(char) -> true; -is_predefined(cons) -> true; -is_predefined(deep_string) -> true; -is_predefined(float) -> true; -is_predefined(function) -> true; -is_predefined(integer) -> true; -is_predefined(list) -> true; -is_predefined(nil) -> true; -is_predefined(none) -> true; -is_predefined(number) -> true; -is_predefined(pid) -> true; -is_predefined(port) -> true; -is_predefined(reference) -> true; -is_predefined(string) -> true; -is_predefined(term) -> true; -is_predefined(tuple) -> true; -is_predefined(_) -> false. +is_predefined(any, 0) -> true; +is_predefined(atom, 0) -> true; +is_predefined(binary, 0) -> true; +is_predefined(bool, 0) -> true; +is_predefined(char, 0) -> true; +is_predefined(cons, 2) -> true; +is_predefined(deep_string, 0) -> true; +is_predefined(float, 0) -> true; +is_predefined(function, 0) -> true; +is_predefined(integer, 0) -> true; +is_predefined(list, 0) -> true; +is_predefined(list, 1) -> true; +is_predefined(nil, 0) -> true; +is_predefined(none, 0) -> true; +is_predefined(number, 0) -> true; +is_predefined(pid, 0) -> true; +is_predefined(port, 0) -> true; +is_predefined(reference, 0) -> true; +is_predefined(string, 0) -> true; +is_predefined(term, 0) -> true; +is_predefined(tuple, 0) -> true; +is_predefined(F, A) -> is_new_predefined(F, A). + +%% Should eventually be coalesced with is_predefined/2. +is_new_predefined(arity, 0) -> true; +is_new_predefined(bitstring, 0) -> true; +is_new_predefined(boolean, 0) -> true; +is_new_predefined(byte, 0) -> true; +is_new_predefined(iodata, 0) -> true; +is_new_predefined(iolist, 0) -> true; +is_new_predefined(maybe_improper_list, 0) -> true; +is_new_predefined(maybe_improper_list, 2) -> true; +is_new_predefined(mfa, 0) -> true; +is_new_predefined(module, 0) -> true; +is_new_predefined(neg_integer, 0) -> true; +is_new_predefined(node, 0) -> true; +is_new_predefined(non_neg_integer, 0) -> true; +is_new_predefined(nonempty_improper_list, 2) -> true; +is_new_predefined(nonempty_list, 0) -> true; +is_new_predefined(nonempty_list, 1) -> true; +is_new_predefined(nonempty_maybe_improper_list, 0) -> true; +is_new_predefined(nonempty_maybe_improper_list, 2) -> true; +is_new_predefined(nonempty_string, 0) -> true; +is_new_predefined(pos_integer, 0) -> true; +is_new_predefined(timeout, 0) -> true; +is_new_predefined(_, _) -> false. + +%% The following types will be removed later, but they are currently +%% kind of built-in. +is_predefined_otp_type(array, 0) -> true; +is_predefined_otp_type(dict, 0) -> true; +is_predefined_otp_type(digraph, 0) -> true; +is_predefined_otp_type(gb_set, 0) -> true; +is_predefined_otp_type(gb_tree, 0) -> true; +is_predefined_otp_type(queue, 0) -> true; +is_predefined_otp_type(set, 0) -> true; +is_predefined_otp_type(_, _) -> false. to_ref(#t_typedef{name = N}) -> to_ref(N); @@ -89,7 +128,9 @@ to_xml(#t_name{app = A, module = M, name = N}, _Env) -> to_xml(#t_type{name = N, args = As}, Env) -> Predef = case N of #t_name{module = [], name = T} -> - is_predefined(T); + NArgs = length(As), + (is_predefined(T, NArgs) + orelse is_predefined_otp_type(T, NArgs)); _ -> false end, @@ -107,14 +148,30 @@ to_xml(#t_list{type = T}, Env) -> {list, [wrap_utype(T, Env)]}; to_xml(#t_nil{}, _Env) -> nil; +to_xml(#t_paren{type = T}, Env) -> + {paren, [wrap_utype(T, Env)]}; +to_xml(#t_nonempty_list{type = T}, Env) -> + {nonempty_list, [wrap_utype(T, Env)]}; to_xml(#t_atom{val = V}, _Env) -> {atom, [{value, io_lib:write(V)}], []}; to_xml(#t_integer{val = V}, _Env) -> {integer, [{value, integer_to_list(V)}], []}; +to_xml(#t_integer_range{from = From, to = To}, _Env) -> + {range, [{value, integer_to_list(From)++".."++integer_to_list(To)}], []}; +to_xml(#t_binary{base_size = 0, unit_size = 0}, _Ens) -> + {binary, [{value, "<<>>"}], []}; +to_xml(#t_binary{base_size = B, unit_size = 0}, _Ens) -> + {binary, [{value, io_lib:fwrite("<<_:~w>>", [B])}], []}; +%to_xml(#t_binary{base_size = 0, unit_size = 8}, _Ens) -> +% {binary, [{value, "binary()"}], []}; +to_xml(#t_binary{base_size = 0, unit_size = U}, _Ens) -> + {binary, [{value, io_lib:fwrite("<<_:_*~w>>", [U])}], []}; +to_xml(#t_binary{base_size = B, unit_size = U}, _Ens) -> + {binary, [{value, io_lib:fwrite("<<_:~w, _:_*~w>>", [B, U])}], []}; to_xml(#t_float{val = V}, _Env) -> {float, [{value, io_lib:write(V)}], []}; to_xml(#t_union{types = Ts}, Env) -> - {union, map(fun wrap_type/2, Ts, Env)}; + {union, map(fun wrap_utype/2, Ts, Env)}; to_xml(#t_record{name = N = #t_atom{}, fields = Fs}, Env) -> {record, [to_xml(N, Env) | map(fun to_xml/2, Fs, Env)]}; to_xml(#t_field{name = N = #t_atom{}, type = T}, Env) -> |