aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Bolinder <hasse@erlang.org>2011-05-18 08:30:54 +0200
committerHans Bolinder <hasse@erlang.org>2011-05-18 08:30:54 +0200
commit4ed30063f15b4b80f5f23b00f55a49ed3496fe9e (patch)
tree7bd83adbc7859ef177d4a09d7cb0fa09e65e060a
parent69f7630157b16eda1639323e6bbc269096255006 (diff)
parent766e09ac2d1abfa65f65377945ce8f06905e786e (diff)
downloadotp-4ed30063f15b4b80f5f23b00f55a49ed3496fe9e.tar.gz
otp-4ed30063f15b4b80f5f23b00f55a49ed3496fe9e.tar.bz2
otp-4ed30063f15b4b80f5f23b00f55a49ed3496fe9e.zip
Merge branch 'hb/edoc/bugfixes/OTP-9301' into dev
* hb/edoc/bugfixes/OTP-9301: Fix bugs concerning the option report_missing_types
-rw-r--r--lib/edoc/src/edoc.hrl2
-rw-r--r--lib/edoc/src/edoc_specs.erl6
-rw-r--r--lib/edoc/src/edoc_tags.erl116
3 files changed, 66 insertions, 58 deletions
diff --git a/lib/edoc/src/edoc.hrl b/lib/edoc/src/edoc.hrl
index 43657b3b8f..31cf45ade9 100644
--- a/lib/edoc/src/edoc.hrl
+++ b/lib/edoc/src/edoc.hrl
@@ -37,7 +37,7 @@
-define(SOURCE_DIR, "src").
-define(EBIN_DIR, "ebin").
-define(EDOC_DIR, "doc").
--define(REPORT_MISSING_TYPE, false).
+-define(REPORT_MISSING_TYPES, false).
-include("edoc_doclet.hrl").
diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl
index 45016ef85a..519ade726f 100644
--- a/lib/edoc/src/edoc_specs.erl
+++ b/lib/edoc/src/edoc_specs.erl
@@ -1,4 +1,4 @@
-%
+%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
@@ -428,8 +428,8 @@ get_typevars(Ts) ->
expand_records(Entries, TypeDefs, DT, Opts, File, Module) ->
TypeList = [{type_name(T), T, not_seen} || T <- TypeDefs],
true = ets:insert(DT, TypeList),
- Warn = proplists:get_value(report_missing_type, Opts,
- ?REPORT_MISSING_TYPE) =:= true,
+ Warn = proplists:get_value(report_missing_types, Opts,
+ ?REPORT_MISSING_TYPES) =:= true,
P = #parms{tab = DT, warn = Warn, file = File, line = 0},
ExportedTypes = [Name ||
{export_type,Ts} <- Module#module.attributes,
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index def39ee34c..8ee8f87b5f 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -331,8 +331,8 @@ parse_typedef(Data, Line, _Env, Where) ->
NAs = length(As),
case edoc_types:is_predefined(T, NAs) of
true ->
- case
- edoc_types:is_new_predefined(T, NAs)
+ case
+ edoc_types:is_new_predefined(T, NAs)
orelse edoc_types:is_predefined_otp_type(T, NAs)
of
false ->
@@ -406,17 +406,20 @@ throw_error(L, D) ->
-record(parms, {tab, warn, file, line}).
-check_types(Entries0, Opts, File) ->
- Entries = edoc_data:hidden_filter(Entries0, Opts),
+check_types(Entries, Opts, File) ->
Tags = edoc_data:get_all_tags(Entries),
+ TypeTags = [Tag || #tag{data = {#t_typedef{},_}}=Tag <- Tags],
+ Entries2 = edoc_data:hidden_filter(Entries, Opts),
+ Tags2 = edoc_data:get_all_tags(Entries2),
+ SpecTags = [Tag || #tag{data = #t_spec{}}=Tag <- Tags2],
DT = ets:new(types, [bag]),
_ = [add_type(DT, Name, As, File, Line) ||
#tag{line = Line,
- data = {#t_typedef{name = Name, args = As},_}} <- Tags],
- Warn = proplists:get_value(report_missing_type, Opts,
- ?REPORT_MISSING_TYPE) =:= true,
+ data = {#t_typedef{name = Name, args = As},_}} <- TypeTags],
+ Warn = proplists:get_value(report_missing_types, Opts,
+ ?REPORT_MISSING_TYPES) =:= true,
P = #parms{tab = DT, warn = Warn, file = File, line = 0},
- try check_types(Tags, P)
+ try check_types3(TypeTags++SpecTags, P, [])
after true = ets:delete(DT)
end.
@@ -431,60 +434,64 @@ add_type(DT, Name, Args, File, Line) ->
ets:insert(DT, {Name, NArgs})
end.
-check_types([], _P)->
+check_types3([], _P, _Ls)->
ok;
-check_types([Tag | Tags], P) ->
- check_type(Tag, P, Tags).
+check_types3([Tag | Tags], P, Ls) ->
+ check_type(Tag, P, Ls, Tags).
-check_type(#tag{line = L, data = Data}, P0, Ts) ->
+check_type(#tag{line = L, data = Data}, P0, Ls, Ts) ->
P = P0#parms{line = L},
case Data of
{#t_typedef{type = Type, defs = Defs},_} ->
- check_type(Type, P, Defs++Ts);
+ check_type(Type, P, Ls, Defs++Ts);
#t_spec{type = Type, defs = Defs} ->
- check_type(Type, P, Defs++Ts);
+ LocalTypes =
+ [{N,length(Args)} ||
+ #t_def{name = #t_type{name = N, args = Args}} <- Defs],
+ check_type(Type, P, LocalTypes, Defs),
+ check_types3(Ts, P, Ls);
_->
- check_types(Ts, P0)
+ check_types3(Ts, P0, Ls)
end;
-check_type(#t_def{type = Type}, P, Ts) ->
- check_type(Type, P, Ts);
-check_type(#t_type{name = Name, args = Args}, P, Ts) ->
- check_used_type(Name, Args, P),
- check_types(Args++Ts, P);
-check_type(#t_var{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_fun{args = Args, range = Range}, P, Ts) ->
- check_type(Range, P, Args++Ts);
-check_type(#t_tuple{types = Types}, P, Ts) ->
- check_types(Types ++Ts, P);
-check_type(#t_list{type = Type}, P, Ts) ->
- check_type(Type, P, Ts);
-check_type(#t_nil{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_paren{type = Type}, P, Ts) ->
- check_type(Type, P, Ts);
-check_type(#t_nonempty_list{type = Type}, P, Ts) ->
- check_type(Type, P, Ts);
-check_type(#t_atom{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_integer{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_integer_range{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_binary{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_float{}, P, Ts) ->
- check_types(Ts, P);
-check_type(#t_union{types = Types}, P, Ts) ->
- check_types(Types++Ts, P);
-check_type(#t_record{fields = Fields}, P, Ts) ->
- check_types(Fields++Ts, P);
-check_type(#t_field{type = Type}, P, Ts) ->
- check_type(Type, P, Ts);
-check_type(undefined, P, Ts) ->
- check_types(Ts, P).
-
-check_used_type(#t_name{name = N, module = Mod}=Name, Args, P) ->
+check_type(#t_def{type = Type}, P, Ls, Ts) ->
+ check_type(Type, P, Ls, Ts);
+check_type(#t_type{name = Name, args = Args}, P, Ls, Ts) ->
+ check_used_type(Name, Args, P, Ls),
+ check_types3(Args++Ts, P, Ls);
+check_type(#t_var{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_fun{args = Args, range = Range}, P, Ls, Ts) ->
+ check_type(Range, P, Ls, Args++Ts);
+check_type(#t_tuple{types = Types}, P, Ls, Ts) ->
+ check_types3(Types ++Ts, P, Ls);
+check_type(#t_list{type = Type}, P, Ls, Ts) ->
+ check_type(Type, P, Ls, Ts);
+check_type(#t_nil{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_paren{type = Type}, P, Ls, Ts) ->
+ check_type(Type, P, Ls, Ts);
+check_type(#t_nonempty_list{type = Type}, P, Ls, Ts) ->
+ check_type(Type, P, Ls, Ts);
+check_type(#t_atom{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_integer{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_integer_range{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_binary{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_float{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
+check_type(#t_union{types = Types}, P, Ls, Ts) ->
+ check_types3(Types++Ts, P, Ls);
+check_type(#t_record{fields = Fields}, P, Ls, Ts) ->
+ check_types3(Fields++Ts, P, Ls);
+check_type(#t_field{type = Type}, P, Ls, Ts) ->
+ check_type(Type, P, Ls, Ts);
+check_type(undefined, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls).
+
+check_used_type(#t_name{name = N, module = Mod}=Name, Args, P, LocalTypes) ->
NArgs = length(Args),
TypeName = {Name, NArgs},
DT = P#parms.tab,
@@ -493,6 +500,7 @@ check_used_type(#t_name{name = N, module = Mod}=Name, Args, P) ->
orelse lists:member(TypeName, ets:lookup(DT, Name))
orelse edoc_types:is_predefined(N, NArgs)
orelse edoc_types:is_predefined_otp_type(N, NArgs)
+ orelse lists:member(TypeName, LocalTypes)
of
true ->
ok;