aboutsummaryrefslogtreecommitdiffstats
path: root/lib/syntax_tools
diff options
context:
space:
mode:
Diffstat (limited to 'lib/syntax_tools')
-rw-r--r--lib/syntax_tools/doc/Makefile2
-rw-r--r--lib/syntax_tools/examples/Makefile2
-rw-r--r--lib/syntax_tools/src/Makefile5
-rw-r--r--lib/syntax_tools/src/epp_dodger.erl71
-rw-r--r--lib/syntax_tools/src/erl_comment_scan.erl18
-rw-r--r--lib/syntax_tools/src/erl_prettypr.erl55
-rw-r--r--lib/syntax_tools/src/erl_recomment.erl45
-rw-r--r--lib/syntax_tools/src/erl_syntax.erl582
-rw-r--r--lib/syntax_tools/src/erl_syntax_lib.erl150
-rw-r--r--lib/syntax_tools/src/erl_tidy.erl32
-rw-r--r--lib/syntax_tools/src/igor.erl162
-rw-r--r--lib/syntax_tools/src/prettypr.erl74
12 files changed, 970 insertions, 228 deletions
diff --git a/lib/syntax_tools/doc/Makefile b/lib/syntax_tools/doc/Makefile
index 27f32988c8..6afd16f669 100644
--- a/lib/syntax_tools/doc/Makefile
+++ b/lib/syntax_tools/doc/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id: Makefile,v 1.1.1.1 2004/10/04 13:56:14 richardc Exp $
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/syntax_tools/examples/Makefile b/lib/syntax_tools/examples/Makefile
index a52a52a50c..7cfe9185c2 100644
--- a/lib/syntax_tools/examples/Makefile
+++ b/lib/syntax_tools/examples/Makefile
@@ -13,8 +13,6 @@
# Portions created by Ericsson are Copyright 1999, Ericsson Utvecklings
# AB. All Rights Reserved.''
#
-# $Id$
-#
include $(ERL_TOP)/make/target.mk
include $(ERL_TOP)/make/$(TARGET)/otp.mk
diff --git a/lib/syntax_tools/src/Makefile b/lib/syntax_tools/src/Makefile
index 62a24d98c0..50369e633e 100644
--- a/lib/syntax_tools/src/Makefile
+++ b/lib/syntax_tools/src/Makefile
@@ -23,7 +23,10 @@ RELSYSDIR = $(RELEASE_PATH)/lib/syntax_tools-$(VSN)
EBIN = ../ebin
-ERL_COMPILE_FLAGS += +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_obsolete_guard
+ifeq ($(NATIVE_LIBS_ENABLED),yes)
+ERL_COMPILE_FLAGS += +native
+endif
+ERL_COMPILE_FLAGS += +warn_unused_vars +nowarn_shadow_vars +warn_unused_import +warn_missing_spec +warn_untyped_record
SOURCES=erl_syntax.erl erl_prettypr.erl erl_syntax_lib.erl \
erl_comment_scan.erl erl_recomment.erl erl_tidy.erl \
diff --git a/lib/syntax_tools/src/epp_dodger.erl b/lib/syntax_tools/src/epp_dodger.erl
index 7aef549574..6b0f2034f8 100644
--- a/lib/syntax_tools/src/epp_dodger.erl
+++ b/lib/syntax_tools/src/epp_dodger.erl
@@ -90,6 +90,9 @@
%% This is a so-called Erlang I/O ErrorInfo structure; see the {@link
%% //stdlib/io} module for details.
+-type errorinfo() :: term(). % {integer(), atom(), term()}.
+
+-type option() :: atom() | {atom(), term()}.
%% =====================================================================
%% @spec parse_file(File) -> {ok, Forms} | {error, errorinfo()}
@@ -98,6 +101,9 @@
%%
%% @equiv parse_file(File, [])
+-spec parse_file(file:filename()) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
parse_file(File) ->
parse_file(File, []).
@@ -109,11 +115,11 @@ parse_file(File) ->
%% @doc Reads and parses a file. If successful, `{ok, Forms}'
%% is returned, where `Forms' is a list of abstract syntax
%% trees representing the "program forms" of the file (cf.
-%% `erl_syntax:is_form/1'). Otherwise, `{error,
-%% errorinfo()}' is returned, typically if the file could not be
-%% opened. Note that parse errors show up as error markers in the
-%% returned list of forms; they do not cause this function to fail or
-%% return `{error,errorinfo()}'.
+%% `erl_syntax:is_form/1'). Otherwise, `{error, errorinfo()}' is
+%% returned, typically if the file could not be opened. Note that
+%% parse errors show up as error markers in the returned list of
+%% forms; they do not cause this function to fail or return
+%% `{error, errorinfo()}'.
%%
%% Options:
%% <dl>
@@ -135,6 +141,9 @@ parse_file(File) ->
%% @see quick_parse_file/1
%% @see erl_syntax:is_form/1
+-spec parse_file(file:filename(), [option()]) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
parse_file(File, Options) ->
parse_file(File, fun parse/3, Options).
@@ -144,6 +153,9 @@ parse_file(File, Options) ->
%%
%% @equiv quick_parse_file(File, [])
+-spec quick_parse_file(file:filename()) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
quick_parse_file(File) ->
quick_parse_file(File, []).
@@ -167,6 +179,9 @@ quick_parse_file(File) ->
%% @see quick_parse/2
%% @see parse_file/2
+-spec quick_parse_file(file:filename(), [option()]) ->
+ {'ok', erl_syntax:forms()} | {'error', errorinfo()}.
+
quick_parse_file(File, Options) ->
parse_file(File, fun quick_parse/3, Options ++ [no_fail]).
@@ -185,6 +200,8 @@ parse_file(File, Parser, Options) ->
%% @spec parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
%% @equiv parse(IODevice, 1)
+-spec parse(file:io_device()) -> {'ok', erl_syntax:forms()}.
+
parse(Dev) ->
parse(Dev, 1).
@@ -196,6 +213,8 @@ parse(Dev) ->
%% @equiv parse(IODevice, StartLine, [])
%% @see parse/1
+-spec parse(file:io_device(), integer()) -> {'ok', erl_syntax:forms()}.
+
parse(Dev, L) ->
parse(Dev, L, []).
@@ -216,12 +235,18 @@ parse(Dev, L) ->
%% @see parse_form/2
%% @see quick_parse/3
+-spec parse(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms()}.
+
parse(Dev, L0, Options) ->
parse(Dev, L0, fun parse_form/3, Options).
%% @spec quick_parse(IODevice) -> {ok, Forms} | {error, errorinfo()}
%% @equiv quick_parse(IODevice, 1)
+-spec quick_parse(file:io_device()) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev) ->
quick_parse(Dev, 1).
@@ -234,6 +259,9 @@ quick_parse(Dev) ->
%% @equiv quick_parse(IODevice, StartLine, [])
%% @see quick_parse/1
+-spec quick_parse(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev, L) ->
quick_parse(Dev, L, []).
@@ -252,6 +280,9 @@ quick_parse(Dev, L) ->
%% @see quick_parse_form/2
%% @see parse/3
+-spec quick_parse(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms()}.
+
quick_parse(Dev, L0, Options) ->
parse(Dev, L0, fun quick_parse_form/3, Options).
@@ -284,6 +315,10 @@ parse(Dev, L0, Fs, Parser, Options) ->
%%
%% @see quick_parse_form/2
+-spec parse_form(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
parse_form(Dev, L0) ->
parse_form(Dev, L0, []).
@@ -310,6 +345,10 @@ parse_form(Dev, L0) ->
%% @see parse_form/2
%% @see quick_parse_form/3
+-spec parse_form(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
parse_form(Dev, L0, Options) ->
parse_form(Dev, L0, fun normal_parser/2, Options).
@@ -326,6 +365,10 @@ parse_form(Dev, L0, Options) ->
%%
%% @see parse_form/2
+-spec quick_parse_form(file:io_device(), integer()) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
quick_parse_form(Dev, L0) ->
quick_parse_form(Dev, L0, []).
@@ -347,6 +390,10 @@ quick_parse_form(Dev, L0) ->
%% @see quick_parse_form/2
%% @see parse_form/3
+-spec quick_parse_form(file:io_device(), integer(), [option()]) ->
+ {'ok', erl_syntax:forms(), integer()}
+ | {'eof', integer()} | {'error', errorinfo(), integer()}.
+
quick_parse_form(Dev, L0, Options) ->
parse_form(Dev, L0, fun quick_parser/2, Options).
@@ -751,11 +798,13 @@ fix_define([{atom, L, ?pp_form}, {'(', _}, {')', _}, {'->', _},
fix_define(_Ts) ->
error.
-%% @spec (Tokens::[term()]) -> string()
+%% @spec tokens_to_string(Tokens::[term()]) -> string()
%%
%% @doc Generates a string corresponding to the given token sequence.
%% The string can be re-tokenized to yield the same token list again.
+-spec tokens_to_string([term()]) -> string().
+
tokens_to_string([{atom,_,A} | Ts]) ->
io_lib:write_atom(A) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([{string, _, S} | Ts]) ->
@@ -764,21 +813,23 @@ tokens_to_string([{float, _, F} | Ts]) ->
float_to_list(F) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([{integer, _, N} | Ts]) ->
integer_to_list(N) ++ " " ++ tokens_to_string(Ts);
-tokens_to_string([{var,_,A} | Ts]) ->
+tokens_to_string([{var, _, A} | Ts]) ->
atom_to_list(A) ++ " " ++ tokens_to_string(Ts);
-tokens_to_string([{dot,_} | Ts]) ->
+tokens_to_string([{dot, _} | Ts]) ->
".\n" ++ tokens_to_string(Ts);
-tokens_to_string([{A,_} | Ts]) ->
+tokens_to_string([{A, _} | Ts]) ->
atom_to_list(A) ++ " " ++ tokens_to_string(Ts);
tokens_to_string([]) ->
"".
-%% @spec (Descriptor::term()) -> string()
+%% @spec format_error(Descriptor::term()) -> string()
%% @hidden
%% @doc Callback function for formatting error descriptors. Not for
%% normal use.
+-spec format_error(term()) -> string().
+
format_error(macro_args) ->
errormsg("macro call missing end parenthesis");
format_error({unknown, Reason}) ->
diff --git a/lib/syntax_tools/src/erl_comment_scan.erl b/lib/syntax_tools/src/erl_comment_scan.erl
index df1449da4e..09ce21a428 100644
--- a/lib/syntax_tools/src/erl_comment_scan.erl
+++ b/lib/syntax_tools/src/erl_comment_scan.erl
@@ -14,8 +14,7 @@
%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
%% USA
%%
-%% $Id$
-%%
+%% =====================================================================
%% @copyright 1997-2006 Richard Carlsson
%% @author Richard Carlsson <[email protected]>
%% @end
@@ -29,6 +28,11 @@
%% =====================================================================
+
+-type comment() :: {integer(), integer(), integer(), [string()]}.
+-type commentLine() :: {integer(), integer(), integer(), string()}.
+
+%% =====================================================================
%% @spec file(FileName::file:filename()) -> [Comment]
%%
%% Comment = {Line, Column, Indentation, Text}
@@ -59,6 +63,8 @@
%% error occurred, where `Reason' is an atom corresponding to
%% a Posix error code; see the module {@link //kernel/file} for details.
+-spec file(file:filename()) -> [comment()].
+
file(Name) ->
Name1 = filename(Name),
case catch {ok, file:read_file(Name1)} of
@@ -80,7 +86,7 @@ file(Name) ->
%% =====================================================================
-%% string(string()) -> [Comment]
+%% @spec string(string()) -> [Comment]
%%
%% Comment = {Line, Column, Indentation, Text}
%% Line = integer()
@@ -94,6 +100,8 @@ file(Name) ->
%%
%% @see file/1
+-spec string(string()) -> [comment()].
+
string(Text) ->
lists:reverse(join_lines(scan_lines(Text))).
@@ -116,6 +124,8 @@ string(Text) ->
%% to (but not including) the line-terminating newline. For details on
%% `Line', `Column' and `Indent', see {@link file/1}.
+-spec scan_lines(string()) -> [commentLine()].
+
scan_lines(Text) ->
scan_lines(Text, 1, 0, 0, []).
@@ -231,6 +241,8 @@ scan_char([], _L, _Col, Ack) ->
%%
%% @see scan_lines/1
+-spec join_lines([commentLine()]) -> [comment()].
+
join_lines([{L, Col, Ind, Txt} | Lines]) ->
join_lines(Lines, [Txt], L, Col, Ind);
join_lines([]) ->
diff --git a/lib/syntax_tools/src/erl_prettypr.erl b/lib/syntax_tools/src/erl_prettypr.erl
index 8d2f4facea..606441bcf1 100644
--- a/lib/syntax_tools/src/erl_prettypr.erl
+++ b/lib/syntax_tools/src/erl_prettypr.erl
@@ -48,25 +48,30 @@
-define(NOUSER, undefined).
-define(NOHOOK, none).
--record(ctxt, {prec = 0,
- sub_indent = 2,
- break_indent = 4,
- clause = undefined,
- hook = ?NOHOOK,
- paper = ?PAPER,
- ribbon = ?RIBBON,
- user = ?NOUSER}).
+-type hook() :: 'none'
+ | fun((erl_syntax:syntaxTree(), _, _) -> prettypr:document()).
+-record(ctxt, {prec = 0 :: integer(),
+ sub_indent = 2 :: non_neg_integer(),
+ break_indent = 4 :: non_neg_integer(),
+ clause = undefined,
+ hook = ?NOHOOK :: hook(),
+ paper = ?PAPER :: integer(),
+ ribbon = ?RIBBON :: integer(),
+ user = ?NOUSER :: term()}).
+-type context() :: #ctxt{}.
%% =====================================================================
%% The following functions examine and modify contexts:
-%% @spec (context()) -> context()
+%% @spec (context()) -> integer()
%% @doc Returns the operator precedence field of the prettyprinter
%% context.
%%
%% @see set_ctxt_precedence/2
+-spec get_ctxt_precedence(context()) -> integer().
+
get_ctxt_precedence(Ctxt) ->
Ctxt#ctxt.prec.
@@ -78,6 +83,8 @@ get_ctxt_precedence(Ctxt) ->
%% @see //stdlib/erl_parse
%% @see get_ctxt_precedence/1
+-spec set_ctxt_precedence(context(), integer()) -> context().
+
set_ctxt_precedence(Ctxt, Prec) ->
set_prec(Ctxt, Prec).
@@ -91,6 +98,8 @@ reset_prec(Ctxt) ->
%% @doc Returns the paper widh field of the prettyprinter context.
%% @see set_ctxt_paperwidth/2
+-spec get_ctxt_paperwidth(context()) -> integer().
+
get_ctxt_paperwidth(Ctxt) ->
Ctxt#ctxt.paper.
@@ -104,6 +113,8 @@ get_ctxt_paperwidth(Ctxt) ->
%%
%% @see get_ctxt_paperwidth/1
+-spec set_ctxt_paperwidth(context(), integer()) -> context().
+
set_ctxt_paperwidth(Ctxt, W) ->
Ctxt#ctxt{paper = W}.
@@ -111,6 +122,8 @@ set_ctxt_paperwidth(Ctxt, W) ->
%% @doc Returns the line widh field of the prettyprinter context.
%% @see set_ctxt_linewidth/2
+-spec get_ctxt_linewidth(context()) -> integer().
+
get_ctxt_linewidth(Ctxt) ->
Ctxt#ctxt.ribbon.
@@ -124,6 +137,8 @@ get_ctxt_linewidth(Ctxt) ->
%%
%% @see get_ctxt_linewidth/1
+-spec set_ctxt_linewidth(context(), integer()) -> context().
+
set_ctxt_linewidth(Ctxt, W) ->
Ctxt#ctxt{ribbon = W}.
@@ -131,6 +146,8 @@ set_ctxt_linewidth(Ctxt, W) ->
%% @doc Returns the hook function field of the prettyprinter context.
%% @see set_ctxt_hook/2
+-spec get_ctxt_hook(context()) -> hook().
+
get_ctxt_hook(Ctxt) ->
Ctxt#ctxt.hook.
@@ -138,6 +155,8 @@ get_ctxt_hook(Ctxt) ->
%% @doc Updates the hook function field of the prettyprinter context.
%% @see get_ctxt_hook/1
+-spec set_ctxt_hook(context(), hook()) -> context().
+
set_ctxt_hook(Ctxt, Hook) ->
Ctxt#ctxt{hook = Hook}.
@@ -145,6 +164,8 @@ set_ctxt_hook(Ctxt, Hook) ->
%% @doc Returns the user data field of the prettyprinter context.
%% @see set_ctxt_user/2
+-spec get_ctxt_user(context()) -> term().
+
get_ctxt_user(Ctxt) ->
Ctxt#ctxt.user.
@@ -152,6 +173,8 @@ get_ctxt_user(Ctxt) ->
%% @doc Updates the user data field of the prettyprinter context.
%% @see get_ctxt_user/1
+-spec set_ctxt_user(context(), term()) -> context().
+
set_ctxt_user(Ctxt, X) ->
Ctxt#ctxt{user = X}.
@@ -160,6 +183,8 @@ set_ctxt_user(Ctxt, X) ->
%% @spec format(Tree::syntaxTree()) -> string()
%% @equiv format(Tree, [])
+-spec format(erl_syntax:syntaxTree()) -> string().
+
format(Node) ->
format(Node, []).
@@ -237,6 +262,8 @@ format(Node) ->
%% @see get_ctxt_user/1
%% @see set_ctxt_user/2
+-spec format(erl_syntax:syntaxTree(), [term()]) -> string().
+
format(Node, Options) ->
W = proplists:get_value(paper, Options, ?PAPER),
L = proplists:get_value(ribbon, Options, ?RIBBON),
@@ -247,6 +274,8 @@ format(Node, Options) ->
%% @spec best(Tree::syntaxTree()) -> empty | document()
%% @equiv best(Tree, [])
+-spec best(erl_syntax:syntaxTree()) -> 'empty' | prettypr:document().
+
best(Node) ->
best(Node, []).
@@ -266,6 +295,8 @@ best(Node) ->
%% @see format/2
%% @see prettypr:best/3
+-spec best(erl_syntax:syntaxTree(), [term()]) -> 'empty' | prettypr:document().
+
best(Node, Options) ->
W = proplists:get_value(paper, Options, ?PAPER),
L = proplists:get_value(ribbon, Options, ?RIBBON),
@@ -276,6 +307,8 @@ best(Node, Options) ->
%% @spec layout(Tree::syntaxTree()) -> document()
%% @equiv layout(Tree, [])
+-spec layout(erl_syntax:syntaxTree()) -> prettypr:document().
+
layout(Node) ->
layout(Node, []).
@@ -300,6 +333,8 @@ layout(Node) ->
%% @see format/2
%% @see layout/1
+-spec layout(erl_syntax:syntaxTree(), [term()]) -> prettypr:document().
+
layout(Node, Options) ->
lay(Node,
#ctxt{hook = proplists:get_value(hook, Options, ?NOHOOK),
@@ -593,7 +628,7 @@ lay_2(Node, Ctxt) ->
fun_expr ->
Ctxt1 = reset_prec(Ctxt),
D = lay_clauses(erl_syntax:fun_expr_clauses(Node),
- fun_expr, Ctxt1),
+ fun_expr, Ctxt1),
sep([follow(text("fun"), D, Ctxt1#ctxt.sub_indent),
text("end")]);
diff --git a/lib/syntax_tools/src/erl_recomment.erl b/lib/syntax_tools/src/erl_recomment.erl
index 62ec7da200..145bbc6f37 100644
--- a/lib/syntax_tools/src/erl_recomment.erl
+++ b/lib/syntax_tools/src/erl_recomment.erl
@@ -47,6 +47,9 @@
%% comments. Comments within function definitions or declarations
%% ("forms") are simply ignored.
+-spec quick_recomment_forms(erl_syntax:forms(), [erl_comment_scan:comment()]) ->
+ erl_syntax:syntaxTree().
+
quick_recomment_forms(Tree, Cs) ->
recomment_forms(Tree, Cs, false).
@@ -109,6 +112,9 @@ quick_recomment_forms(Tree, Cs) ->
%% @see recomment_tree/2
%% @see quick_recomment_forms/2
+-spec recomment_forms(erl_syntax:forms(), [erl_comment_scan:comment()]) ->
+ erl_syntax:syntaxTree().
+
recomment_forms(Tree, Cs) ->
recomment_forms(Tree, Cs, true).
@@ -209,7 +215,7 @@ comment_delta(Text) ->
%% the source file itself, but have been included by preprocessing. This
%% way, comments will not be inserted into such parts by mistake.
--record(filter, {file = undefined, line = 0}).
+-record(filter, {file = undefined, line = 0 :: integer()}).
filter_forms(Fs) ->
filter_forms(Fs, false, #filter{}).
@@ -330,6 +336,9 @@ check_file_attr_2(L) ->
%%
%% @see recomment_forms/2
+-spec recomment_tree(erl_syntax:syntaxTree(), [erl_comment_scan:comment()]) ->
+ {erl_syntax:syntaxTree(), [erl_comment_scan:comment()]}.
+
recomment_tree(Tree, Cs) ->
{Tree1, Cs1} = insert_comments(Cs, build_tree(Tree)),
{revert_tree(Tree1), Cs1}.
@@ -592,23 +601,23 @@ expand_comment(C) ->
%% syntax tree for any such tree that can have no subtrees, i.e., such
%% that `erl_syntax:is_leaf' yields `true'.
--record(leaf, {min = 0,
- max = 0,
- precomments = [],
- postcomments = [],
- value}).
-
--record(tree, {min = 0,
- max = 0,
- type,
- attrs,
- precomments = [],
- postcomments = [],
- subtrees = []}).
-
--record(list, {min = 0,
- max = 0,
- subtrees = []}).
+-record(leaf, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ precomments = [] :: [erl_syntax:syntaxTree()],
+ postcomments = [] :: [erl_syntax:syntaxTree()],
+ value :: erl_syntax:syntaxTree()}).
+
+-record(tree, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ type :: atom(),
+ attrs :: erl_syntax:syntaxTreeAttributes(),
+ precomments = [] :: [erl_syntax:syntaxTree()],
+ postcomments = [] :: [erl_syntax:syntaxTree()],
+ subtrees = [] :: [erl_syntax:syntaxTree()]}).
+
+-record(list, {min = 0 :: integer(),
+ max = 0 :: integer(),
+ subtrees = [] :: [erl_syntax:syntaxTree()]}).
leaf_node(Min, Max, Value) ->
#leaf{min = Min,
diff --git a/lib/syntax_tools/src/erl_syntax.erl b/lib/syntax_tools/src/erl_syntax.erl
index 6ceb3ddcaf..9a2967d550 100644
--- a/lib/syntax_tools/src/erl_syntax.erl
+++ b/lib/syntax_tools/src/erl_syntax.erl
@@ -343,8 +343,8 @@
%%
%% type(Com) = comment
--record(com, {pre = [],
- post = []}).
+-record(com, {pre = [] :: [syntaxTree()],
+ post = [] :: [syntaxTree()]}).
%% `attr' records store node attributes as an aggregate.
%%
@@ -357,9 +357,10 @@
%% where `Pos' `Ann' and `Comments' are the corresponding values of a
%% `tree' or `wrapper' record.
--record(attr, {pos = 0,
- ann = [],
- com = none}).
+-record(attr, {pos = 0 :: term(),
+ ann = [] :: [term()],
+ com = none :: 'none' | #com{}}).
+-type syntaxTreeAttributes() :: #attr{}.
%% `tree' records represent new-form syntax tree nodes.
%%
@@ -371,9 +372,9 @@
%%
%% is_tree(Tree) = true
--record(tree, {type,
+-record(tree, {type :: atom(),
attr = #attr{} :: #attr{},
- data}).
+ data :: term()}).
%% `wrapper' records are used for attaching new-form node information to
%% `erl_parse' trees.
@@ -386,10 +387,13 @@
%%
%% is_tree(Wrapper) = false
--record(wrapper, {type,
+-record(wrapper, {type :: atom(),
attr = #attr{} :: #attr{},
- tree}).
+ tree :: term()}).
+%% =====================================================================
+
+-type syntaxTree() :: #tree{} | #wrapper{} | tuple(). % XXX: refine
%% =====================================================================
%%
@@ -532,6 +536,8 @@
%% @see variable/1
%% @see warning_marker/1
+-spec type(syntaxTree()) -> atom().
+
type(#tree{type = T}) ->
T;
type(#wrapper{type = T}) ->
@@ -599,7 +605,7 @@ type(Node) ->
%% =====================================================================
-%% @spec is_leaf(Node::syntaxTree()) -> bool()
+%% @spec is_leaf(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> is a leaf node,
%% otherwise <code>false</code>. The currently recognised leaf node
@@ -635,6 +641,8 @@ type(Node) ->
%% @see type/1
%% @see is_literal/1
+-spec is_leaf(syntaxTree()) -> boolean().
+
is_leaf(Node) ->
case type(Node) of
atom -> true;
@@ -657,7 +665,7 @@ is_leaf(Node) ->
%% =====================================================================
-%% @spec is_form(Node::syntaxTree()) -> bool()
+%% @spec is_form(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> is a syntax tree
%% representing a so-called "source code form", otherwise
@@ -688,6 +696,8 @@ is_leaf(Node) ->
%% @see rule/2
%% @see warning_marker/1
+-spec is_form(syntaxTree()) -> boolean().
+
is_form(Node) ->
case type(Node) of
attribute -> true;
@@ -722,6 +732,8 @@ is_form(Node) ->
%% number *of the error descriptor*; this is all handled transparently
%% by `get_pos' and `set_pos'.
+-spec get_pos(syntaxTree()) -> term().
+
get_pos(#tree{attr = Attr}) ->
Attr#attr.pos;
get_pos(#wrapper{attr = Attr}) ->
@@ -745,6 +757,8 @@ get_pos(Node) ->
%% @see get_pos/1
%% @see copy_pos/2
+-spec set_pos(syntaxTree(), term()) -> syntaxTree().
+
set_pos(Node, Pos) ->
case Node of
#tree{attr = Attr} ->
@@ -771,6 +785,8 @@ set_pos(Node, Pos) ->
%% @see get_pos/1
%% @see set_pos/2
+-spec copy_pos(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_pos(Source, Target) ->
set_pos(Target, get_pos(Source)).
@@ -818,6 +834,8 @@ set_com(Node, Com) ->
%% @see get_postcomments/1
%% @see get_attrs/1
+-spec get_precomments(syntaxTree()) -> [syntaxTree()].
+
get_precomments(#tree{attr = Attr}) -> get_precomments_1(Attr);
get_precomments(#wrapper{attr = Attr}) -> get_precomments_1(Attr);
get_precomments(_) -> [].
@@ -842,6 +860,8 @@ get_precomments_1(#attr{com = #com{pre = Cs}}) -> Cs.
%% @see remove_comments/1
%% @see join_comments/2
+-spec set_precomments(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
set_precomments(Node, Cs) ->
case Node of
#tree{attr = Attr} ->
@@ -875,6 +895,8 @@ set_precomments_1(#attr{com = Com} = Attr, Cs) ->
%% @see add_postcomments/2
%% @see join_comments/2
+-spec add_precomments([syntaxTree()], syntaxTree()) -> syntaxTree().
+
add_precomments(Cs, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -916,6 +938,8 @@ add_precomments_1(Cs, #attr{com = Com} = Attr) ->
%% @see get_precomments/1
%% @see get_attrs/1
+-spec get_postcomments(syntaxTree()) -> [syntaxTree()].
+
get_postcomments(#tree{attr = Attr}) -> get_postcomments_1(Attr);
get_postcomments(#wrapper{attr = Attr}) -> get_postcomments_1(Attr);
get_postcomments(_) -> [].
@@ -940,6 +964,8 @@ get_postcomments_1(#attr{com = #com{post = Cs}}) -> Cs.
%% @see remove_comments/1
%% @see join_comments/2
+-spec set_postcomments(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
set_postcomments(Node, Cs) ->
case Node of
#tree{attr = Attr} ->
@@ -973,6 +999,8 @@ set_postcomments_1(#attr{com = Com} = Attr, Cs) ->
%% @see add_precomments/2
%% @see join_comments/2
+-spec add_postcomments([syntaxTree()], syntaxTree()) -> syntaxTree().
+
add_postcomments(Cs, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -990,7 +1018,7 @@ add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
%% =====================================================================
-%% @spec has_comments(Node::syntaxTree()) -> bool()
+%% @spec has_comments(Node::syntaxTree()) -> boolean()
%%
%% @doc Yields <code>false</code> if the node has no associated
%% comments, and <code>true</code> otherwise.
@@ -1003,6 +1031,8 @@ add_postcomments_1(Cs, #attr{com = Com} = Attr) ->
%% @see get_postcomments/1
%% @see remove_comments/1
+-spec has_comments(syntaxTree()) -> boolean().
+
has_comments(#tree{attr = Attr}) ->
case Attr#attr.com of
none -> false;
@@ -1030,6 +1060,8 @@ has_comments(_) -> false.
%% @see set_precomments/2
%% @see set_postcomments/2
+-spec remove_comments(syntaxTree()) -> syntaxTree().
+
remove_comments(Node) ->
case Node of
#tree{attr = Attr} ->
@@ -1059,6 +1091,8 @@ remove_comments(Node) ->
%% @see set_precomments/2
%% @see set_postcomments/2
+-spec copy_comments(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_comments(Source, Target) ->
set_com(Target, get_com(Source)).
@@ -1081,6 +1115,8 @@ copy_comments(Source, Target) ->
%% @see add_precomments/2
%% @see add_postcomments/2
+-spec join_comments(syntaxTree(), syntaxTree()) -> syntaxTree().
+
join_comments(Source, Target) ->
add_postcomments(
get_postcomments(Source),
@@ -1097,6 +1133,8 @@ join_comments(Source, Target) ->
%% @see set_ann/2
%% @see get_attrs/1
+-spec get_ann(syntaxTree()) -> [term()].
+
get_ann(#tree{attr = Attr}) -> Attr#attr.ann;
get_ann(#wrapper{attr = Attr}) -> Attr#attr.ann;
get_ann(_) -> [].
@@ -1113,6 +1151,8 @@ get_ann(_) -> [].
%% @see add_ann/2
%% @see copy_ann/2
+-spec set_ann(syntaxTree(), [term()]) -> syntaxTree().
+
set_ann(Node, As) ->
case Node of
#tree{attr = Attr} ->
@@ -1138,6 +1178,8 @@ set_ann(Node, As) ->
%% @see get_ann/1
%% @see set_ann/2
+-spec add_ann(term(), syntaxTree()) -> syntaxTree().
+
add_ann(A, Node) ->
case Node of
#tree{attr = Attr} ->
@@ -1164,6 +1206,8 @@ add_ann(A, Node) ->
%% @see get_ann/1
%% @see set_ann/2
+-spec copy_ann(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_ann(Source, Target) ->
set_ann(Target, get_ann(Source)).
@@ -1192,6 +1236,8 @@ copy_ann(Source, Target) ->
%% @see get_precomments/1
%% @see get_postcomments/1
+-spec get_attrs(syntaxTree()) -> syntaxTreeAttributes().
+
get_attrs(#tree{attr = Attr}) -> Attr;
get_attrs(#wrapper{attr = Attr}) -> Attr;
get_attrs(Node) -> #attr{pos = get_pos(Node),
@@ -1209,6 +1255,8 @@ get_attrs(Node) -> #attr{pos = get_pos(Node),
%% @see get_attrs/1
%% @see copy_attrs/2
+-spec set_attrs(syntaxTree(), syntaxTreeAttributes()) -> syntaxTree().
+
set_attrs(Node, Attr) ->
case Node of
#tree{} ->
@@ -1233,6 +1281,8 @@ set_attrs(Node, Attr) ->
%% @see get_attrs/1
%% @see set_attrs/2
+-spec copy_attrs(syntaxTree(), syntaxTree()) -> syntaxTree().
+
copy_attrs(S, T) ->
set_attrs(T, get_attrs(S)).
@@ -1241,6 +1291,8 @@ copy_attrs(S, T) ->
%% @spec comment(Strings) -> syntaxTree()
%% @equiv comment(none, Strings)
+-spec comment([string()]) -> syntaxTree().
+
comment(Strings) ->
comment(none, Strings).
@@ -1268,7 +1320,9 @@ comment(Strings) ->
%% @see comment/1
%% @see is_form/1
--record(comment, {pad, text}).
+-type padding() :: 'none' | integer().
+
+-record(comment, {pad :: padding(), text :: [string()]}).
%% type(Node) = comment
%% data(Node) = #comment{pad :: Padding, text :: Strings}
@@ -1276,6 +1330,8 @@ comment(Strings) ->
%% Padding = none | integer()
%% Strings = [string()]
+-spec comment(padding(), [string()]) -> syntaxTree().
+
comment(Pad, Strings) ->
tree(comment, #comment{pad = Pad, text = Strings}).
@@ -1287,6 +1343,8 @@ comment(Pad, Strings) ->
%%
%% @see comment/2
+-spec comment_text(syntaxTree()) -> [string()].
+
comment_text(Node) ->
(data(Node))#comment.text.
@@ -1300,6 +1358,8 @@ comment_text(Node) ->
%%
%% @see comment/2
+-spec comment_padding(syntaxTree()) -> padding().
+
comment_padding(Node) ->
(data(Node))#comment.pad.
@@ -1333,6 +1393,8 @@ comment_padding(Node) ->
%% Form = syntaxTree()
%% is_form(Form) = true
+-spec form_list([syntaxTree()]) -> syntaxTree().
+
form_list(Forms) ->
tree(form_list, Forms).
@@ -1344,6 +1406,8 @@ form_list(Forms) ->
%%
%% @see form_list/1
+-spec form_list_elements(syntaxTree()) -> [syntaxTree()].
+
form_list_elements(Node) ->
data(Node).
@@ -1358,6 +1422,8 @@ form_list_elements(Node) ->
%%
%% @see form_list/1
+-spec flatten_form_list(syntaxTree()) -> syntaxTree().
+
flatten_form_list(Node) ->
Fs = form_list_elements(Node),
Fs1 = lists:reverse(flatten_form_list_1(Fs, [])),
@@ -1389,6 +1455,8 @@ flatten_form_list_1([], As) ->
%% type(Node) = text
%% data(Node) = string()
+-spec text(string()) -> syntaxTree().
+
text(String) ->
tree(text, String).
@@ -1401,6 +1469,8 @@ text(String) ->
%%
%% @see text/1
+-spec text_string(syntaxTree()) -> string().
+
text_string(Node) ->
data(Node).
@@ -1432,6 +1502,8 @@ text_string(Node) ->
%%
%% Name = atom() \ '_'
+-spec variable(atom() | string()) -> syntaxTree().
+
variable(Name) when is_atom(Name) ->
tree(variable, Name);
variable(Name) ->
@@ -1450,6 +1522,8 @@ revert_variable(Node) ->
%%
%% @see variable/1
+-spec variable_name(syntaxTree()) -> atom().
+
variable_name(Node) ->
case unwrap(Node) of
{var, _, Name} ->
@@ -1466,6 +1540,8 @@ variable_name(Node) ->
%%
%% @see variable/1
+-spec variable_literal(syntaxTree()) -> string().
+
variable_literal(Node) ->
case unwrap(Node) of
{var, _, Name} ->
@@ -1491,6 +1567,8 @@ variable_literal(Node) ->
%%
%% {var, Pos, '_'}
+-spec underscore() -> syntaxTree().
+
underscore() ->
tree(underscore, []).
@@ -1518,6 +1596,8 @@ revert_underscore(Node) ->
%%
%% Value = integer()
+-spec integer(integer()) -> syntaxTree().
+
integer(Value) ->
tree(integer, Value).
@@ -1527,7 +1607,7 @@ revert_integer(Node) ->
%% =====================================================================
-%% @spec is_integer(Node::syntaxTree(), Value::integer()) -> bool()
+%% @spec is_integer(Node::syntaxTree(), Value::integer()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>integer</code> and represents <code>Value</code>, otherwise
@@ -1535,6 +1615,8 @@ revert_integer(Node) ->
%%
%% @see integer/1
+-spec is_integer(syntaxTree(), integer()) -> boolean().
+
is_integer(Node, Value) ->
case unwrap(Node) of
{integer, _, Value} ->
@@ -1553,6 +1635,8 @@ is_integer(Node, Value) ->
%%
%% @see integer/1
+-spec integer_value(syntaxTree()) -> integer().
+
integer_value(Node) ->
case unwrap(Node) of
{integer, _, Value} ->
@@ -1570,6 +1654,8 @@ integer_value(Node) ->
%%
%% @see integer/1
+-spec integer_literal(syntaxTree()) -> string().
+
integer_literal(Node) ->
integer_to_list(integer_value(Node)).
@@ -1600,6 +1686,8 @@ integer_literal(Node) ->
%% overridden by the type conversion BIF of the same name, so always use
%% `make_float/1' for local calls.
+-spec float(float()) -> syntaxTree().
+
float(Value) ->
make_float(Value).
@@ -1620,6 +1708,8 @@ revert_float(Node) ->
%%
%% @see float/1
+-spec float_value(syntaxTree()) -> float().
+
float_value(Node) ->
case unwrap(Node) of
{float, _, Value} ->
@@ -1637,6 +1727,8 @@ float_value(Node) ->
%%
%% @see float/1
+-spec float_literal(syntaxTree()) -> string().
+
float_literal(Node) ->
float_to_list(float_value(Node)).
@@ -1667,6 +1759,8 @@ float_literal(Node) ->
%%
%% Code = integer()
+-spec char(char()) -> syntaxTree().
+
char(Char) ->
tree(char, Char).
@@ -1676,7 +1770,7 @@ revert_char(Node) ->
%% =====================================================================
-%% @spec is_char(Node::syntaxTree(), Value::char()) -> bool()
+%% @spec is_char(Node::syntaxTree(), Value::char()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>char</code> and represents <code>Value</code>, otherwise
@@ -1684,6 +1778,8 @@ revert_char(Node) ->
%%
%% @see char/1
+-spec is_char(syntaxTree(), char()) -> boolean().
+
is_char(Node, Value) ->
case unwrap(Node) of
{char, _, Value} ->
@@ -1702,6 +1798,8 @@ is_char(Node, Value) ->
%%
%% @see char/1
+-spec char_value(syntaxTree()) -> char().
+
char_value(Node) ->
case unwrap(Node) of
{char, _, Char} ->
@@ -1719,6 +1817,8 @@ char_value(Node) ->
%%
%% @see char/1
+-spec char_literal(syntaxTree()) -> string().
+
char_literal(Node) ->
io_lib:write_char(char_value(Node)).
@@ -1749,6 +1849,8 @@ char_literal(Node) ->
%%
%% Chars = string()
+-spec string(string()) -> syntaxTree().
+
string(String) ->
tree(string, String).
@@ -1758,7 +1860,7 @@ revert_string(Node) ->
%% =====================================================================
-%% @spec is_string(Node::syntaxTree(), Value::string()) -> bool()
+%% @spec is_string(Node::syntaxTree(), Value::string()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>string</code> and represents <code>Value</code>, otherwise
@@ -1766,6 +1868,8 @@ revert_string(Node) ->
%%
%% @see string/1
+-spec is_string(syntaxTree(), string()) -> boolean().
+
is_string(Node, Value) ->
case unwrap(Node) of
{string, _, Value} ->
@@ -1784,6 +1888,8 @@ is_string(Node, Value) ->
%%
%% @see string/1
+-spec string_value(syntaxTree()) -> string().
+
string_value(Node) ->
case unwrap(Node) of
{string, _, List} ->
@@ -1801,6 +1907,8 @@ string_value(Node) ->
%%
%% @see string/1
+-spec string_literal(syntaxTree()) -> string().
+
string_literal(Node) ->
io_lib:write_string(string_value(Node)).
@@ -1826,6 +1934,8 @@ string_literal(Node) ->
%%
%% Value = atom()
+-spec atom(atom() | string()) -> syntaxTree().
+
atom(Name) when is_atom(Name) ->
tree(atom, Name);
atom(Name) ->
@@ -1837,7 +1947,7 @@ revert_atom(Node) ->
%% =====================================================================
-%% @spec is_atom(Node::syntaxTree(), Value::atom()) -> bool()
+%% @spec is_atom(Node::syntaxTree(), Value::atom()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>atom</code> and represents <code>Value</code>, otherwise
@@ -1845,6 +1955,8 @@ revert_atom(Node) ->
%%
%% @see atom/1
+-spec is_atom(syntaxTree(), atom()) -> boolean().
+
is_atom(Node, Value) ->
case unwrap(Node) of
{atom, _, Value} ->
@@ -1863,6 +1975,8 @@ is_atom(Node, Value) ->
%%
%% @see atom/1
+-spec atom_value(syntaxTree()) -> atom().
+
atom_value(Node) ->
case unwrap(Node) of
{atom, _, Name} ->
@@ -1879,6 +1993,8 @@ atom_value(Node) ->
%%
%% @see atom/1
+-spec atom_name(syntaxTree()) -> string().
+
atom_name(Node) ->
atom_to_list(atom_value(Node)).
@@ -1897,6 +2013,8 @@ atom_name(Node) ->
%% @see atom/1
%% @see string/1
+-spec atom_literal(syntaxTree()) -> string().
+
atom_literal(Node) ->
io_lib:write_atom(atom_value(Node)).
@@ -1925,6 +2043,8 @@ atom_literal(Node) ->
%%
%% Elements = [erl_parse()]
+-spec tuple([syntaxTree()]) -> syntaxTree().
+
tuple(List) ->
tree(tuple, List).
@@ -1941,6 +2061,8 @@ revert_tuple(Node) ->
%%
%% @see tuple/1
+-spec tuple_elements(syntaxTree()) -> [syntaxTree()].
+
tuple_elements(Node) ->
case unwrap(Node) of
{tuple, _, List} ->
@@ -1962,6 +2084,8 @@ tuple_elements(Node) ->
%% @see tuple/1
%% @see tuple_elements/1
+-spec tuple_size(syntaxTree()) -> non_neg_integer().
+
tuple_size(Node) ->
length(tuple_elements(Node)).
@@ -1970,6 +2094,8 @@ tuple_size(Node) ->
%% @spec list(List) -> syntaxTree()
%% @equiv list(List, none)
+-spec list([syntaxTree()]) -> syntaxTree().
+
list(List) ->
list(List, none).
@@ -2020,7 +2146,7 @@ list(List) ->
%% @see compact_list/1
%% @see get_attrs/1
--record(list, {prefix, suffix}).
+-record(list, {prefix :: [syntaxTree()], suffix :: 'none' | syntaxTree()}).
%% type(Node) = list
%% data(Node) = #list{prefix :: Elements, suffix :: Tail}
@@ -2038,9 +2164,11 @@ list(List) ->
%% <Suffix>]' where the form of <Suffix> can depend on the
%% structure of <Tail>; there is no fixed printed form.
+-spec list([syntaxTree()], 'none' | syntaxTree()) -> syntaxTree().
+
list([], none) ->
nil();
-list(Elements, Tail) when Elements /= [] ->
+list(Elements, Tail) when Elements =/= [] ->
tree(list, #list{prefix = Elements, suffix = Tail}).
revert_list(Node) ->
@@ -2073,6 +2201,8 @@ revert_list(Node) ->
%%
%% {nil, Pos}
+-spec nil() -> syntaxTree().
+
nil() ->
tree(nil).
@@ -2092,6 +2222,8 @@ revert_nil(Node) ->
%%
%% @see list/2
+-spec list_prefix(syntaxTree()) -> [syntaxTree()].
+
list_prefix(Node) ->
case unwrap(Node) of
{cons, _, Head, _} ->
@@ -2102,7 +2234,7 @@ list_prefix(Node) ->
%% =====================================================================
-%% @spec list_suffix(Node::syntaxTree()) -> none | syntaxTree()
+%% @spec list_suffix(Node::syntaxTree()) -> none | syntaxTree()
%%
%% @doc Returns the suffix subtree of a <code>list</code> node, if one
%% exists. If <code>Node</code> represents "<code>[<em>E1</em>, ...,
@@ -2121,6 +2253,8 @@ list_prefix(Node) ->
%% @see nil/0
%% @see compact_list/1
+-spec list_suffix(syntaxTree()) -> 'none' | syntaxTree().
+
list_suffix(Node) ->
case unwrap(Node) of
{cons, _, _, Tail} ->
@@ -2158,6 +2292,8 @@ list_suffix(Node) ->
%% @see list_head/1
%% @see list_tail/1
+-spec cons(syntaxTree(), syntaxTree()) -> syntaxTree().
+
cons(Head, Tail) ->
case type(Tail) of
list ->
@@ -2181,6 +2317,8 @@ cons(Head, Tail) ->
%% @see list_tail/1
%% @see cons/2
+-spec list_head(syntaxTree()) -> syntaxTree().
+
list_head(Node) ->
hd(list_prefix(Node)).
@@ -2202,6 +2340,8 @@ list_head(Node) ->
%% @see list_head/1
%% @see cons/2
+-spec list_tail(syntaxTree()) -> syntaxTree().
+
list_tail(Node) ->
Tail = list_suffix(Node),
case tl(list_prefix(Node)) of
@@ -2217,7 +2357,7 @@ list_tail(Node) ->
%% =====================================================================
-%% @spec is_list_skeleton(syntaxTree()) -> bool()
+%% @spec is_list_skeleton(syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> has type
%% <code>list</code> or <code>nil</code>, otherwise <code>false</code>.
@@ -2225,6 +2365,8 @@ list_tail(Node) ->
%% @see list/2
%% @see nil/0
+-spec is_list_skeleton(syntaxTree()) -> boolean().
+
is_list_skeleton(Node) ->
case type(Node) of
list -> true;
@@ -2234,7 +2376,7 @@ is_list_skeleton(Node) ->
%% =====================================================================
-%% @spec is_proper_list(Node::syntaxTree()) -> bool()
+%% @spec is_proper_list(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> represents a
%% proper list, and <code>false</code> otherwise. A proper list is a
@@ -2255,6 +2397,8 @@ is_list_skeleton(Node) ->
%%
%% @see list/2
+-spec is_proper_list(syntaxTree()) -> boolean().
+
is_proper_list(Node) ->
case type(Node) of
list ->
@@ -2284,6 +2428,8 @@ is_proper_list(Node) ->
%% @see list/2
%% @see is_proper_list/1
+-spec list_elements(syntaxTree()) -> [syntaxTree()].
+
list_elements(Node) ->
lists:reverse(list_elements(Node, [])).
@@ -2319,6 +2465,8 @@ list_elements(Node, As) ->
%% @see is_proper_list/1
%% @see list_elements/1
+-spec list_length(syntaxTree()) -> non_neg_integer().
+
list_length(Node) ->
list_length(Node, 0).
@@ -2354,6 +2502,8 @@ list_length(Node, A) ->
%% @see list/2
%% @see compact_list/1
+-spec normalize_list(syntaxTree()) -> syntaxTree().
+
normalize_list(Node) ->
case type(Node) of
list ->
@@ -2391,6 +2541,8 @@ normalize_list_1(Es, Tail) ->
%% @see list/2
%% @see normalize_list/1
+-spec compact_list(syntaxTree()) -> syntaxTree().
+
compact_list(Node) ->
case type(Node) of
list ->
@@ -2447,6 +2599,8 @@ compact_list(Node) ->
%% See `binary_field' for documentation on `erl_parse' binary
%% fields (or "elements").
+-spec binary([syntaxTree()]) -> syntaxTree().
+
binary(List) ->
tree(binary, List).
@@ -2464,6 +2618,8 @@ revert_binary(Node) ->
%% @see binary/1
%% @see binary_field/2
+-spec binary_fields(syntaxTree()) -> [syntaxTree()].
+
binary_fields(Node) ->
case unwrap(Node) of
{bin, _, List} ->
@@ -2477,6 +2633,8 @@ binary_fields(Node) ->
%% @spec binary_field(Body) -> syntaxTree()
%% @equiv binary_field(Body, [])
+-spec binary_field(syntaxTree()) -> syntaxTree().
+
binary_field(Body) ->
binary_field(Body, []).
@@ -2498,6 +2656,9 @@ binary_field(Body) ->
%% @see binary_field/2
%% @see size_qualifier/2
+-spec binary_field(syntaxTree(), 'none' | syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
binary_field(Body, none, Types) ->
binary_field(Body, Types);
binary_field(Body, Size, Types) ->
@@ -2521,13 +2682,13 @@ binary_field(Body, Size, Types) ->
%% @see binary_field_types/1
%% @see binary_field_size/1
--record(binary_field, {body, types}).
+-record(binary_field, {body :: syntaxTree(), types :: [syntaxTree()]}).
%% type(Node) = binary_field
%% data(Node) = #binary_field{body :: Body, types :: Types}
%%
%% Body = syntaxTree()
-%% Types = [Type]
+%% Types = [syntaxTree()]
%%
%% `erl_parse' representation:
%%
@@ -2538,6 +2699,8 @@ binary_field(Body, Size, Types) ->
%% TypeList = default | [Type] \ []
%% Type = atom() | {atom(), integer()}
+-spec binary_field(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
binary_field(Body, Types) ->
tree(binary_field, #binary_field{body = Body, types = Types}).
@@ -2569,6 +2732,8 @@ revert_binary_field(Node) ->
%%
%% @see binary_field/2
+-spec binary_field_body(syntaxTree()) -> syntaxTree().
+
binary_field_body(Node) ->
case unwrap(Node) of
{bin_element, _, Body, Size, _} ->
@@ -2592,6 +2757,8 @@ binary_field_body(Node) ->
%%
%% @see binary_field/2
+-spec binary_field_types(syntaxTree()) -> [syntaxTree()].
+
binary_field_types(Node) ->
case unwrap(Node) of
{bin_element, Pos, _, _, Types} ->
@@ -2620,6 +2787,8 @@ binary_field_types(Node) ->
%% @see binary_field/2
%% @see binary_field/3
+-spec binary_field_size(syntaxTree()) -> 'none' | syntaxTree().
+
binary_field_size(Node) ->
case unwrap(Node) of
{bin_element, _, _, Size, _} ->
@@ -2649,13 +2818,15 @@ binary_field_size(Node) ->
%% @see size_qualifier_body/1
%% @see size_qualifier_argument/1
--record(size_qualifier, {body, size}).
+-record(size_qualifier, {body :: syntaxTree(), size :: syntaxTree()}).
%% type(Node) = size_qualifier
%% data(Node) = #size_qualifier{body :: Body, size :: Size}
%%
%% Body = Size = syntaxTree()
+-spec size_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
size_qualifier(Body, Size) ->
tree(size_qualifier,
#size_qualifier{body = Body, size = Size}).
@@ -2669,6 +2840,8 @@ size_qualifier(Body, Size) ->
%%
%% @see size_qualifier/2
+-spec size_qualifier_body(syntaxTree()) -> syntaxTree().
+
size_qualifier_body(Node) ->
(data(Node))#size_qualifier.body.
@@ -2681,6 +2854,8 @@ size_qualifier_body(Node) ->
%%
%% @see size_qualifier/2
+-spec size_qualifier_argument(syntaxTree()) -> syntaxTree().
+
size_qualifier_argument(Node) ->
(data(Node))#size_qualifier.size.
@@ -2714,6 +2889,8 @@ size_qualifier_argument(Node) ->
%% Note that there is no position information for the node
%% itself: `get_pos' and `set_pos' handle this as a special case.
+-spec error_marker(term()) -> syntaxTree().
+
error_marker(Error) ->
tree(error_marker, Error).
@@ -2731,6 +2908,8 @@ revert_error_marker(Node) ->
%%
%% @see error_marker/1
+-spec error_marker_info(syntaxTree()) -> term().
+
error_marker_info(Node) ->
case unwrap(Node) of
{error, Error} ->
@@ -2769,6 +2948,8 @@ error_marker_info(Node) ->
%% Note that there is no position information for the node
%% itself: `get_pos' and `set_pos' handle this as a special case.
+-spec warning_marker(term()) -> syntaxTree().
+
warning_marker(Warning) ->
tree(warning_marker, Warning).
@@ -2786,6 +2967,8 @@ revert_warning_marker(Node) ->
%%
%% @see warning_marker/1
+-spec warning_marker_info(syntaxTree()) -> term().
+
warning_marker_info(Node) ->
case unwrap(Node) of
{warning, Error} ->
@@ -2818,6 +3001,8 @@ warning_marker_info(Node) ->
%%
%% {eof, Pos}
+-spec eof_marker() -> syntaxTree().
+
eof_marker() ->
tree(eof_marker).
@@ -2830,6 +3015,8 @@ revert_eof_marker(Node) ->
%% @spec attribute(Name) -> syntaxTree()
%% @equiv attribute(Name, none)
+-spec attribute(syntaxTree()) -> syntaxTree().
+
attribute(Name) ->
attribute(Name, none).
@@ -2859,7 +3046,7 @@ attribute(Name) ->
%% @see text/1
%% @see is_form/1
--record(attribute, {name, args}).
+-record(attribute, {name :: syntaxTree(), args :: 'none' | [syntaxTree()]}).
%% type(Node) = attribute
%% data(Node) = #attribute{name :: Name, args :: Arguments}
@@ -2922,6 +3109,8 @@ attribute(Name) ->
%%
%% Representing `-Name(Term).'.
+-spec attribute(syntaxTree(), 'none' | [syntaxTree()]) -> syntaxTree().
+
attribute(Name, Args) ->
tree(attribute, #attribute{name = Name, args = Args}).
@@ -3049,6 +3238,8 @@ revert_module_name(A) ->
%%
%% @see attribute/1
+-spec attribute_name(syntaxTree()) -> syntaxTree().
+
attribute_name(Node) ->
case unwrap(Node) of
{attribute, Pos, Name, _} ->
@@ -3071,6 +3262,8 @@ attribute_name(Node) ->
%%
%% @see attribute/1
+-spec attribute_arguments(syntaxTree()) -> none | [syntaxTree()].
+
attribute_arguments(Node) ->
case unwrap(Node) of
{attribute, Pos, Name, Data} ->
@@ -3141,13 +3334,15 @@ attribute_arguments(Node) ->
%% @see arity_qualifier_body/1
%% @see arity_qualifier_argument/1
--record(arity_qualifier, {body, arity}).
+-record(arity_qualifier, {body :: syntaxTree(), arity :: syntaxTree()}).
%% type(Node) = arity_qualifier
%% data(Node) = #arity_qualifier{body :: Body, arity :: Arity}
%%
%% Body = Arity = syntaxTree()
+-spec arity_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
arity_qualifier(Body, Arity) ->
tree(arity_qualifier,
#arity_qualifier{body = Body, arity = Arity}).
@@ -3161,6 +3356,8 @@ arity_qualifier(Body, Arity) ->
%%
%% @see arity_qualifier/2
+-spec arity_qualifier_body(syntaxTree()) -> syntaxTree().
+
arity_qualifier_body(Node) ->
(data(Node))#arity_qualifier.body.
@@ -3173,6 +3370,8 @@ arity_qualifier_body(Node) ->
%%
%% @see arity_qualifier/2
+-spec arity_qualifier_argument(syntaxTree()) -> syntaxTree().
+
arity_qualifier_argument(Node) ->
(data(Node))#arity_qualifier.arity.
@@ -3187,7 +3386,7 @@ arity_qualifier_argument(Node) ->
%% @see module_qualifier_argument/1
%% @see module_qualifier_body/1
--record(module_qualifier, {module, body}).
+-record(module_qualifier, {module :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = module_qualifier
%% data(Node) = #module_qualifier{module :: Module, body :: Body}
@@ -3200,6 +3399,8 @@ arity_qualifier_argument(Node) ->
%%
%% Module = Arg = erl_parse()
+-spec module_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
module_qualifier(Module, Body) ->
tree(module_qualifier,
#module_qualifier{module = Module, body = Body}).
@@ -3219,6 +3420,8 @@ revert_module_qualifier(Node) ->
%%
%% @see module_qualifier/2
+-spec module_qualifier_argument(syntaxTree()) -> syntaxTree().
+
module_qualifier_argument(Node) ->
case unwrap(Node) of
{remote, _, Module, _} ->
@@ -3236,6 +3439,8 @@ module_qualifier_argument(Node) ->
%%
%% @see module_qualifier/2
+-spec module_qualifier_body(syntaxTree()) -> syntaxTree().
+
module_qualifier_body(Node) ->
case unwrap(Node) of
{remote, _, _, Body} ->
@@ -3267,6 +3472,8 @@ module_qualifier_body(Node) ->
%% represents a Mnemosyne query record field access ('record_access');
%% see type/1 for details.
+-spec qualified_name([syntaxTree()]) -> syntaxTree().
+
qualified_name(Segments) ->
tree(qualified_name, Segments).
@@ -3283,6 +3490,8 @@ revert_qualified_name(Node) ->
%%
%% @see qualified_name/1
+-spec qualified_name_segments(syntaxTree()) -> [syntaxTree()].
+
qualified_name_segments(Node) ->
case unwrap(Node) of
{record_field, _, _, _} = Node1 ->
@@ -3314,6 +3523,9 @@ qualified_name_segments(Node) ->
%% @see rule/2
-record(function, {name, clauses}).
+%% XXX: This one is problematic because there is a tuple with the same
+%% tag and size that comes from 'erl_parse'
+%% -record(function, {name :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = function
%% data(Node) = #function{name :: Name, clauses :: Clauses}
@@ -3340,6 +3552,8 @@ qualified_name_segments(Node) ->
%% the integer `Arity'; see `clause' for documentation on
%% `erl_parse' clauses.
+-spec function(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
function(Name, Clauses) ->
tree(function, #function{name = Name, clauses = Clauses}).
@@ -3363,6 +3577,8 @@ revert_function(Node) ->
%%
%% @see function/2
+-spec function_name(syntaxTree()) -> syntaxTree().
+
function_name(Node) ->
case unwrap(Node) of
{function, Pos, Name, _, _} ->
@@ -3380,6 +3596,8 @@ function_name(Node) ->
%%
%% @see function/2
+-spec function_clauses(syntaxTree()) -> [syntaxTree()].
+
function_clauses(Node) ->
case unwrap(Node) of
{function, _, _, _, Clauses} ->
@@ -3406,6 +3624,8 @@ function_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec function_arity(syntaxTree()) -> arity().
+
function_arity(Node) ->
%% Note that this never accesses the arity field of `erl_parse'
%% function nodes.
@@ -3416,6 +3636,10 @@ function_arity(Node) ->
%% @spec clause(Guard, Body) -> syntaxTree()
%% @equiv clause([], Guard, Body)
+-type guard() :: 'none' | syntaxTree() | [syntaxTree()] | [[syntaxTree()]].
+
+-spec clause(guard(), [syntaxTree()]) -> syntaxTree().
+
clause(Guard, Body) ->
clause([], Guard, Body).
@@ -3455,7 +3679,9 @@ clause(Guard, Body) ->
%% @see clause_guard/1
%% @see clause_body/1
--record(clause, {patterns, guard, body}).
+-record(clause, {patterns :: [syntaxTree()],
+ guard :: guard(),
+ body :: [syntaxTree()]}).
%% type(Node) = clause
%% data(Node) = #clause{patterns :: Patterns, guard :: Guard,
@@ -3482,6 +3708,8 @@ clause(Guard, Body) ->
%% versions, `Guard' was simply a list `[E1, ..., En]' of parse
%% trees, which is equivalent to the new form `[[E1, ..., En]]'.
+-spec clause([syntaxTree()], guard(), [syntaxTree()]) -> syntaxTree().
+
clause(Patterns, Guard, Body) ->
Guard1 = case Guard of
[] ->
@@ -3551,7 +3779,7 @@ fold_try_clause({clause, Pos, [P], Guard, Body}) ->
unfold_try_clauses(Cs) ->
[unfold_try_clause(C) || C <- Cs].
-unfold_try_clause({clause, Pos, [{tuple, _, [{atom,_,throw}, V, _]}],
+unfold_try_clause({clause, Pos, [{tuple, _, [{atom, _, throw}, V, _]}],
Guard, Body}) ->
{clause, Pos, [V], Guard, Body};
unfold_try_clause({clause, Pos, [{tuple, _, [C, V, _]}],
@@ -3567,6 +3795,8 @@ unfold_try_clause({clause, Pos, [{tuple, _, [C, V, _]}],
%%
%% @see clause/3
+-spec clause_patterns(syntaxTree()) -> [syntaxTree()].
+
clause_patterns(Node) ->
case unwrap(Node) of
{clause, _, Patterns, _, _} ->
@@ -3587,6 +3817,8 @@ clause_patterns(Node) ->
%%
%% @see clause/3
+-spec clause_guard(syntaxTree()) -> 'none' | syntaxTree().
+
clause_guard(Node) ->
case unwrap(Node) of
{clause, _, _, Guard, _} ->
@@ -3610,6 +3842,8 @@ clause_guard(Node) ->
%%
%% @see clause/3
+-spec clause_body(syntaxTree()) -> [syntaxTree()].
+
clause_body(Node) ->
case unwrap(Node) of
{clause, _, _, _, Body} ->
@@ -3632,6 +3866,8 @@ clause_body(Node) ->
%% type(Node) = disjunction
%% data(Node) = [syntaxTree()]
+-spec disjunction([syntaxTree()]) -> syntaxTree().
+
disjunction(Tests) ->
tree(disjunction, Tests).
@@ -3644,6 +3880,8 @@ disjunction(Tests) ->
%%
%% @see disjunction/1
+-spec disjunction_body(syntaxTree()) -> [syntaxTree()].
+
disjunction_body(Node) ->
data(Node).
@@ -3661,6 +3899,8 @@ disjunction_body(Node) ->
%% type(Node) = conjunction
%% data(Node) = [syntaxTree()]
+-spec conjunction([syntaxTree()]) -> syntaxTree().
+
conjunction(Tests) ->
tree(conjunction, Tests).
@@ -3673,6 +3913,8 @@ conjunction(Tests) ->
%%
%% @see conjunction/1
+-spec conjunction_body(syntaxTree()) -> [syntaxTree()].
+
conjunction_body(Node) ->
data(Node).
@@ -3694,6 +3936,8 @@ conjunction_body(Node) ->
%%
%% Expr = erl_parse()
+-spec catch_expr(syntaxTree()) -> syntaxTree().
+
catch_expr(Expr) ->
tree(catch_expr, Expr).
@@ -3710,6 +3954,8 @@ revert_catch_expr(Node) ->
%%
%% @see catch_expr/1
+-spec catch_expr_body(syntaxTree()) -> syntaxTree().
+
catch_expr_body(Node) ->
case unwrap(Node) of
{'catch', _, Expr} ->
@@ -3729,7 +3975,7 @@ catch_expr_body(Node) ->
%% @see match_expr_pattern/1
%% @see match_expr_body/1
--record(match_expr, {pattern, body}).
+-record(match_expr, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = match_expr
%% data(Node) = #match_expr{pattern :: Pattern, body :: Body}
@@ -3742,6 +3988,8 @@ catch_expr_body(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec match_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
match_expr(Pattern, Body) ->
tree(match_expr, #match_expr{pattern = Pattern, body = Body}).
@@ -3759,6 +4007,8 @@ revert_match_expr(Node) ->
%%
%% @see match_expr/2
+-spec match_expr_pattern(syntaxTree()) -> syntaxTree().
+
match_expr_pattern(Node) ->
case unwrap(Node) of
{match, _, Pattern, _} ->
@@ -3775,6 +4025,8 @@ match_expr_pattern(Node) ->
%%
%% @see match_expr/2
+-spec match_expr_body(syntaxTree()) -> syntaxTree().
+
match_expr_body(Node) ->
case unwrap(Node) of
{match, _, _, Body} ->
@@ -3802,6 +4054,8 @@ match_expr_body(Node) ->
%% type(Node) = operator
%% data(Node) = atom()
+-spec operator(atom() | string()) -> syntaxTree().
+
operator(Name) when is_atom(Name) ->
tree(operator, Name);
operator(Name) ->
@@ -3816,6 +4070,8 @@ operator(Name) ->
%%
%% @see operator/1
+-spec operator_name(syntaxTree()) -> atom().
+
operator_name(Node) ->
data(Node).
@@ -3829,6 +4085,8 @@ operator_name(Node) ->
%%
%% @see operator/1
+-spec operator_literal(syntaxTree()) -> string().
+
operator_literal(Node) ->
atom_to_list(operator_name(Node)).
@@ -3846,7 +4104,9 @@ operator_literal(Node) ->
%% @see infix_expr_operator/1
%% @see prefix_expr/2
--record(infix_expr, {operator, left, right}).
+-record(infix_expr, {operator :: syntaxTree(),
+ left :: syntaxTree(),
+ right :: syntaxTree()}).
%% type(Node) = infix_expr
%% data(Node) = #infix_expr{left :: Left, operator :: Operator,
@@ -3861,6 +4121,8 @@ operator_literal(Node) ->
%% Operator = atom()
%% Left = Right = erl_parse()
+-spec infix_expr(syntaxTree(), syntaxTree(), syntaxTree()) -> syntaxTree().
+
infix_expr(Left, Operator, Right) ->
tree(infix_expr, #infix_expr{operator = Operator, left = Left,
right = Right}).
@@ -3888,6 +4150,8 @@ revert_infix_expr(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_left(syntaxTree()) -> syntaxTree().
+
infix_expr_left(Node) ->
case unwrap(Node) of
{op, _, _, Left, _} ->
@@ -3905,6 +4169,8 @@ infix_expr_left(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_operator(syntaxTree()) -> syntaxTree().
+
infix_expr_operator(Node) ->
case unwrap(Node) of
{op, Pos, Operator, _, _} ->
@@ -3922,6 +4188,8 @@ infix_expr_operator(Node) ->
%%
%% @see infix_expr/3
+-spec infix_expr_right(syntaxTree()) -> syntaxTree().
+
infix_expr_right(Node) ->
case unwrap(Node) of
{op, _, _, _, Right} ->
@@ -3942,7 +4210,7 @@ infix_expr_right(Node) ->
%% @see prefix_expr_operator/1
%% @see infix_expr/3
--record(prefix_expr, {operator, argument}).
+-record(prefix_expr, {operator :: syntaxTree(), argument :: syntaxTree()}).
%% type(Node) = prefix_expr
%% data(Node) = #prefix_expr{operator :: Operator,
@@ -3957,6 +4225,8 @@ infix_expr_right(Node) ->
%% Operator = atom()
%% Argument = erl_parse()
+-spec prefix_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
prefix_expr(Operator, Argument) ->
tree(prefix_expr, #prefix_expr{operator = Operator,
argument = Argument}).
@@ -3983,6 +4253,8 @@ revert_prefix_expr(Node) ->
%%
%% @see prefix_expr/2
+-spec prefix_expr_operator(syntaxTree()) -> syntaxTree().
+
prefix_expr_operator(Node) ->
case unwrap(Node) of
{op, Pos, Operator, _} ->
@@ -4000,6 +4272,8 @@ prefix_expr_operator(Node) ->
%%
%% @see prefix_expr/2
+-spec prefix_expr_argument(syntaxTree()) -> syntaxTree().
+
prefix_expr_argument(Node) ->
case unwrap(Node) of
{op, _, _, Argument} ->
@@ -4013,6 +4287,8 @@ prefix_expr_argument(Node) ->
%% @spec record_field(Name) -> syntaxTree()
%% @equiv record_field(Name, none)
+-spec record_field(syntaxTree()) -> syntaxTree().
+
record_field(Name) ->
record_field(Name, none).
@@ -4030,13 +4306,15 @@ record_field(Name) ->
%% @see record_field_value/1
%% @see record_expr/3
--record(record_field, {name, value}).
+-record(record_field, {name :: syntaxTree(), value :: 'none' | syntaxTree()}).
%% type(Node) = record_field
%% data(Node) = #record_field{name :: Name, value :: Value}
%%
%% Name = Value = syntaxTree()
+-spec record_field(syntaxTree(), 'none' | syntaxTree()) -> syntaxTree().
+
record_field(Name, Value) ->
tree(record_field, #record_field{name = Name, value = Value}).
@@ -4048,6 +4326,8 @@ record_field(Name, Value) ->
%%
%% @see record_field/2
+-spec record_field_name(syntaxTree()) -> syntaxTree().
+
record_field_name(Node) ->
(data(Node))#record_field.name.
@@ -4064,6 +4344,8 @@ record_field_name(Node) ->
%%
%% @see record_field/2
+-spec record_field_value(syntaxTree()) -> 'none' | syntaxTree().
+
record_field_value(Node) ->
(data(Node))#record_field.value.
@@ -4083,7 +4365,7 @@ record_field_value(Node) ->
%% @see record_index_expr_field/1
%% @see record_expr/3
--record(record_index_expr, {type, field}).
+-record(record_index_expr, {type :: syntaxTree(), field :: syntaxTree()}).
%% type(Node) = record_index_expr
%% data(Node) = #record_index_expr{type :: Type, field :: Field}
@@ -4097,6 +4379,8 @@ record_field_value(Node) ->
%% Type = atom()
%% Field = erl_parse()
+-spec record_index_expr(syntaxTree(), syntaxTree()) -> syntaxTree().
+
record_index_expr(Type, Field) ->
tree(record_index_expr, #record_index_expr{type = Type,
field = Field}).
@@ -4121,6 +4405,8 @@ revert_record_index_expr(Node) ->
%%
%% @see record_index_expr/2
+-spec record_index_expr_type(syntaxTree()) -> syntaxTree().
+
record_index_expr_type(Node) ->
case unwrap(Node) of
{record_index, Pos, Type, _} ->
@@ -4138,6 +4424,8 @@ record_index_expr_type(Node) ->
%%
%% @see record_index_expr/2
+-spec record_index_expr_field(syntaxTree()) -> syntaxTree().
+
record_index_expr_field(Node) ->
case unwrap(Node) of
{record_index, _, _, Field} ->
@@ -4151,6 +4439,8 @@ record_index_expr_field(Node) ->
%% @spec record_access(Argument, Field) -> syntaxTree()
%% @equiv record_access(Argument, none, Field)
+-spec record_access(syntaxTree(), syntaxTree()) -> syntaxTree().
+
record_access(Argument, Field) ->
record_access(Argument, none, Field).
@@ -4175,7 +4465,9 @@ record_access(Argument, Field) ->
%% @see record_expr/3
%% @see query_expr/1
--record(record_access, {argument, type, field}).
+-record(record_access, {argument :: syntaxTree(),
+ type :: 'none' | syntaxTree(),
+ field :: syntaxTree()}).
%% type(Node) = record_access
%% data(Node) = #record_access{argument :: Argument, type :: Type,
@@ -4192,6 +4484,9 @@ record_access(Argument, Field) ->
%% Argument = Field = erl_parse()
%% Type = atom()
+-spec record_access(syntaxTree(), 'none' | syntaxTree(), syntaxTree()) ->
+ syntaxTree().
+
record_access(Argument, Type, Field) ->
tree(record_access,#record_access{argument = Argument,
type = Type,
@@ -4223,6 +4518,8 @@ revert_record_access(Node) ->
%%
%% @see record_access/3
+-spec record_access_argument(syntaxTree()) -> syntaxTree().
+
record_access_argument(Node) ->
case unwrap(Node) of
{record_field, _, Argument, _} ->
@@ -4246,6 +4543,8 @@ record_access_argument(Node) ->
%%
%% @see record_access/3
+-spec record_access_type(syntaxTree()) -> 'none' | syntaxTree().
+
record_access_type(Node) ->
case unwrap(Node) of
{record_field, _, _, _} ->
@@ -4265,6 +4564,8 @@ record_access_type(Node) ->
%%
%% @see record_access/3
+-spec record_access_field(syntaxTree()) -> syntaxTree().
+
record_access_field(Node) ->
case unwrap(Node) of
{record_field, _, _, Field} ->
@@ -4280,6 +4581,8 @@ record_access_field(Node) ->
%% @spec record_expr(Type, Fields) -> syntaxTree()
%% @equiv record_expr(none, Type, Fields)
+-spec record_expr(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
record_expr(Type, Fields) ->
record_expr(none, Type, Fields).
@@ -4305,7 +4608,9 @@ record_expr(Type, Fields) ->
%% @see record_index_expr/2
%% @see record_access/3
--record(record_expr, {argument, type, fields}).
+-record(record_expr, {argument :: 'none' | syntaxTree(),
+ type :: syntaxTree(),
+ fields :: [syntaxTree()]}).
%% type(Node) = record_expr
%% data(Node) = #record_expr{argument :: Argument, type :: Type,
@@ -4327,6 +4632,9 @@ record_expr(Type, Fields) ->
%% | {record_field, Pos, Field}
%% Field = Value = erl_parse()
+-spec record_expr('none' | syntaxTree(), syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
record_expr(Argument, Type, Fields) ->
tree(record_expr, #record_expr{argument = Argument,
type = Type, fields = Fields}).
@@ -4363,6 +4671,8 @@ revert_record_expr(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_argument(syntaxTree()) -> 'none' | syntaxTree().
+
record_expr_argument(Node) ->
case unwrap(Node) of
{record, _, _, _} ->
@@ -4381,6 +4691,8 @@ record_expr_argument(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_type(syntaxTree()) -> syntaxTree().
+
record_expr_type(Node) ->
case unwrap(Node) of
{record, Pos, Type, _} ->
@@ -4400,6 +4712,8 @@ record_expr_type(Node) ->
%%
%% @see record_expr/3
+-spec record_expr_fields(syntaxTree()) -> [syntaxTree()].
+
record_expr_fields(Node) ->
case unwrap(Node) of
{record, _, _, Fields} ->
@@ -4427,6 +4741,9 @@ record_expr_fields(Node) ->
%% @see application/2
%% @see module_qualifier/2
+-spec application('none' | syntaxTree(), syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
application(none, Name, Arguments) ->
application(Name, Arguments);
application(Module, Name, Arguments) ->
@@ -4446,7 +4763,7 @@ application(Module, Name, Arguments) ->
%% @see application_arguments/1
%% @see application/3
--record(application, {operator, arguments}).
+-record(application, {operator :: syntaxTree(), arguments :: [syntaxTree()]}).
%% type(Node) = application
%% data(Node) = #application{operator :: Operator,
@@ -4462,6 +4779,8 @@ application(Module, Name, Arguments) ->
%% Operator = erl_parse()
%% Arguments = [erl_parse()]
+-spec application(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
application(Operator, Arguments) ->
tree(application, #application{operator = Operator,
arguments = Arguments}).
@@ -4486,6 +4805,8 @@ revert_application(Node) ->
%% @see application/2
%% @see module_qualifier/2
+-spec application_operator(syntaxTree()) -> syntaxTree().
+
application_operator(Node) ->
case unwrap(Node) of
{call, _, Operator, _} ->
@@ -4503,6 +4824,8 @@ application_operator(Node) ->
%%
%% @see application/2
+-spec application_arguments(syntaxTree()) -> [syntaxTree()].
+
application_arguments(Node) ->
case unwrap(Node) of
{call, _, _, Arguments} ->
@@ -4524,7 +4847,7 @@ application_arguments(Node) ->
%% @see list_comp_body/1
%% @see generator/2
--record(list_comp, {template, body}).
+-record(list_comp, {template :: syntaxTree(), body :: [syntaxTree()]}).
%% type(Node) = list_comp
%% data(Node) = #list_comp{template :: Template, body :: Body}
@@ -4539,6 +4862,8 @@ application_arguments(Node) ->
%% Template = erl_parse()
%% Body = [erl_parse()] \ []
+-spec list_comp(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
list_comp(Template, Body) ->
tree(list_comp, #list_comp{template = Template, body = Body}).
@@ -4556,6 +4881,8 @@ revert_list_comp(Node) ->
%%
%% @see list_comp/2
+-spec list_comp_template(syntaxTree()) -> syntaxTree().
+
list_comp_template(Node) ->
case unwrap(Node) of
{lc, _, Template, _} ->
@@ -4573,6 +4900,8 @@ list_comp_template(Node) ->
%%
%% @see list_comp/2
+-spec list_comp_body(syntaxTree()) -> [syntaxTree()].
+
list_comp_body(Node) ->
case unwrap(Node) of
{lc, _, _, Body} ->
@@ -4593,7 +4922,7 @@ list_comp_body(Node) ->
%% @see binary_comp_body/1
%% @see generator/2
--record(binary_comp, {template, body}).
+-record(binary_comp, {template :: syntaxTree(), body :: [syntaxTree()]}).
%% type(Node) = binary_comp
%% data(Node) = #binary_comp{template :: Template, body :: Body}
@@ -4608,6 +4937,8 @@ list_comp_body(Node) ->
%% Template = erl_parse()
%% Body = [erl_parse()] \ []
+-spec binary_comp(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
binary_comp(Template, Body) ->
tree(binary_comp, #binary_comp{template = Template, body = Body}).
@@ -4625,6 +4956,8 @@ revert_binary_comp(Node) ->
%%
%% @see binary_comp/2
+-spec binary_comp_template(syntaxTree()) -> syntaxTree().
+
binary_comp_template(Node) ->
case unwrap(Node) of
{bc, _, Template, _} ->
@@ -4642,6 +4975,8 @@ binary_comp_template(Node) ->
%%
%% @see binary_comp/2
+-spec binary_comp_body(syntaxTree()) -> [syntaxTree()].
+
binary_comp_body(Node) ->
case unwrap(Node) of
{bc, _, _, Body} ->
@@ -4670,6 +5005,8 @@ binary_comp_body(Node) ->
%%
%% Body = erl_parse()
+-spec query_expr(syntaxTree()) -> syntaxTree().
+
query_expr(Body) ->
tree(query_expr, Body).
@@ -4686,6 +5023,8 @@ revert_query_expr(Node) ->
%%
%% @see query_expr/1
+-spec query_expr_body(syntaxTree()) -> syntaxTree().
+
query_expr_body(Node) ->
case unwrap(Node) of
{'query', _, Body} ->
@@ -4715,7 +5054,7 @@ query_expr_body(Node) ->
%% @see is_form/1
%% @see function/2
--record(rule, {name, clauses}).
+-record(rule, {name :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = rule
%% data(Node) = #rule{name :: Name, clauses :: Clauses}
@@ -4738,6 +5077,8 @@ query_expr_body(Node) ->
%% the integer `Arity'; see `clause' for documentation on
%% `erl_parse' clauses.
+-spec rule(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
rule(Name, Clauses) ->
tree(rule, #rule{name = Name, clauses = Clauses}).
@@ -4761,6 +5102,8 @@ revert_rule(Node) ->
%%
%% @see rule/2
+-spec rule_name(syntaxTree()) -> syntaxTree().
+
rule_name(Node) ->
case unwrap(Node) of
{rule, Pos, Name, _, _} ->
@@ -4776,6 +5119,8 @@ rule_name(Node) ->
%%
%% @see rule/2
+-spec rule_clauses(syntaxTree()) -> [syntaxTree()].
+
rule_clauses(Node) ->
case unwrap(Node) of
{rule, _, _, _, Clauses} ->
@@ -4801,6 +5146,8 @@ rule_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec rule_arity(syntaxTree()) -> arity().
+
rule_arity(Node) ->
%% Note that this never accesses the arity field of
%% `erl_parse' rule nodes.
@@ -4819,7 +5166,7 @@ rule_arity(Node) ->
%% @see list_comp/2
%% @see binary_comp/2
--record(generator, {pattern, body}).
+-record(generator, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = generator
%% data(Node) = #generator{pattern :: Pattern, body :: Body}
@@ -4832,6 +5179,8 @@ rule_arity(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec generator(syntaxTree(), syntaxTree()) -> syntaxTree().
+
generator(Pattern, Body) ->
tree(generator, #generator{pattern = Pattern, body = Body}).
@@ -4849,6 +5198,8 @@ revert_generator(Node) ->
%%
%% @see generator/2
+-spec generator_pattern(syntaxTree()) -> syntaxTree().
+
generator_pattern(Node) ->
case unwrap(Node) of
{generate, _, Pattern, _} ->
@@ -4865,6 +5216,8 @@ generator_pattern(Node) ->
%%
%% @see generator/2
+-spec generator_body(syntaxTree()) -> syntaxTree().
+
generator_body(Node) ->
case unwrap(Node) of
{generate, _, _, Body} ->
@@ -4886,7 +5239,7 @@ generator_body(Node) ->
%% @see list_comp/2
%% @see binary_comp/2
--record(binary_generator, {pattern, body}).
+-record(binary_generator, {pattern :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = binary_generator
%% data(Node) = #binary_generator{pattern :: Pattern, body :: Body}
@@ -4899,6 +5252,8 @@ generator_body(Node) ->
%%
%% Pattern = Body = erl_parse()
+-spec binary_generator(syntaxTree(), syntaxTree()) -> syntaxTree().
+
binary_generator(Pattern, Body) ->
tree(binary_generator, #binary_generator{pattern = Pattern, body = Body}).
@@ -4916,6 +5271,8 @@ revert_binary_generator(Node) ->
%%
%% @see binary_generator/2
+-spec binary_generator_pattern(syntaxTree()) -> syntaxTree().
+
binary_generator_pattern(Node) ->
case unwrap(Node) of
{b_generate, _, Pattern, _} ->
@@ -4932,6 +5289,8 @@ binary_generator_pattern(Node) ->
%%
%% @see binary_generator/2
+-spec binary_generator_body(syntaxTree()) -> syntaxTree().
+
binary_generator_body(Node) ->
case unwrap(Node) of
{b_generate, _, _, Body} ->
@@ -4940,6 +5299,7 @@ binary_generator_body(Node) ->
(data(Node1))#binary_generator.body
end.
+
%% =====================================================================
%% @spec block_expr(Body::[syntaxTree()]) -> syntaxTree()
%%
@@ -4960,6 +5320,8 @@ binary_generator_body(Node) ->
%%
%% Body = [erl_parse()] \ []
+-spec block_expr(Body::[syntaxTree()]) -> syntaxTree().
+
block_expr(Body) ->
tree(block_expr, Body).
@@ -4977,6 +5339,8 @@ revert_block_expr(Node) ->
%%
%% @see block_expr/1
+-spec block_expr_body(syntaxTree()) -> [syntaxTree()].
+
block_expr_body(Node) ->
case unwrap(Node) of
{block, _, Body} ->
@@ -5015,6 +5379,8 @@ block_expr_body(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec if_expr([syntaxTree()]) -> syntaxTree().
+
if_expr(Clauses) ->
tree(if_expr, Clauses).
@@ -5032,6 +5398,8 @@ revert_if_expr(Node) ->
%%
%% @see if_expr/1
+-spec if_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
if_expr_clauses(Node) ->
case unwrap(Node) of
{'if', _, Clauses} ->
@@ -5059,7 +5427,7 @@ if_expr_clauses(Node) ->
%% @see if_expr/1
%% @see cond_expr/1
--record(case_expr, {argument, clauses}).
+-record(case_expr, {argument :: syntaxTree(), clauses :: [syntaxTree()]}).
%% type(Node) = case_expr
%% data(Node) = #case_expr{argument :: Argument,
@@ -5078,6 +5446,8 @@ if_expr_clauses(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec case_expr(syntaxTree(), [syntaxTree()]) -> syntaxTree().
+
case_expr(Argument, Clauses) ->
tree(case_expr, #case_expr{argument = Argument,
clauses = Clauses}).
@@ -5096,6 +5466,8 @@ revert_case_expr(Node) ->
%%
%% @see case_expr/2
+-spec case_expr_argument(syntaxTree()) -> syntaxTree().
+
case_expr_argument(Node) ->
case unwrap(Node) of
{'case', _, Argument, _} ->
@@ -5113,6 +5485,8 @@ case_expr_argument(Node) ->
%%
%% @see case_expr/2
+-spec case_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
case_expr_clauses(Node) ->
case unwrap(Node) of
{'case', _, _, Clauses} ->
@@ -5151,6 +5525,8 @@ case_expr_clauses(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec cond_expr([syntaxTree()]) -> syntaxTree().
+
cond_expr(Clauses) ->
tree(cond_expr, Clauses).
@@ -5168,6 +5544,8 @@ revert_cond_expr(Node) ->
%%
%% @see cond_expr/1
+-spec cond_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
cond_expr_clauses(Node) ->
case unwrap(Node) of
{'cond', _, Clauses} ->
@@ -5181,6 +5559,8 @@ cond_expr_clauses(Node) ->
%% @spec receive_expr(Clauses) -> syntaxTree()
%% @equiv receive_expr(Clauses, none, [])
+-spec receive_expr([syntaxTree()]) -> syntaxTree().
+
receive_expr(Clauses) ->
receive_expr(Clauses, none, []).
@@ -5213,7 +5593,9 @@ receive_expr(Clauses) ->
%% @see clause/3
%% @see case_expr/2
--record(receive_expr, {clauses, timeout, action}).
+-record(receive_expr, {clauses :: [syntaxTree()],
+ timeout :: 'none' | syntaxTree(),
+ action :: [syntaxTree()]}).
%% type(Node) = receive_expr
%% data(Node) = #receive_expr{clauses :: Clauses,
@@ -5236,6 +5618,9 @@ receive_expr(Clauses) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec receive_expr([syntaxTree()], 'none' | syntaxTree(), [syntaxTree()]) ->
+ syntaxTree().
+
receive_expr(Clauses, Timeout, Action) ->
%% If `Timeout' is `none', we always replace the actual
%% `Action' argument with an empty list, since
@@ -5271,6 +5656,8 @@ revert_receive_expr(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
receive_expr_clauses(Node) ->
case unwrap(Node) of
{'receive', _, Clauses} ->
@@ -5295,6 +5682,8 @@ receive_expr_clauses(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_timeout(syntaxTree()) -> 'none' | syntaxTree().
+
receive_expr_timeout(Node) ->
case unwrap(Node) of
{'receive', _, _} ->
@@ -5316,6 +5705,8 @@ receive_expr_timeout(Node) ->
%%
%% @see receive_expr/3
+-spec receive_expr_action(syntaxTree()) -> [syntaxTree()].
+
receive_expr_action(Node) ->
case unwrap(Node) of
{'receive', _, _} ->
@@ -5332,6 +5723,8 @@ receive_expr_action(Node) ->
%% syntaxTree()
%% @equiv try_expr(Body, [], Handlers)
+-spec try_expr([syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Handlers) ->
try_expr(Body, [], Handlers).
@@ -5341,6 +5734,8 @@ try_expr(Body, Handlers) ->
%% Handlers::[syntaxTree()]) -> syntaxTree()
%% @equiv try_expr(Body, Clauses, Handlers, [])
+-spec try_expr([syntaxTree()], [syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Clauses, Handlers) ->
try_expr(Body, Clauses, Handlers, []).
@@ -5350,6 +5745,8 @@ try_expr(Body, Clauses, Handlers) ->
%% syntaxTree()
%% @equiv try_expr(Body, [], [], After)
+-spec try_after_expr([syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_after_expr(Body, After) ->
try_expr(Body, [], [], After).
@@ -5391,7 +5788,10 @@ try_after_expr(Body, After) ->
%% @see class_qualifier/2
%% @see case_expr/2
--record(try_expr, {body, clauses, handlers, 'after'}).
+-record(try_expr, {body :: [syntaxTree()],
+ clauses :: [syntaxTree()],
+ handlers :: [syntaxTree()],
+ 'after' :: [syntaxTree()]}).
%% type(Node) = try_expr
%% data(Node) = #try_expr{body :: Body,
@@ -5414,6 +5814,9 @@ try_after_expr(Body, After) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec try_expr([syntaxTree()], [syntaxTree()],
+ [syntaxTree()], [syntaxTree()]) -> syntaxTree().
+
try_expr(Body, Clauses, Handlers, After) ->
tree(try_expr, #try_expr{body = Body,
clauses = Clauses,
@@ -5437,6 +5840,8 @@ revert_try_expr(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_body(syntaxTree()) -> [syntaxTree()].
+
try_expr_body(Node) ->
case unwrap(Node) of
{'try', _, Body, _, _, _} ->
@@ -5456,6 +5861,8 @@ try_expr_body(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
try_expr_clauses(Node) ->
case unwrap(Node) of
{'try', _, _, Clauses, _, _} ->
@@ -5473,6 +5880,8 @@ try_expr_clauses(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_handlers(syntaxTree()) -> [syntaxTree()].
+
try_expr_handlers(Node) ->
case unwrap(Node) of
{'try', _, _, _, Handlers, _} ->
@@ -5490,6 +5899,8 @@ try_expr_handlers(Node) ->
%%
%% @see try_expr/4
+-spec try_expr_after(syntaxTree()) -> [syntaxTree()].
+
try_expr_after(Node) ->
case unwrap(Node) of
{'try', _, _, _, _, After} ->
@@ -5510,13 +5921,15 @@ try_expr_after(Node) ->
%% @see class_qualifier_body/1
%% @see try_expr/4
--record(class_qualifier, {class, body}).
+-record(class_qualifier, {class :: syntaxTree(), body :: syntaxTree()}).
%% type(Node) = class_qualifier
%% data(Node) = #class_qualifier{class :: Class, body :: Body}
%%
%% Class = Body = syntaxTree()
+-spec class_qualifier(syntaxTree(), syntaxTree()) -> syntaxTree().
+
class_qualifier(Class, Body) ->
tree(class_qualifier,
#class_qualifier{class = Class, body = Body}).
@@ -5530,6 +5943,8 @@ class_qualifier(Class, Body) ->
%%
%% @see class_qualifier/2
+-spec class_qualifier_argument(syntaxTree()) -> syntaxTree().
+
class_qualifier_argument(Node) ->
(data(Node))#class_qualifier.class.
@@ -5541,6 +5956,8 @@ class_qualifier_argument(Node) ->
%%
%% @see class_qualifier/2
+-spec class_qualifier_body(syntaxTree()) -> syntaxTree().
+
class_qualifier_body(Node) ->
(data(Node))#class_qualifier.body.
@@ -5559,6 +5976,8 @@ class_qualifier_body(Node) ->
%% @see implicit_fun/1
%% @see implicit_fun/3
+-spec implicit_fun(syntaxTree(), 'none' | syntaxTree()) -> syntaxTree().
+
implicit_fun(Name, none) ->
implicit_fun(Name);
implicit_fun(Name, Arity) ->
@@ -5580,6 +5999,9 @@ implicit_fun(Name, Arity) ->
%% @see implicit_fun/1
%% @see implicit_fun/2
+-spec implicit_fun('none' | syntaxTree(), syntaxTree(), syntaxTree()) ->
+ syntaxTree().
+
implicit_fun(none, Name, Arity) ->
implicit_fun(Name, Arity);
implicit_fun(Module, Name, Arity) ->
@@ -5610,7 +6032,9 @@ implicit_fun(Module, Name, Arity) ->
%%
%% Module = atom()
%% Name = atom()
-%% Arity = integer()
+%% Arity = arity()
+
+-spec implicit_fun(syntaxTree()) -> syntaxTree().
implicit_fun(Name) ->
tree(implicit_fun, Name).
@@ -5661,6 +6085,8 @@ revert_implicit_fun(Node) ->
%% @see arity_qualifier/2
%% @see module_qualifier/2
+-spec implicit_fun_name(syntaxTree()) -> syntaxTree().
+
implicit_fun_name(Node) ->
case unwrap(Node) of
{'fun', Pos, {function, Atom, Arity}} ->
@@ -5707,6 +6133,8 @@ implicit_fun_name(Node) ->
%%
%% See `clause' for documentation on `erl_parse' clauses.
+-spec fun_expr([syntaxTree()]) -> syntaxTree().
+
fun_expr(Clauses) ->
tree(fun_expr, Clauses).
@@ -5724,6 +6152,8 @@ revert_fun_expr(Node) ->
%%
%% @see fun_expr/1
+-spec fun_expr_clauses(syntaxTree()) -> [syntaxTree()].
+
fun_expr_clauses(Node) ->
case unwrap(Node) of
{'fun', _, {clauses, Clauses}} ->
@@ -5750,6 +6180,8 @@ fun_expr_clauses(Node) ->
%% @see clause/3
%% @see clause_patterns/1
+-spec fun_expr_arity(syntaxTree()) -> arity().
+
fun_expr_arity(Node) ->
length(clause_patterns(hd(fun_expr_clauses(Node)))).
@@ -5766,6 +6198,8 @@ fun_expr_arity(Node) ->
%% type(Node) = parentheses
%% data(Node) = syntaxTree()
+-spec parentheses(syntaxTree()) -> syntaxTree().
+
parentheses(Expr) ->
tree(parentheses, Expr).
@@ -5780,6 +6214,8 @@ revert_parentheses(Node) ->
%%
%% @see parentheses/1
+-spec parentheses_body(syntaxTree()) -> syntaxTree().
+
parentheses_body(Node) ->
data(Node).
@@ -5788,6 +6224,8 @@ parentheses_body(Node) ->
%% @spec macro(Name) -> syntaxTree()
%% @equiv macro(Name, none)
+-spec macro(syntaxTree()) -> syntaxTree().
+
macro(Name) ->
macro(Name, none).
@@ -5818,7 +6256,7 @@ macro(Name) ->
%% @see macro/1
%% @see text/1
--record(macro, {name, arguments}).
+-record(macro, {name :: syntaxTree(), arguments :: 'none' | [syntaxTree()]}).
%% type(Node) = macro
%% data(Node) = #macro{name :: Name, arguments :: Arguments}
@@ -5826,6 +6264,8 @@ macro(Name) ->
%% Name = syntaxTree()
%% Arguments = none | [syntaxTree()]
+-spec macro(syntaxTree(), 'none' | [syntaxTree()]) -> syntaxTree().
+
macro(Name, Arguments) ->
tree(macro, #macro{name = Name, arguments = Arguments}).
@@ -5837,6 +6277,8 @@ macro(Name, Arguments) ->
%%
%% @see macro/2
+-spec macro_name(syntaxTree()) -> syntaxTree().
+
macro_name(Node) ->
(data(Node))#macro.name.
@@ -5853,6 +6295,8 @@ macro_name(Node) ->
%%
%% @see macro/2
+-spec macro_arguments(syntaxTree()) -> 'none' | [syntaxTree()].
+
macro_arguments(Node) ->
(data(Node))#macro.arguments.
@@ -5871,6 +6315,8 @@ macro_arguments(Node) ->
%% @see concrete/1
%% @see is_literal/1
+-spec abstract(term()) -> syntaxTree().
+
abstract([H | T] = L) when is_integer(H) ->
case is_printable(L) of
true ->
@@ -5932,6 +6378,8 @@ abstract_tail(H, T) ->
%% @see is_literal/1
%% @see char/1
+-spec concrete(syntaxTree()) -> term().
+
concrete(Node) ->
case type(Node) of
atom ->
@@ -5978,7 +6426,7 @@ concrete_list([]) ->
%% =====================================================================
-%% @spec is_literal(Node::syntaxTree()) -> bool()
+%% @spec is_literal(Node::syntaxTree()) -> boolean()
%%
%% @doc Returns <code>true</code> if <code>Node</code> represents a
%% literal term, otherwise <code>false</code>. This function returns
@@ -5988,6 +6436,8 @@ concrete_list([]) ->
%% @see abstract/1
%% @see concrete/1
+-spec is_literal(syntaxTree()) -> boolean().
+
is_literal(T) ->
case type(T) of
atom ->
@@ -6031,6 +6481,8 @@ is_literal(T) ->
%% @see revert_forms/1
%% @see //stdlib/erl_parse
+-spec revert(syntaxTree()) -> syntaxTree().
+
revert(Node) ->
case is_tree(Node) of
false ->
@@ -6172,6 +6624,10 @@ revert_root(Node) ->
%% @see form_list/1
%% @see is_form/1
+-type forms() :: syntaxTree() | [syntaxTree()].
+
+%% -spec revert_forms(forms()) -> [erl_parse()].
+
revert_forms(L) when is_list(L) ->
revert_forms(form_list(L));
revert_forms(T) ->
@@ -6270,6 +6726,8 @@ revert_forms_1([]) ->
%% @see is_leaf/1
%% @see copy_attrs/2
+-spec subtrees(syntaxTree()) -> [[syntaxTree()]].
+
subtrees(T) ->
case is_leaf(T) of
true ->
@@ -6442,6 +6900,8 @@ subtrees(T) ->
%% @see copy_attrs/2
%% @see type/1
+-spec update_tree(syntaxTree(), [[syntaxTree()]]) -> syntaxTree().
+
update_tree(Node, Groups) ->
copy_attrs(Node, make_tree(type(Node), Groups)).
@@ -6471,6 +6931,8 @@ update_tree(Node, Groups) ->
%% @see is_leaf/1
%% @see copy_attrs/2
+-spec make_tree(atom(), [[syntaxTree()]]) -> syntaxTree().
+
make_tree(application, [[F], A]) -> application(F, A);
make_tree(arity_qualifier, [[N], [A]]) -> arity_qualifier(N, A);
make_tree(attribute, [[N]]) -> attribute(N);
@@ -6567,6 +7029,8 @@ make_tree(tuple, [E]) -> tuple(E).
%% @see type/1
%% @see get_ann/1
+-spec meta(syntaxTree()) -> syntaxTree().
+
meta(T) ->
%% First of all we check for metavariables:
case type(T) of
@@ -6693,6 +7157,8 @@ meta_call(F, As) ->
%% @spec tree(Type) -> syntaxTree()
%% @equiv tree(Type, [])
+-spec tree(atom()) -> syntaxTree().
+
tree(Type) ->
tree(Type, []).
@@ -6727,12 +7193,14 @@ tree(Type) ->
%% @see data/1
%% @see type/1
+-spec tree(atom(), term()) -> syntaxTree().
+
tree(Type, Data) ->
#tree{type = Type, data = Data}.
%% =====================================================================
-%% @spec is_tree(Tree::syntaxTree()) -> bool()
+%% @spec is_tree(Tree::syntaxTree()) -> boolean()
%%
%% @doc <em>For special purposes only</em>. Returns <code>true</code> if
%% <code>Tree</code> is an abstract syntax tree and <code>false</code>
@@ -6743,6 +7211,8 @@ tree(Type, Data) ->
%%
%% @see tree/2
+-spec is_tree(syntaxTree()) -> boolean().
+
is_tree(#tree{}) ->
true;
is_tree(_) ->
@@ -6759,6 +7229,8 @@ is_tree(_) ->
%%
%% @see tree/2
+-spec data(syntaxTree()) -> term().
+
data(#tree{data = D}) -> D;
data(T) -> erlang:error({badarg, T}).
@@ -6788,6 +7260,8 @@ data(T) -> erlang:error({badarg, T}).
%% trees. <em>Attaching a wrapper onto another wrapper structure is an
%% error</em>.</p>
+%%-spec wrap(erl_parse:parse_tree()) -> syntaxTree().
+
wrap(Node) ->
%% We assume that Node is an old-school `erl_parse' tree.
#wrapper{type = type(Node), attr = #attr{pos = get_pos(Node)},
@@ -6802,17 +7276,21 @@ wrap(Node) ->
%% <code>erl_parse</code> tree; otherwise it returns <code>Node</code>
%% itself.
+-spec unwrap(syntaxTree()) -> syntaxTree().
+
unwrap(#wrapper{tree = Node}) -> Node;
unwrap(Node) -> Node. % This could also be a new-form node.
%% =====================================================================
-%% @spec is_wrapper(Term::term()) -> bool()
+%% @spec is_wrapper(Term::term()) -> boolean()
%%
%% @doc Returns <code>true</code> if the argument is a wrapper
%% structure, otherwise <code>false</code>.
-ifndef(NO_UNUSED).
+-spec is_wrapper(term()) -> boolean().
+
is_wrapper(#wrapper{}) ->
true;
is_wrapper(_) ->
diff --git a/lib/syntax_tools/src/erl_syntax_lib.erl b/lib/syntax_tools/src/erl_syntax_lib.erl
index ccbf864c2a..5c4e074488 100644
--- a/lib/syntax_tools/src/erl_syntax_lib.erl
+++ b/lib/syntax_tools/src/erl_syntax_lib.erl
@@ -46,6 +46,9 @@
new_variable_names/2, new_variable_names/3, strip_comments/1,
to_comment/1, to_comment/2, to_comment/3, variables/1]).
+%% =====================================================================
+
+-type ordset(X) :: [X]. % XXX: TAKE ME OUT
%% =====================================================================
%% @spec map(Function, Tree::syntaxTree()) -> syntaxTree()
@@ -58,6 +61,9 @@
%%
%% @see map_subtrees/2
+-spec map(fun((erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree()),
+ erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
map(F, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -81,6 +87,9 @@ map(F, Tree) ->
%%
%% @see map/2
+-spec map_subtrees(fun((erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree()),
+ erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
map_subtrees(F, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -105,6 +114,9 @@ map_subtrees(F, Tree) ->
%% @see fold_subtrees/3
%% @see foldl_listlist/3
+-spec fold(fun((erl_syntax:syntaxTree(), term()) -> term()),
+ term(), erl_syntax:syntaxTree()) -> term().
+
fold(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -137,6 +149,9 @@ fold_2(_, S, []) ->
%%
%% @see fold/3
+-spec fold_subtrees(fun((erl_syntax:syntaxTree(), term()) -> term()),
+ term(), erl_syntax:syntaxTree()) -> term().
+
fold_subtrees(F, S, Tree) ->
foldl_listlist(F, S, erl_syntax:subtrees(Tree)).
@@ -151,6 +166,9 @@ fold_subtrees(F, S, Tree) ->
%% @see fold/3
%% @see //stdlib/lists:foldl/3
+-spec foldl_listlist(fun((term(), term()) -> term()),
+ term(), [[term()]]) -> term().
+
foldl_listlist(F, S, [L | Ls]) ->
foldl_listlist(F, foldl(F, S, L), Ls);
foldl_listlist(_, S, []) ->
@@ -178,6 +196,9 @@ foldl(_, S, []) ->
%% @see map/2
%% @see fold/3
+-spec mapfold(fun((erl_syntax:syntaxTree(), term()) -> {erl_syntax:syntaxTree(), term()}),
+ term(), erl_syntax:syntaxTree()) -> {erl_syntax:syntaxTree(), term()}.
+
mapfold(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -216,6 +237,11 @@ mapfold_2(_, S, []) ->
%%
%% @see mapfold/3
+-spec mapfold_subtrees(fun((erl_syntax:syntaxTree(), term()) ->
+ {erl_syntax:syntaxTree(), term()}),
+ term(), erl_syntax:syntaxTree()) ->
+ {erl_syntax:syntaxTree(), term()}.
+
mapfold_subtrees(F, S, Tree) ->
case erl_syntax:subtrees(Tree) of
[] ->
@@ -237,6 +263,9 @@ mapfold_subtrees(F, S, Tree) ->
%% The list of lists in the result has the same structure as the given
%% list of lists.
+-spec mapfoldl_listlist(fun((term(), term()) -> {term(), term()}),
+ term(), [[term()]]) -> {[[term()]], term()}.
+
mapfoldl_listlist(F, S, [L | Ls]) ->
{L1, S1} = mapfoldl(F, S, L),
{Ls1, S2} = mapfoldl_listlist(F, S1, Ls),
@@ -263,6 +292,8 @@ mapfoldl(_, S, []) ->
%%
%% @see //stdlib/sets
+-spec variables(erl_syntax:syntaxTree()) -> set().
+
variables(Tree) ->
variables(Tree, sets:new()).
@@ -316,6 +347,8 @@ default_variable_name(N) ->
%%
%% @see new_variable_name/2
+-spec new_variable_name(set()) -> atom().
+
new_variable_name(S) ->
new_variable_name(fun default_variable_name/1, S).
@@ -340,6 +373,8 @@ new_variable_name(S) ->
%% @see //stdlib/sets
%% @see //stdlib/random
+-spec new_variable_name(fun((integer()) -> atom()), set()) -> atom().
+
new_variable_name(F, S) ->
R = start_range(S),
new_variable_name(R, F, S).
@@ -388,6 +423,8 @@ generate(_Key, Range) ->
%%
%% @see new_variable_name/1
+-spec new_variable_names(integer(), set()) -> [atom()].
+
new_variable_names(N, S) ->
new_variable_names(N, fun default_variable_name/1, S).
@@ -402,6 +439,9 @@ new_variable_names(N, S) ->
%%
%% @see new_variable_name/2
+-spec new_variable_names(integer(), fun((integer()) -> atom()), set()) ->
+ [atom()].
+
new_variable_names(N, F, S) when is_integer(N) ->
R = start_range(S),
new_variable_names(N, [], R, F, S).
@@ -441,6 +481,9 @@ new_variable_names(0, Names, _, _, _) ->
%% @see annotate_bindings/1
%% @see //stdlib/ordsets
+-spec annotate_bindings(erl_syntax:syntaxTree(), ordset(atom())) ->
+ erl_syntax:syntaxTree().
+
annotate_bindings(Tree, Env) ->
{Tree1, _, _} = vann(Tree, Env),
Tree1.
@@ -457,6 +500,8 @@ annotate_bindings(Tree, Env) ->
%%
%% @see annotate_bindings/2
+-spec annotate_bindings(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
annotate_bindings(Tree) ->
As = erl_syntax:get_ann(Tree),
case lists:keyfind(env, 1, As) of
@@ -856,7 +901,7 @@ delete_binding_anns([]) ->
%% =====================================================================
-%% @spec is_fail_expr(Tree::syntaxTree()) -> bool()
+%% @spec is_fail_expr(Tree::syntaxTree()) -> boolean()
%%
%% @doc Returns `true' if `Tree' represents an
%% expression which never terminates normally. Note that the reverse
@@ -869,6 +914,8 @@ delete_binding_anns([]) ->
%% @see //erts/erlang:error/1
%% @see //erts/erlang:error/2
+-spec is_fail_expr(erl_syntax:syntaxTree()) -> boolean().
+
is_fail_expr(E) ->
case erl_syntax:type(E) of
application ->
@@ -1038,6 +1085,12 @@ is_fail_expr(E) ->
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
+-type key() :: 'attributes' | 'errors' | 'exports' | 'functions' | 'imports'
+ | 'module' | 'records' | 'rules' | 'warnings'.
+-type info_pair() :: {key(), term()}.
+
+-spec analyze_forms(erl_syntax:forms()) -> [info_pair()].
+
analyze_forms(Forms) when is_list(Forms) ->
finfo_to_list(lists:foldl(fun collect_form/2, new_finfo(), Forms));
analyze_forms(Forms) ->
@@ -1204,6 +1257,8 @@ list_value(List) ->
%% @see erl_syntax:error_marker_info/1
%% @see erl_syntax:warning_marker_info/1
+-spec analyze_form(erl_syntax:syntaxTree()) -> {atom(), term()} | atom().
+
analyze_form(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1276,6 +1331,9 @@ analyze_form(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_wild_attribute/1
+-spec analyze_attribute(erl_syntax:syntaxTree()) ->
+ 'preprocessor' | {atom(), term()}. % XXX: underspecified
+
analyze_attribute(Node) ->
Name = erl_syntax:attribute_name(Node),
case erl_syntax:type(Name) of
@@ -1326,12 +1384,14 @@ analyze_attribute(_, Node) ->
%% containing the module name and a list of the parameter variable
%% names.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed module
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed module attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_module_attribute(erl_syntax:syntaxTree()) ->
+ atom() | {atom(), [atom()]}.
+
analyze_module_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1370,12 +1430,16 @@ analyze_variable_list(Node) ->
%% attribute. We do not guarantee that each name occurs at most once in
%% the list. The order of listing is not defined.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed export
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed export attribute.
%%
%% @see analyze_attribute/1
+-type functionN() :: atom() | {atom(), arity()}.
+-type functionName() :: functionN() | {atom(), functionN()}.
+
+-spec analyze_export_attribute(erl_syntax:syntaxTree()) -> [functionName()].
+
analyze_export_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1416,6 +1480,8 @@ analyze_function_name_list(Node) ->
%% The evaluation throws `syntax_error' if
%% `Node' does not represent a well-formed function name.
+-spec analyze_function_name(erl_syntax:syntaxTree()) -> functionName().
+
analyze_function_name(Node) ->
case erl_syntax:type(Node) of
atom ->
@@ -1470,12 +1536,14 @@ append_arity(_A, Name) ->
%% that each name occurs at most once in `Names'. The order
%% of listing is not defined.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed import
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed import attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_import_attribute(erl_syntax:syntaxTree()) ->
+ {atom(), [functionName()]} | atom().
+
analyze_import_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1498,19 +1566,19 @@ analyze_import_attribute(Node) ->
%% @spec analyze_wild_attribute(Node::syntaxTree()) -> {atom(), term()}
%%
%% @doc Returns the name and value of a "wild" attribute. The result is
-%% the pair `{Name, Value}', if `Node' represents
-%% "`-Name(Value)'".
+%% the pair `{Name, Value}', if `Node' represents "`-Name(Value)'".
%%
%% Note that no checking is done whether `Name' is a
%% reserved attribute name such as `module' or
%% `export': it is assumed that the attribute is "wild".
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed wild
-%% attribute.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed wild attribute.
%%
%% @see analyze_attribute/1
+-spec analyze_wild_attribute(erl_syntax:syntaxTree()) -> {atom(), term()}.
+
analyze_wild_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1559,6 +1627,10 @@ analyze_wild_attribute(Node) ->
%% @see analyze_attribute/1
%% @see analyze_record_field/1
+-type fields() :: [{atom(), 'none' | erl_syntax:syntaxTree()}].
+
+-spec analyze_record_attribute(erl_syntax:syntaxTree()) -> {atom(), fields()}.
+
analyze_record_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1629,6 +1701,11 @@ analyze_record_attribute_tuple(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_record_field/1
+-type info() :: {atom(), [{atom(), 'none' | erl_syntax:syntaxTree()}]}
+ | {atom(), atom()} | atom().
+
+-spec analyze_record_expr(erl_syntax:syntaxTree()) -> {atom(), info()} | atom().
+
analyze_record_expr(Node) ->
case erl_syntax:type(Node) of
record_expr ->
@@ -1700,6 +1777,9 @@ analyze_record_expr(Node) ->
%% @see analyze_record_attribute/1
%% @see analyze_record_expr/1
+-spec analyze_record_field(erl_syntax:syntaxTree()) ->
+ {atom(), 'none' | erl_syntax:syntaxTree()}.
+
analyze_record_field(Node) ->
case erl_syntax:type(Node) of
record_field ->
@@ -1730,6 +1810,8 @@ analyze_record_field(Node) ->
%%
%% @see analyze_attribute/1
+-spec analyze_file_attribute(erl_syntax:syntaxTree()) -> {string(), integer()}.
+
analyze_file_attribute(Node) ->
case erl_syntax:type(Node) of
attribute ->
@@ -1765,6 +1847,8 @@ analyze_file_attribute(Node) ->
%%
%% @see analyze_rule/1
+-spec analyze_function(erl_syntax:syntaxTree()) -> {atom(), arity()}.
+
analyze_function(Node) ->
case erl_syntax:type(Node) of
function ->
@@ -1794,6 +1878,8 @@ analyze_function(Node) ->
%%
%% @see analyze_function/1
+-spec analyze_rule(erl_syntax:syntaxTree()) -> {atom(), arity()}.
+
analyze_rule(Node) ->
case erl_syntax:type(Node) of
rule ->
@@ -1826,11 +1912,12 @@ analyze_rule(Node) ->
%%
%% @see analyze_function_name/1
+-spec analyze_implicit_fun(erl_syntax:syntaxTree()) -> functionName().
+
analyze_implicit_fun(Node) ->
case erl_syntax:type(Node) of
implicit_fun ->
- analyze_function_name(
- erl_syntax:implicit_fun_name(Node));
+ analyze_function_name(erl_syntax:implicit_fun_name(Node));
_ ->
throw(syntax_error)
end.
@@ -1851,12 +1938,15 @@ analyze_implicit_fun(Node) ->
%% function is not explicitly named (i.e., `F' is given by
%% some expression), only the arity `A' is returned.
%%
-%% The evaluation throws `syntax_error' if
-%% `Node' does not represent a well-formed application
-%% expression.
+%% The evaluation throws `syntax_error' if `Node' does not represent a
+%% well-formed application expression.
%%
%% @see analyze_function_name/1
+-type appFunName() :: {atom(), arity()} | {atom(), {atom(), arity()}}.
+
+-spec analyze_application(erl_syntax:syntaxTree()) -> appFunName() | arity().
+
analyze_application(Node) ->
case erl_syntax:type(Node) of
application ->
@@ -1897,6 +1987,11 @@ analyze_application(Node) ->
%%
%% @see analyze_function_name/1
+-type shortname() :: atom() | {atom(), arity()}.
+-type name() :: shortname() | {atom(), shortname()}.
+
+-spec function_name_expansions([name()]) -> [{shortname(), name()}].
+
function_name_expansions(Fs) ->
function_name_expansions(Fs, []).
@@ -1922,6 +2017,8 @@ function_name_expansions(A, Name, Ack) ->
%% Standalone comments in form lists are removed; any other standalone
%% comments are changed into null-comments (no text, no indentation).
+-spec strip_comments(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
strip_comments(Tree) ->
map(fun strip_comments_1/1, Tree).
@@ -1942,6 +2039,8 @@ strip_comments_1(T) ->
%% @spec to_comment(Tree) -> syntaxTree()
%% @equiv to_comment(Tree, "% ")
+-spec to_comment(erl_syntax:syntaxTree()) -> erl_syntax:syntaxTree().
+
to_comment(Tree) ->
to_comment(Tree, "% ").
@@ -1956,6 +2055,8 @@ to_comment(Tree) ->
%% @see to_comment/3
%% @see erl_prettypr:format/1
+-spec to_comment(erl_syntax:syntaxTree(), string()) -> erl_syntax:syntaxTree().
+
to_comment(Tree, Prefix) ->
F = fun (T) -> erl_prettypr:format(T) end,
to_comment(Tree, Prefix, F).
@@ -1985,6 +2086,10 @@ to_comment(Tree, Prefix) ->
%% @see to_comment/1
%% @see to_comment/2
+-spec to_comment(erl_syntax:syntaxTree(), string(),
+ fun((erl_syntax:syntaxTree()) -> string())) ->
+ erl_syntax:syntaxTree().
+
to_comment(Tree, Prefix, F) ->
erl_syntax:comment(split_lines(F(Tree), Prefix)).
@@ -1998,6 +2103,8 @@ to_comment(Tree, Prefix, F) ->
%% @see limit/3
%% @see erl_syntax:text/1
+-spec limit(erl_syntax:syntaxTree(), integer()) -> erl_syntax:syntaxTree().
+
limit(Tree, Depth) ->
limit(Tree, Depth, erl_syntax:text("...")).
@@ -2026,6 +2133,9 @@ limit(Tree, Depth) ->
%%
%% @see limit/2
+-spec limit(erl_syntax:syntaxTree(), integer(), erl_syntax:syntaxTree()) ->
+ erl_syntax:syntaxTree().
+
limit(_Tree, Depth, Node) when Depth < 0 ->
Node;
limit(Tree, Depth, Node) ->
diff --git a/lib/syntax_tools/src/erl_tidy.erl b/lib/syntax_tools/src/erl_tidy.erl
index e3b479008f..021ab18736 100644
--- a/lib/syntax_tools/src/erl_tidy.erl
+++ b/lib/syntax_tools/src/erl_tidy.erl
@@ -66,6 +66,7 @@ dir__defaults() ->
%% @equiv dir("")
-spec dir() -> 'ok'.
+
dir() ->
dir("").
@@ -74,6 +75,7 @@ dir() ->
%% @equiv dir(Dir, [])
-spec dir(file:filename()) -> 'ok'.
+
dir(Dir) ->
dir(Dir, []).
@@ -130,6 +132,7 @@ dir(Dir) ->
options :: options()}).
-spec dir(file:filename(), options()) -> 'ok'.
+
dir(Dir, Opts) ->
Opts1 = Opts ++ dir__defaults(),
Env = #dir{follow_links = proplists:get_bool(follow_links, Opts1),
@@ -212,6 +215,7 @@ default_printer() ->
%% @equiv file(Name, [])
-spec file(file:filename()) -> 'ok'.
+
file(Name) ->
file(Name, []).
@@ -275,6 +279,7 @@ file(Name) ->
%% @see module/2
-spec file(file:filename(), options()) -> 'ok'.
+
file(Name, Opts) ->
Parent = self(),
Child = spawn_link(fun () -> file_1(Parent, Name, Opts) end),
@@ -478,11 +483,12 @@ backup_file_1(Name, Opts) ->
throw(R)
end.
-
%% =====================================================================
%% @spec module(Forms) -> syntaxTree()
%% @equiv module(Forms, [])
+-spec module(erl_syntax:forms()) -> erl_syntax:syntaxTree().
+
module(Forms) ->
module(Forms, []).
@@ -609,6 +615,8 @@ module(Forms) ->
%%
%% </dl>
+-spec module(erl_syntax:forms(), [term()]) -> erl_syntax:syntaxTree().
+
module(Forms, Opts) when is_list(Forms) ->
module(erl_syntax:form_list(Forms), Opts);
module(Forms, Opts) ->
@@ -668,11 +676,8 @@ analyze_forms(Forms, File) ->
throw(R)
end.
-%% XXX: The following should be imported from erl_syntax_lib
--type key() :: atom().
--type info_pair() :: {key(), any()}.
+-spec get_module_name([erl_syntax_lib:info_pair()], string()) -> atom().
--spec get_module_name([info_pair()], string()) -> atom().
get_module_name(List, File) ->
case lists:keyfind(module, 1, List) of
{module, M} ->
@@ -691,7 +696,8 @@ get_module_attributes(List) ->
[]
end.
--spec get_module_exports([info_pair()]) -> [{atom(), byte()}].
+-spec get_module_exports([erl_syntax_lib:info_pair()]) -> [{atom(), arity()}].
+
get_module_exports(List) ->
case lists:keyfind(exports, 1, List) of
{exports, Es} ->
@@ -700,7 +706,8 @@ get_module_exports(List) ->
[]
end.
--spec get_module_imports([info_pair()]) -> [{atom(), atom()}].
+-spec get_module_imports([erl_syntax_lib:info_pair()]) -> [{atom(), atom()}].
+
get_module_imports(List) ->
case lists:keyfind(imports, 1, List) of
{imports, Is} ->
@@ -714,6 +721,7 @@ compile_attrs(As) ->
|| {compile, T} <- As]).
-spec flatten_imports([{atom(), [atom()]}]) -> [{atom(), atom()}].
+
flatten_imports(Is) ->
[{F, M} || {M, Fs} <- Is, F <- Fs].
@@ -736,7 +744,8 @@ check_imports(Is, Opts, File) ->
end.
-spec check_imports_1([{atom(), atom()}]) -> boolean().
-check_imports_1([{F1, M1}, {F2, M2} | _Is]) when F1 =:= F2, M1 =/= M2 ->
+
+check_imports_1([{F, M1}, {F, M2} | _Is]) when M1 =/= M2 ->
false;
check_imports_1([_ | Is]) ->
check_imports_1(Is);
@@ -1629,6 +1638,7 @@ rename_remote_call(F, St) ->
end.
-spec rename_remote_call_1(mfa()) -> {atom(), atom()} | 'false'.
+
rename_remote_call_1({dict, dict_to_list, 1}) -> {dict, to_list};
rename_remote_call_1({dict, list_to_dict, 1}) -> {dict, from_list};
rename_remote_call_1({erl_eval, arg_list, 2}) -> {erl_eval, expr_list};
@@ -1662,7 +1672,8 @@ rename_remote_call_1({string, index, 2}) -> {string, str};
rename_remote_call_1({unix, cmd, 1}) -> {os, cmd};
rename_remote_call_1(_) -> false.
--spec rewrite_guard_test(atom(), byte()) -> atom().
+-spec rewrite_guard_test(atom(), arity()) -> atom().
+
rewrite_guard_test(atom, 1) -> is_atom;
rewrite_guard_test(binary, 1) -> is_binary;
rewrite_guard_test(constant, 1) -> is_constant;
@@ -1680,7 +1691,8 @@ rewrite_guard_test(record, 2) -> is_record;
rewrite_guard_test(record, 3) -> is_record;
rewrite_guard_test(N, _A) -> N.
--spec reverse_guard_test(atom(), byte()) -> atom().
+-spec reverse_guard_test(atom(), arity()) -> atom().
+
reverse_guard_test(is_atom, 1) -> atom;
reverse_guard_test(is_binary, 1) -> binary;
reverse_guard_test(is_constant, 1) -> constant;
diff --git a/lib/syntax_tools/src/igor.erl b/lib/syntax_tools/src/igor.erl
index 9e7b784170..e92e9593b6 100644
--- a/lib/syntax_tools/src/igor.erl
+++ b/lib/syntax_tools/src/igor.erl
@@ -117,20 +117,23 @@
-define(record_name(R), {record, R}).
+%% =====================================================================
+
+-type ordset(X) :: [X]. % XXX: TAKE ME OUT
+
+%% =====================================================================
%% Data structure for module information
--record(module, {name, % = atom()
- vars = none, % = [atom()] | none
- functions, % = ordset({atom(), int()})
- exports, % = ordset({atom(), int()})
- % | ordset({{atom(), int()},
- % term()})
- aliases, % = ordset({{atom(), int()},
- % {atom(),
- % {atom(), int()}}})
- attributes, % = ordset({atom(), term()})
- records % = [{atom(), [{atom(), term()}]}]
+-record(module, {name :: atom(),
+ vars = none :: [atom()] | 'none',
+ functions :: ordset({atom(), arity()}),
+ exports :: ordset({atom(), arity()})
+ | ordset({{atom(), arity()}, term()}),
+ aliases :: ordset({{atom(), arity()},
+ {atom(), {atom(), arity()}}}),
+ attributes :: ordset({atom(), term()}),
+ records :: [{atom(), [{atom(), term()}]}]
}).
%% The default pretty-printing function.
@@ -138,6 +141,17 @@
default_printer(Tree, Options) ->
erl_prettypr:format(Tree, Options).
+%% =====================================================================
+
+-type option() :: atom() | {atom(), term()}.
+
+-type attribute() :: {atom(), term()}.
+-type moduleName() :: atom().
+-type functionName() :: {atom(), arity()}.
+-type functionPair() :: {functionName(), {moduleName(), functionName()}}.
+-type stubDescriptor() :: [{moduleName(), [functionPair()], [attribute()]}].
+
+-type notes() :: 'always' | 'yes' | 'no'.
%% =====================================================================
%% @spec parse_transform(Forms::[syntaxTree()], Options::[term()]) ->
@@ -169,6 +183,9 @@ default_printer(Tree, Options) ->
%% @see merge_files/4
%% @see //compiler/compile:file/2
+-spec parse_transform(erl_syntax:forms(), [option()]) ->
+ [erl_syntax:syntaxTree()].
+
parse_transform(Forms, Options) ->
M = get_module_info(Forms),
Name = M#module.name,
@@ -192,6 +209,8 @@ parse_transform(Forms, Options) ->
%% @spec merge(Name::atom(), Files::[filename()]) -> [filename()]
%% @equiv merge(Name, Files, [])
+-spec merge(atom(), [file:filename()]) -> [file:filename()].
+
merge(Name, Files) ->
merge(Name, Files, []).
@@ -251,7 +270,7 @@ merge(Name, Files) ->
%% <dd>Specifies the file name suffix to be used when a backup file
%% is created; the default value is `".bak"'.</dd>
%%
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%%
%% <dd>If the value is `true', existing files will be
%% renamed before new files are opened for writing. The new names
@@ -271,7 +290,7 @@ merge(Name, Files) ->
%% resulting source code is to be written. By default, this is the
%% same as the `Name' argument.</dd>
%%
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%%
%% <dd>If the value is `true', preprocessing will be done
%% when reading the source code. See `merge_files/4' for
@@ -294,7 +313,7 @@ merge(Name, Files) ->
%% stub module files are written. The default value is
%% `"stubs"'.</dd>
%%
-%% <dt>`{stubs, bool()}'</dt>
+%% <dt>`{stubs, boolean()}'</dt>
%%
%% <dd>If the value is `true', stub module files will be
%% automatically generated for all exported modules that do not have
@@ -324,6 +343,8 @@ merge(Name, Files) ->
{suffix, ?DEFAULT_SUFFIX},
{verbose, false}]).
+-spec merge(atom(), [file:filename()], [option()]) -> [file:filename()].
+
merge(Name, Files, Opts) ->
Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS,
{Tree, Stubs} = merge_files(Name, Files, Opts1),
@@ -339,6 +360,9 @@ merge(Name, Files, Opts) ->
%% {syntaxTree(), [stubDescriptor()]}
%% @equiv merge_files(Name, [], Files, Options)
+-spec merge_files(atom(), [file:filename()], [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_files(Name, Files, Options) ->
merge_files(Name, [], Files, Options).
@@ -380,7 +404,7 @@ merge_files(Name, Files, Options) ->
%%
%% Options:
%% <dl>
-%% <dt>`{comments, bool()}'</dt>
+%% <dt>`{comments, boolean()}'</dt>
%%
%% <dd>If the value is `true', source code comments in
%% the original files will be preserved in the output. The default
@@ -409,7 +433,7 @@ merge_files(Name, Files, Options) ->
%% Erlang preprocessor, if used (cf. the `preprocess'
%% option). The default value is the empty list.</dd>
%%
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%%
%% <dd>If the value is `false', Igor will read source
%% files without passing them through the Erlang preprocessor
@@ -438,6 +462,9 @@ merge_files(Name, Files, Options) ->
%% @see //stdlib/filename:find_src/2
%% @see epp_dodger
+-spec merge_files(atom(), erl_syntax:forms(), [file:filename()], [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_files(_, _Trees, [], _) ->
report_error("no files to merge."),
exit(badarg);
@@ -512,7 +539,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% `Sources' will be exported. The default value is the
%% empty list.</dd>
%%
-%% <dt>`{export_all, bool()}'</dt>
+%% <dt>`{export_all, boolean()}'</dt>
%%
%% <dd>If the value is `true', this is equivalent to
%% listing all of the input modules in the `export'
@@ -532,7 +559,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% they will be handled as in the `comment' case. The
%% default value is `no'.</dd>
%%
-%% <dt>`{no_banner, bool()}'</dt>
+%% <dt>`{no_banner, boolean()}'</dt>
%%
%% <dd>If the value is `true', no banner comment will be
%% added at the top of the resulting module, even if the target
@@ -541,7 +568,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% code is at the top of the output. The default value is
%% `false'.</dd>
%%
-%% <dt>`{no_headers, bool()}'</dt>
+%% <dt>`{no_headers, boolean()}'</dt>
%%
%% <dd>If the value is `true', no header comments will be
%% added to the resulting module at the beginning of each section of
@@ -550,7 +577,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% normally added whenever more than two or more modules are
%% merged.</dd>
%%
-%% <dt>`{no_imports, bool()}'</dt>
+%% <dt>`{no_imports, boolean()}'</dt>
%%
%% <dd>If the value is `true', all
%% `-import(...)' declarations in the original code will
@@ -599,7 +626,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% regarded as "static", regardless of the value of this option. By
%% default, all involved modules are assumed to be static.</dd>
%%
-%% <dt>`{tidy, bool()}'</dt>
+%% <dt>`{tidy, boolean()}'</dt>
%%
%% <dd>If the value is `true', the resulting code will be
%% processed using the `erl_tidy' module, which removes
@@ -607,7 +634,7 @@ merge_files(Name, Trees, Files, Opts) ->
%% `erl_tidy:module/2' for additional options.) The
%% default value is `true'.</dd>
%%
-%% <dt>`{verbose, bool()}'</dt>
+%% <dt>`{verbose, boolean()}'</dt>
%%
%% <dd>If the value is `true', progress messages will be
%% output while the program is running; the default value is
@@ -659,19 +686,22 @@ merge_files(Name, Trees, Files, Opts) ->
%% Data structure for merging environment.
--record(merge, {target, % = atom()
- sources, % = ordset(atom())
- export, % = ordset(atom())
- static, % = ordset(atom())
- safe, % = ordset(atom())
- preserved, % = bool()
- no_headers, % = bool()
- notes, % = bool()
- redirect, % = dict(atom(), atom())
- no_imports, % = ordset(atom())
- options % = [term()]
+-record(merge, {target :: atom(),
+ sources :: ordset(atom()),
+ export :: ordset(atom()),
+ static :: ordset(atom()),
+ safe :: ordset(atom()),
+ preserved :: boolean(),
+ no_headers :: boolean(),
+ notes :: notes(),
+ redirect :: dict(), % = dict(atom(), atom())
+ no_imports :: ordset(atom()),
+ options :: [option()]
}).
+-spec merge_sources(atom(), erl_syntax:forms(), [option()]) ->
+ {erl_syntax:syntaxTree(), [stubDescriptor()]}.
+
merge_sources(Name, Sources, Opts) ->
%% Prepare the options and the inputs.
Opts1 = Opts ++ [{export_all, false},
@@ -696,7 +726,7 @@ merge_sources(Name, Sources, Opts) ->
%% Data structure for keeping state during transformation.
--record(state, {export}).
+-record(state, {export :: set()}).
state__add_export(Name, Arity, S) ->
S#state{export = sets:add_element({Name, Arity},
@@ -981,7 +1011,7 @@ make_stubs(Modules, Renaming, Env) ->
make_stubs_1([M | Ms], Renaming, Env) ->
Name = M#module.name,
- if Name /= Env#merge.target ->
+ if Name =/= Env#merge.target ->
case ordsets:is_element(Name, Env#merge.export) of
true ->
[make_stub(M, Renaming(Name), Env)
@@ -1005,7 +1035,7 @@ make_stub(M, Map, Env) ->
%% Removing and/or out-commenting program forms. The returned form
%% sequence tree is not necessarily flat.
--record(filter, {records, file_attributes, attributes}).
+-record(filter, {records :: set(), file_attributes, attributes}).
filter_forms(Tree, Env) ->
Forms = erl_syntax:form_list_elements(
@@ -1098,8 +1128,7 @@ filter_form(F, S) ->
kill_form(F) ->
F1 = erl_syntax:set_precomments(F, []),
F2 = erl_syntax_lib:to_comment(F1, ?KILL_PREFIX),
- erl_syntax:set_precomments(F2,
- erl_syntax:get_precomments(F)).
+ erl_syntax:set_precomments(F2, erl_syntax:get_precomments(F)).
%% ---------------------------------------------------------------------
@@ -1138,8 +1167,7 @@ merge_namespaces(Modules, Env) ->
[] ->
ok;
Fs ->
- report_warning("interface functions renamed:\n\t~p.",
- [Fs])
+ report_warning("interface functions renamed:\n\t~p.", [Fs])
end,
{M4, Acc2} = merge_namespaces_1(M2, Acc1),
Ms = M3 ++ M4,
@@ -1550,20 +1578,20 @@ alias_expansions_2(Modules, Table) ->
%% Data structure for code transformation environment.
--record(code, {module, % = atom()
- target, % = atom()
- sources, % = ordset(atom())
- static, % = ordset(atom())
- safe, % = ordset(atom())
- preserved, % = bool()
- no_headers, % = bool()
- notes, % = bool()
+-record(code, {module :: atom(),
+ target :: atom(),
+ sources :: set(), % set(atom()),
+ static :: set(), % set(atom()),
+ safe :: set(), % set(atom()),
+ preserved :: boolean(),
+ no_headers :: boolean(),
+ notes :: notes(),
map, % = ({atom(), int()}) -> {atom(), int()}
renaming, % = (atom()) -> ({atom(), int()}) ->
% {atom(), int()}
- expand, % = dict({atom(), int()},
- % {atom(), {atom(), int()}})
- redirect % = dict(atom(), atom())
+ expand :: dict(), % = dict({atom(), int()},
+ % {atom(), {atom(), int()}})
+ redirect :: dict() % = dict(atom(), atom())
}).
%% `Trees' must be a list of syntax trees of type `form_list'. The
@@ -1657,8 +1685,8 @@ take_header_1([F | Fs], As) ->
section_header(Name, Tree, Env) ->
N = sets:size(Env#code.sources),
- if N > 1, Name /= Env#code.target, Env#code.notes /= no,
- Env#code.no_headers /= true ->
+ if N > 1, Name =/= Env#code.target, Env#code.notes =/= no,
+ Env#code.no_headers =/= true ->
Text = io_lib:fwrite("The following code stems "
"from module `~w'.", [Name]),
Header = comment([?COMMENT_BAR, "",
@@ -2292,11 +2320,11 @@ maybe_modified_1({value, Node1}, Node, Depth, Message, Notes) ->
%% Options:
%% <dl>
%% <dt>`{backup_suffix, string()}'</dt>
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%% <dt>`{printer, Function}'</dt>
%% <dt>`{stub_dir, filename()}'</dt>
%% <dt>`{suffix, string()}'</dt>
-%% <dt>`{verbose, bool()}'</dt>
+%% <dt>`{verbose, boolean()}'</dt>
%% </dl>
%%
%% See `merge/3' for details on these options.
@@ -2304,6 +2332,8 @@ maybe_modified_1({value, Node1}, Node, Depth, Message, Notes) ->
%% @see merge/3
%% @see merge_sources/3
+-spec create_stubs([stubDescriptor()], [option()]) -> [string()].
+
create_stubs(Stubs, Opts) ->
Opts1 = Opts ++ ?DEFAULT_MERGE_OPTS,
lists:foldl(fun (S, Fs) ->
@@ -2365,9 +2395,15 @@ stub_header(Name, Exports, Attrs) ->
%% =====================================================================
+
+-type renamings() :: [{atom(), atom()}].
+
+%% =====================================================================
%% @spec rename(Files::[filename()], Renamings) -> [string()]
%% @equiv rename(Files, Renamings, [])
+-spec rename([file:filename()], renamings()) -> [string()].
+
rename(Files, Renamings) ->
rename(Files, Renamings, []).
@@ -2408,35 +2444,35 @@ rename(Files, Renamings) ->
%% Options:
%% <dl>
%% <dt>`{backup_suffix, string()}'</dt>
-%% <dt>`{backups, bool()}'</dt>
+%% <dt>`{backups, boolean()}'</dt>
%% <dt>`{printer, Function}'</dt>
-%% <dt>`{stubs, bool()}'</dt>
+%% <dt>`{stubs, boolean()}'</dt>
%% <dt>`{suffix, string()}'</dt>
%% </dl>
%% See `merge/3' for details on these options.
%%
%% <dl>
-%% <dt>`{comments, bool()}'</dt>
-%% <dt>`{preprocess, bool()}'</dt>
+%% <dt>`{comments, boolean()}'</dt>
+%% <dt>`{preprocess, boolean()}'</dt>
%% </dl>
%% See `merge_files/4' for details on these options.
%%
%% <dl>
-%% <dt>`{no_banner, bool()}'</dt>
+%% <dt>`{no_banner, boolean()}'</dt>
%% </dl>
%% For the `rename' function, this option is
%% `true' by default. See `merge_sources/3' for
%% details.
%%
%% <dl>
-%% <dt>`{tidy, bool()}'</dt>
+%% <dt>`{tidy, boolean()}'</dt>
%% </dl>
%% For the `rename' function, this option is
%% `false' by default. See `merge_sources/3' for
%% details.
%%
%% <dl>
-%% <dt>`{no_headers, bool()}'</dt>
+%% <dt>`{no_headers, boolean()}'</dt>
%% <dt>`{stub_dir, filename()}'</dt>
%% </dl>
%% These options are preset by the `rename' function and
@@ -2448,6 +2484,8 @@ rename(Files, Renamings) ->
%% @see merge_sources/3
%% @see merge_files/4
+-spec rename([file:filename()], renamings(), [term()]) -> [string()].
+
rename(Files, Renamings, Opts) ->
Dict = case is_atom_map(Renamings) of
true ->
diff --git a/lib/syntax_tools/src/prettypr.erl b/lib/syntax_tools/src/prettypr.erl
index 4dd95a2b08..1868f63e54 100644
--- a/lib/syntax_tools/src/prettypr.erl
+++ b/lib/syntax_tools/src/prettypr.erl
@@ -50,29 +50,22 @@
%% ---------------------------------------------------------------------
-%% XXX: just an approximation
--type deep_string() :: [char() | [_]].
-
-%% XXX: poor man's document() until recursive data types are supported
--type doc() :: 'null'
- | {'text' | 'fit', _}
- | {'nest' | 'beside' | 'above' | 'union', _, _}
- | {'sep' | 'float', _, _, _}.
+-type deep_string() :: [char() | deep_string()].
%% Document structures fully implemented and available to the user:
-record(text, {s :: deep_string()}).
--record(nest, {n :: integer(), d :: doc()}).
--record(beside, {d1 :: doc(), d2 :: doc()}).
--record(above, {d1 :: doc(), d2 :: doc()}).
--record(sep, {ds :: [doc()], i = 0 :: integer(), p = false :: boolean()}).
+-record(nest, {n :: integer(), d :: document()}).
+-record(beside, {d1 :: document(), d2 :: document()}).
+-record(above, {d1 :: document(), d2 :: document()}).
+-record(sep, {ds :: [document()], i = 0 :: integer(),
+ p = false :: boolean()}).
%% Document structure which is not clear whether it is fully implemented:
--record(float, {d :: doc(), h :: integer(), v :: integer()}).
+-record(float, {d :: document(), h :: integer(), v :: integer()}).
%% Document structures not available to the user:
--record(union, {d1 :: doc(), d2 :: doc()}).
--record(fit, {d :: doc()}).
-
+-record(union, {d1 :: document(), d2 :: document()}).
+-record(fit, {d :: document()}).
%% ---------------------------------------------------------------------
%% A small warning for hackers: it's fairly easy to break this
@@ -637,43 +630,43 @@ flatrev([], As, []) ->
%% Contexts:
%%
%% #c_best_nest{w = integer(), r = integer(), i = integer()}
-%% #c_above_nest{d = doc(), i = integer(), c = ctxt()}
-%% #c_beside{d = doc(), c = ctxt()}
+%% #c_above_nest{d = document(), i = integer(), c = ctxt()}
+%% #c_beside{d = document(), c = ctxt()}
%% #c_text_beside{s = string(), c = ctxt()}
-%% #c_sep_nest{ds = [doc()], i = integer(), p = boolean(),
+%% #c_sep_nest{ds = [document()], i = integer(), p = boolean(),
%% c = ctxt()}
%% #c_best_nest_or{w = integer(), r = integer(), i = integer(),
-%% d = doc()}
+%% d = document()}
%% #c_fit{c = ctxt()}
--record(c_best_nest, {w, r, i}). %% best(w, r, nest(i, *))
+%% best(w, r, nest(i, *))
+-record(c_best_nest, {w :: integer(), r :: integer(), i :: integer()}).
--record(c_above_nest, {d, i = 0, c}). %% above(*, nest(i, d))
+%% above(*, nest(i, d))
+-record(c_above_nest, {d :: document(), i = 0 :: integer(), c :: ctxt()}).
--record(c_beside, {d, c}). %% beside(*, d)
+-record(c_beside, {d :: document(), c :: ctxt()}). %% beside(*, d)
--record(c_text_beside, {s, c}). %% beside(text(s), *)
+-record(c_text_beside, {s :: string(), c :: ctxt()}). %% beside(text(s), *)
%% p = false => sep([* | map(nest i, ds)])
%% p = true => par([* | map(nest i, ds)])
--record(c_sep_nest, {ds, i, p, c}).
+-record(c_sep_nest, {ds :: [document()], i :: integer(),
+ p :: boolean(), c :: ctxt()}).
--record(c_best_nest_or, {w, r, i, d}). %% nicest(
- %% best(w, r,
- %% nest(i, *)),
- %% best(w, r, d))
+%% nicest(best(w, r, nest(i, *)), best(w, r, d))
+-record(c_best_nest_or, {w :: integer(), r :: integer(),
+ i :: integer(), d :: document()}).
--record(c_fit, {c}). %% fit(*)
+-record(c_fit, {c :: ctxt()}). %% fit(*)
--record(c_float_beside, {d, h, v, c}). %% beside(
- %% float(d, h,
- %% v),
- %% *)
--record(c_float_above_nest, {d, h, v, i, c}). %% above(
- %% float(d, h,
- %% v),
- %% nest(i, *))
+%% beside(float(d, h, v), *)
+-record(c_float_beside, {d :: document(), h :: integer(),
+ v :: integer(), c :: ctxt()}).
+%% above(float(d, h, v), nest(i, *))
+-record(c_float_above_nest, {d :: document(), h :: integer(),
+ v :: integer(), i :: integer(), c :: ctxt()}).
%% Contexts introduced: In case:
%%
@@ -687,6 +680,11 @@ flatrev([], As, []) ->
%% c_float_beside float (c_beside)
%% c_float_above_nest float (c_above_nest)
+-type ctxt() :: #c_best_nest{} | #c_above_nest{}
+ | #c_beside{} | #c_text_beside{}
+ | #c_sep_nest{} | #c_best_nest_or{}
+ | #c_fit{} | #c_float_beside{} | #c_float_above_nest{}.
+
%% Entry point for the layout algorithm:
-spec best(document(), integer(), integer()) -> 'empty' | document().