aboutsummaryrefslogtreecommitdiffstats
path: root/lib/edoc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/edoc')
-rw-r--r--lib/edoc/doc/src/book.xml4
-rw-r--r--lib/edoc/doc/src/fascicules.xml2
-rw-r--r--lib/edoc/doc/src/part.xml4
-rw-r--r--lib/edoc/doc/src/part_notes.xml4
-rw-r--r--lib/edoc/doc/src/ref_man.xml4
-rw-r--r--lib/edoc/src/edoc.appup.src22
-rw-r--r--lib/edoc/src/edoc_doclet.erl2
-rw-r--r--lib/edoc/src/edoc_layout.erl10
-rw-r--r--lib/edoc/src/edoc_lib.erl3
-rw-r--r--lib/edoc/src/edoc_parser.yrl17
-rw-r--r--lib/edoc/src/edoc_scanner.erl2
-rw-r--r--lib/edoc/src/edoc_specs.erl19
-rw-r--r--lib/edoc/src/edoc_tags.erl4
-rw-r--r--lib/edoc/src/edoc_types.erl4
-rw-r--r--lib/edoc/src/edoc_types.hrl4
-rw-r--r--lib/edoc/test/edoc_SUITE.erl46
-rw-r--r--lib/edoc/test/edoc_SUITE_data/map_module.erl27
17 files changed, 140 insertions, 38 deletions
diff --git a/lib/edoc/doc/src/book.xml b/lib/edoc/doc/src/book.xml
index 67b7cdb2d7..1a11629e6d 100644
--- a/lib/edoc/doc/src/book.xml
+++ b/lib/edoc/doc/src/book.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE book SYSTEM "book.dtd">
<book xmlns:xi="http://www.w3.org/2001/XInclude">
<header titlestyle="normal">
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/edoc/doc/src/fascicules.xml b/lib/edoc/doc/src/fascicules.xml
index 1b9d6bc94d..154c8a3b6d 100644
--- a/lib/edoc/doc/src/fascicules.xml
+++ b/lib/edoc/doc/src/fascicules.xml
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE fascicules SYSTEM "fascicules.dtd">
<fascicules>
diff --git a/lib/edoc/doc/src/part.xml b/lib/edoc/doc/src/part.xml
index a71b4eda13..876ae858f9 100644
--- a/lib/edoc/doc/src/part.xml
+++ b/lib/edoc/doc/src/part.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE part SYSTEM "part.dtd">
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2006</year><year>2009</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/edoc/doc/src/part_notes.xml b/lib/edoc/doc/src/part_notes.xml
index 42fc39af42..41e6c1c7f7 100644
--- a/lib/edoc/doc/src/part_notes.xml
+++ b/lib/edoc/doc/src/part_notes.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE part SYSTEM "part.dtd">
<part xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2007</year><year>2009</year>
+ <year>2007</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/edoc/doc/src/ref_man.xml b/lib/edoc/doc/src/ref_man.xml
index a9af8740b9..a71b35d118 100644
--- a/lib/edoc/doc/src/ref_man.xml
+++ b/lib/edoc/doc/src/ref_man.xml
@@ -1,10 +1,10 @@
-<?xml version="1.0" encoding="latin1" ?>
+<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE application SYSTEM "application.dtd">
<application xmlns:xi="http://www.w3.org/2001/XInclude">
<header>
<copyright>
- <year>2006</year><year>2011</year>
+ <year>2006</year><year>2013</year>
<holder>Ericsson AB. All Rights Reserved.</holder>
</copyright>
<legalnotice>
diff --git a/lib/edoc/src/edoc.appup.src b/lib/edoc/src/edoc.appup.src
index 54a63833e6..45b4046ed8 100644
--- a/lib/edoc/src/edoc.appup.src
+++ b/lib/edoc/src/edoc.appup.src
@@ -1 +1,21 @@
-{"%VSN%",[],[]}.
+%% -*- erlang -*-
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2014. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+{"%VSN%",
+ [{<<".*">>,[{restart_application, edoc}]}],
+ [{<<".*">>,[{restart_application, edoc}]}]
+}.
diff --git a/lib/edoc/src/edoc_doclet.erl b/lib/edoc/src/edoc_doclet.erl
index ce1e94a26a..5653b5894b 100644
--- a/lib/edoc/src/edoc_doclet.erl
+++ b/lib/edoc/src/edoc_doclet.erl
@@ -200,7 +200,7 @@ source({M, P, Name, Path}, Dir, Suffix, Env, Set, Private, Hidden,
{Set, Error}
end;
R ->
- report("skipping source file '~ts': ~W.", [File, R, 15]),
+ report("skipping source file '~ts': ~P.", [File, R, 15]),
{Set, true}
end.
diff --git a/lib/edoc/src/edoc_layout.erl b/lib/edoc/src/edoc_layout.erl
index 7bd0615f5c..e164ff060f 100644
--- a/lib/edoc/src/edoc_layout.erl
+++ b/lib/edoc/src/edoc_layout.erl
@@ -829,6 +829,10 @@ t_type([#xmlElement{name = list, content = Es}]) ->
t_list(Es);
t_type([#xmlElement{name = nonempty_list, content = Es}]) ->
t_nonempty_list(Es);
+t_type([#xmlElement{name = map, content = Es}]) ->
+ t_map(Es);
+t_type([#xmlElement{name = map_field, content=Es}]) ->
+ t_map_field(Es);
t_type([#xmlElement{name = tuple, content = Es}]) ->
t_tuple(Es);
t_type([#xmlElement{name = 'fun', content = Es}]) ->
@@ -877,6 +881,12 @@ t_fun(Es) ->
["("] ++ seq(fun t_utype_elem/1, get_content(argtypes, Es),
[") -> "] ++ t_utype(get_elem(type, Es))).
+t_map(Es) ->
+ ["#{"] ++ seq(fun t_utype_elem/1, Es, ["}"]).
+
+t_map_field([K,V]) ->
+ [t_utype_elem(K) ++ " => " ++ t_utype_elem(V)].
+
t_record(E, Es) ->
Name = ["#"] ++ t_type(get_elem(atom, Es)),
case get_elem(field, Es) of
diff --git a/lib/edoc/src/edoc_lib.erl b/lib/edoc/src/edoc_lib.erl
index 276f48453e..c46338a2e1 100644
--- a/lib/edoc/src/edoc_lib.erl
+++ b/lib/edoc/src/edoc_lib.erl
@@ -1,4 +1,3 @@
-%% -*- coding: utf-8 -*-
%% =====================================================================
%% This library is free software; you can redistribute it and/or modify
%% it under the terms of the GNU Lesser General Public License as
@@ -1033,7 +1032,7 @@ run_plugin(Name, Key, Default, Fun, Opts) when is_atom(Name) ->
{ok, Value} ->
Value;
R ->
- report("error in ~ts '~w': ~W.", [Name, Module, R, 20]),
+ report("error in ~ts '~w': ~P.", [Name, Module, R, 20]),
exit(error)
end.
diff --git a/lib/edoc/src/edoc_parser.yrl b/lib/edoc/src/edoc_parser.yrl
index a20f152f34..c6f8a04775 100644
--- a/lib/edoc/src/edoc_parser.yrl
+++ b/lib/edoc/src/edoc_parser.yrl
@@ -1,4 +1,3 @@
-%% -*- coding: utf-8 -*-
%% ========================== -*-Erlang-*- =============================
%% EDoc type specification grammar for the Yecc parser generator,
%% adapted from Sven-Olof Nyström's type specification parser.
@@ -30,13 +29,14 @@ Nonterminals
start spec func_type utype_list utype_tuple utypes utype ptypes ptype
nutype function_name where_defs defs defs2 def typedef etype
throws qname ref aref mref lref pref var_list vars fields field
+utype_map utype_map_fields utype_map_field
futype_list bin_base_type bin_unit_type.
Terminals
atom float integer var an_var string start_spec start_typedef start_throws
start_ref
-'(' ')' ',' '.' '->' '{' '}' '[' ']' '|' '+' ':' '::' '=' '/' '//' '*'
+'(' ')' ',' '.' '=>' '->' '{' '}' '[' ']' '|' '+' ':' '::' '=' '/' '//' '*'
'#' 'where' '<<' '>>' '..' '...'.
Rootsymbol start.
@@ -70,6 +70,14 @@ utype_list -> '(' utypes ')' : {lists:reverse('$2'), tok_line('$1')}.
futype_list -> utype_list : '$1'.
futype_list -> '(' '...' ')' : {[#t_var{name = '...'}], tok_line('$1')}.
+utype_map -> '#' '{' utype_map_fields '}' : lists:reverse('$3').
+
+utype_map_fields -> '$empty' : [].
+utype_map_fields -> utype_map_field : ['$1'].
+utype_map_fields -> utype_map_fields ',' utype_map_field : ['$3' | '$1'].
+
+utype_map_field -> utype '=>' utype : #t_map_field{ k_type = '$1', v_type = '$3'}.
+
utype_tuple -> '{' utypes '}' : lists:reverse('$2').
%% Produced in reverse order.
@@ -92,9 +100,10 @@ ptype -> var : #t_var{name = tok_val('$1')}.
ptype -> atom : #t_atom{val = tok_val('$1')}.
ptype -> integer: #t_integer{val = tok_val('$1')}.
ptype -> integer '..' integer: #t_integer_range{from = tok_val('$1'),
- to = tok_val('$3')}.
+ to = tok_val('$3')}.
ptype -> float: #t_float{val = tok_val('$1')}.
ptype -> utype_tuple : #t_tuple{types = '$1'}.
+ptype -> utype_map : #t_map{types = '$1'}.
ptype -> '[' ']' : #t_nil{}.
ptype -> '[' utype ']' : #t_list{type = '$2'}.
ptype -> '[' utype ',' '...' ']' : #t_nonempty_list{type = '$2'}.
@@ -463,3 +472,5 @@ throw_error(parse_param, L) ->
throw({error, L, "missing parameter name"});
throw_error({Where, E}, L) when is_list(Where) ->
throw({error,L,{"unknown error parsing ~ts: ~P.",[Where,E,15]}}).
+
+%% vim: ft=erlang
diff --git a/lib/edoc/src/edoc_scanner.erl b/lib/edoc/src/edoc_scanner.erl
index 754fcef643..6ff97a134c 100644
--- a/lib/edoc/src/edoc_scanner.erl
+++ b/lib/edoc/src/edoc_scanner.erl
@@ -137,6 +137,8 @@ scan1([$"|Cs0], Toks, Pos) -> % String
scan_error({illegal, string}, Pos)
end;
%% Punctuation characters and operators, first recognise multiples.
+scan1([$=,$>|Cs], Toks, Pos) ->
+ scan1(Cs, [{'=>',Pos}|Toks], Pos);
scan1([$<,$<|Cs], Toks, Pos) ->
scan1(Cs, [{'<<',Pos}|Toks], Pos);
scan1([$>,$>|Cs], Toks, Pos) ->
diff --git a/lib/edoc/src/edoc_specs.erl b/lib/edoc/src/edoc_specs.erl
index 5acf8ac0d5..211a354c74 100644
--- a/lib/edoc/src/edoc_specs.erl
+++ b/lib/edoc/src/edoc_specs.erl
@@ -1,7 +1,7 @@
%%
%% %CopyrightBegin%
%%
-%% Copyright Ericsson AB 1996-2011. All Rights Reserved.
+%% Copyright Ericsson AB 1996-2014. All Rights Reserved.
%%
%% The contents of this file are subject to the Erlang Public License,
%% Version 1.1, (the "License"); you may not use this file except in
@@ -35,7 +35,7 @@
%% Exported functions
%%
--spec type(Form::syntaxTree(), TypeDocs::dict()) -> #tag{}.
+-spec type(Form::syntaxTree(), TypeDocs::dict:dict()) -> #tag{}.
%% @doc Convert an Erlang type to EDoc representation.
%% TypeDocs is a dict of {Name, Doc}.
@@ -88,7 +88,7 @@ dummy_spec(Form) ->
-spec docs(Forms::[syntaxTree()],
CommentFun :: fun( ([syntaxTree()], Line :: term()) -> #tag{} ))
- -> dict().
+ -> dict:dict().
%% @doc Find comments after -type/-opaque declarations.
%% Postcomments "inside" the type are skipped.
@@ -358,6 +358,14 @@ d2e({type,_,tuple,any}) ->
d2e({type,_,binary,[Base,Unit]}) ->
#t_binary{base_size = element(3, Base),
unit_size = element(3, Unit)};
+d2e({type,_,map,any}) ->
+ #t_map{ types = []};
+d2e({type,_,map,Es}) ->
+ #t_map{ types = d2e(Es) };
+d2e({type,_,map_field_assoc,K,V}) ->
+ #t_map_field{ k_type = d2e(K), v_type=d2e(V) };
+d2e({type,_,map_field_exact,K,V}) ->
+ #t_map_field{ k_type = d2e(K), v_type=d2e(V) };
d2e({type,_,tuple,Ts0}) ->
Ts = d2e(Ts0),
typevar_anno(#t_tuple{types = Ts}, Ts);
@@ -476,6 +484,11 @@ xrecs(#t_fun{args = Args0, range = Range0}=T, P) ->
Args = xrecs(Args0, P),
Range = xrecs(Range0, P),
T#t_fun{args = Args, range = Range};
+xrecs(#t_map{ types = Ts0 }=T,P) ->
+ Ts = xrecs(Ts0, P),
+ T#t_map{ types = Ts };
+xrecs(#t_map_field{ k_type=Kt, v_type=Vt}=T, P) ->
+ T#t_map_field{ k_type=xrecs(Kt,P), v_type=xrecs(Vt,P)};
xrecs(#t_tuple{types = Types0}=T, P) ->
Types = xrecs(Types0, P),
T#t_tuple{types = Types};
diff --git a/lib/edoc/src/edoc_tags.erl b/lib/edoc/src/edoc_tags.erl
index eb41f1922a..264a533a52 100644
--- a/lib/edoc/src/edoc_tags.erl
+++ b/lib/edoc/src/edoc_tags.erl
@@ -454,12 +454,14 @@ check_type(#tag{line = L, data = Data}, P0, Ls, Ts) ->
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_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_map{}, P, Ls, Ts) ->
+ check_types3(Ts, P, Ls);
check_type(#t_tuple{types = Types}, P, Ls, Ts) ->
check_types3(Types ++Ts, P, Ls);
check_type(#t_list{type = Type}, P, Ls, Ts) ->
diff --git a/lib/edoc/src/edoc_types.erl b/lib/edoc/src/edoc_types.erl
index 60c6cecb97..af8f1230fb 100644
--- a/lib/edoc/src/edoc_types.erl
+++ b/lib/edoc/src/edoc_types.erl
@@ -141,6 +141,10 @@ to_xml(#t_type{name = N, args = As}, Env) ->
to_xml(#t_fun{args = As, range = T}, Env) ->
{'fun', [{argtypes, map(fun wrap_utype/2, As, Env)},
wrap_utype(T, Env)]};
+to_xml(#t_map{ types = Ts}, Env) ->
+ {map, map(fun wrap_utype/2, Ts, Env)};
+to_xml(#t_map_field{ k_type=K, v_type=V}, Env) ->
+ {map_field, [wrap_utype(K,Env), wrap_utype(V, Env)]};
to_xml(#t_tuple{types = Ts}, Env) ->
{tuple, map(fun wrap_utype/2, Ts, Env)};
to_xml(#t_list{type = T}, Env) ->
diff --git a/lib/edoc/src/edoc_types.hrl b/lib/edoc/src/edoc_types.hrl
index 05c61d70ff..7fec10d936 100644
--- a/lib/edoc/src/edoc_types.hrl
+++ b/lib/edoc/src/edoc_types.hrl
@@ -155,3 +155,7 @@
%% @type t_paren() = #t_paren{a = list(), type = type()}
-record(t_paren, {a=[], type}). % parentheses
+
+-record(t_map, {a=[], types=[]}).
+-record(t_map_field, {a=[], k_type, v_type}).
+
diff --git a/lib/edoc/test/edoc_SUITE.erl b/lib/edoc/test/edoc_SUITE.erl
index 5b95c35756..c9c7811afb 100644
--- a/lib/edoc/test/edoc_SUITE.erl
+++ b/lib/edoc/test/edoc_SUITE.erl
@@ -22,12 +22,12 @@
init_per_group/2,end_per_group/2]).
%% Test cases
--export([build_std/1]).
+-export([app/1,appup/1,build_std/1,build_map_module/1]).
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [build_std].
+ [app,appup,build_std,build_map_module].
groups() ->
[].
@@ -44,26 +44,36 @@ init_per_group(_GroupName, Config) ->
end_per_group(_GroupName, Config) ->
Config.
+%% Test that the .app file does not contain any `basic' errors
+app(Config) when is_list(Config) ->
+ ok = ?t:app_test(edoc).
-build_std(suite) ->
- [];
-build_std(doc) ->
- ["Build some documentation using standard EDoc layout"];
-build_std(Config) when is_list(Config) ->
+%% Test that the .appup file does not contain any `basic' errors
+appup(Config) when is_list(Config) ->
+ ok = ?t:appup_test(edoc).
- ?line DataDir = ?config(data_dir, Config),
- ?line Overview1 = filename:join(DataDir, "overview.edoc"),
- ?line Overview2 = filename:join(DataDir, "overview.syntax_tools"),
- ?line PrivDir = ?config(priv_dir, Config),
+build_std(suite) -> [];
+build_std(doc) -> ["Build some documentation using standard EDoc layout"];
+build_std(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ Overview1 = filename:join(DataDir, "overview.edoc"),
+ Overview2 = filename:join(DataDir, "overview.syntax_tools"),
+ PrivDir = ?config(priv_dir, Config),
- ?line ok = edoc:application(edoc, [{overview, Overview1},
- {def, {vsn,"TEST"}},
- {dir, PrivDir}]),
+ ok = edoc:application(edoc, [{overview, Overview1},
+ {def, {vsn,"TEST"}},
+ {dir, PrivDir}]),
- ?line ok = edoc:application(syntax_tools, [{overview, Overview2},
- {def, {vsn,"TEST"}},
- {dir, PrivDir}]),
+ ok = edoc:application(syntax_tools, [{overview, Overview2},
+ {def, {vsn,"TEST"}},
+ {dir, PrivDir}]),
- ?line ok = edoc:application(xmerl, [{dir, PrivDir}]),
+ ok = edoc:application(xmerl, [{dir, PrivDir}]),
+ ok.
+build_map_module(Config) when is_list(Config) ->
+ DataDir = ?config(data_dir, Config),
+ PrivDir = ?config(priv_dir, Config),
+ Filename = filename:join(DataDir, "map_module.erl"),
+ ok = edoc:file(Filename, [{dir, PrivDir}]),
ok.
diff --git a/lib/edoc/test/edoc_SUITE_data/map_module.erl b/lib/edoc/test/edoc_SUITE_data/map_module.erl
new file mode 100644
index 0000000000..94ee7e6f26
--- /dev/null
+++ b/lib/edoc/test/edoc_SUITE_data/map_module.erl
@@ -0,0 +1,27 @@
+-module(map_module).
+
+-export([foo1/1,foo2/3]).
+
+%% @type wazzup() = integer()
+%% @type some_type() = map()
+%% @type some_other_type() = {a, #{ list() => term()}}
+
+-type some_type() :: map().
+-type some_other_type() :: {'a', #{ list() => term()} }.
+-type wazzup() :: integer().
+
+-spec foo1(Map :: #{ 'a' => integer(), 'b' => term()}) -> term().
+
+%% @doc Gets value from map.
+
+foo1(#{ a:= 1, b := V}) -> V.
+
+%% @spec foo2(some_type(), Type2 :: some_other_type(), map()) -> Value
+%% @doc Gets value from map.
+
+-spec foo2(
+ Type1 :: some_type(),
+ Type2 :: some_other_type(),
+ Map :: #{ get => 'value', 'value' => binary()}) -> binary().
+
+foo2(Type1, {a,#{ "a" := _}}, #{get := value, value := B}) when is_map(Type1) -> B.