diff options
Diffstat (limited to 'lib/syntax_tools')
-rw-r--r-- | lib/syntax_tools/Makefile | 6 | ||||
-rw-r--r-- | lib/syntax_tools/doc/Makefile | 2 | ||||
-rw-r--r-- | lib/syntax_tools/doc/src/Makefile | 14 | ||||
-rw-r--r-- | lib/syntax_tools/doc/src/notes.xml | 37 | ||||
-rw-r--r-- | lib/syntax_tools/examples/Makefile | 2 | ||||
-rw-r--r-- | lib/syntax_tools/src/Makefile | 17 | ||||
-rw-r--r-- | lib/syntax_tools/src/epp_dodger.erl | 71 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_comment_scan.erl | 18 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_prettypr.erl | 55 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_recomment.erl | 45 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_syntax.erl | 582 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_syntax_lib.erl | 150 | ||||
-rw-r--r-- | lib/syntax_tools/src/erl_tidy.erl | 32 | ||||
-rw-r--r-- | lib/syntax_tools/src/igor.erl | 162 | ||||
-rw-r--r-- | lib/syntax_tools/src/prettypr.erl | 74 | ||||
-rw-r--r-- | lib/syntax_tools/vsn.mk | 2 |
16 files changed, 1022 insertions, 247 deletions
diff --git a/lib/syntax_tools/Makefile b/lib/syntax_tools/Makefile index 08ede67209..37e84a80a5 100644 --- a/lib/syntax_tools/Makefile +++ b/lib/syntax_tools/Makefile @@ -58,10 +58,10 @@ include $(ERL_TOP)/make/otp_subdir.mk version: @echo "$(VSN)" -docs: - erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop +# The overriding "docs" target have been removed so the default make rules work properly. -edocs: docs +edocs: + erl -noshell -pa "$(BINDIR)" -run edoc_run application "'$(APPNAME)'" '"."' '$(DOC_OPTS)' -s init stop app_release: tar 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/doc/src/Makefile b/lib/syntax_tools/doc/src/Makefile index 2065614251..291b3e3047 100644 --- a/lib/syntax_tools/doc/src/Makefile +++ b/lib/syntax_tools/doc/src/Makefile @@ -1,19 +1,19 @@ # # %CopyrightBegin% -# -# Copyright Ericsson AB 2006-2009. All Rights Reserved. -# +# +# Copyright Ericsson AB 2006-2010. All Rights Reserved. +# # The contents of this file are subject to the Erlang Public License, # Version 1.1, (the "License"); you may not use this file except in # compliance with the License. You should have received a copy of the # Erlang Public License along with this software. If not, it can be # retrieved online at http://www.erlang.org/. -# +# # Software distributed under the License is distributed on an "AS IS" # basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See # the License for the specific language governing rights and limitations # under the License. -# +# # %CopyrightEnd% # include $(ERL_TOP)/make/target.mk @@ -101,10 +101,10 @@ html: gifs $(HTML_REF_MAN_FILE) man: $(MAN3_FILES) $(XML_REF3_FILES): - docb_gen $(SRC_DIR)/$(@:%.xml=%.erl) + escript $(DOCGEN)/priv/bin/xml_from_edoc.escript $(SRC_DIR)/$(@:%.xml=%.erl) $(XML_CHAPTER_FILES): - docb_gen -chapter -def vsn $(VSN) ../overview.edoc + escript $(DOCGEN)/priv/bin/xml_from_edoc.escript -def vsn $(VSN) -chapter ../overview.edoc gifs: $(GIF_FILES:%=$(HTMLDIR)/%) diff --git a/lib/syntax_tools/doc/src/notes.xml b/lib/syntax_tools/doc/src/notes.xml index 8fe21c8859..a3b842b50b 100644 --- a/lib/syntax_tools/doc/src/notes.xml +++ b/lib/syntax_tools/doc/src/notes.xml @@ -4,7 +4,7 @@ <chapter> <header> <copyright> - <year>2007</year><year>2009</year> + <year>2007</year><year>2010</year> <holder>Ericsson AB. All Rights Reserved.</holder> </copyright> <legalnotice> @@ -13,12 +13,12 @@ compliance with the License. You should have received a copy of the Erlang Public License along with this software. If not, it can be retrieved online at http://www.erlang.org/. - + Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. - + </legalnotice> <title>Syntax_Tools Release Notes</title> @@ -31,6 +31,37 @@ <p>This document describes the changes made to the Syntax_Tools application.</p> +<section><title>Syntax_Tools 1.6.5</title> + + <section><title>Improvements and New Features</title> + <list> + <item> + <p>The documentation is now possible to build in an open + source environment after a number of bugs are fixed and + some features are added in the documentation build + process. </p> + <p>- The arity calculation is updated.</p> + <p>- The module prefix used in the function names for + bif's are removed in the generated links so the links + will look like + "http://www.erlang.org/doc/man/erlang.html#append_element-2" + instead of + "http://www.erlang.org/doc/man/erlang.html#erlang:append_element-2".</p> + <p>- Enhanced the menu positioning in the html + documentation when a new page is loaded.</p> + <p>- A number of corrections in the generation of man + pages (thanks to Sergei Golovan)</p> + <p>- The legal notice is taken from the xml book file so + OTP's build process can be used for non OTP + applications.</p> + <p> + Own Id: OTP-8343</p> + </item> + </list> + </section> + +</section> + <section><title>Syntax_Tools 1.6.4</title> <section><title>Improvements and New Features</title> 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 5ffe85c975..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 \ @@ -34,15 +37,15 @@ OBJECTS=$(SOURCES:%.erl=$(EBIN)/%.$(EMULATOR)) $(APP_TARGET) $(APPUP_TARGET) APP_FILE= syntax_tools.app APP_SRC= $(APP_FILE).src APP_TARGET= $(EBIN)/$(APP_FILE) - + APPUP_FILE= syntax_tools.appup APPUP_SRC= $(APPUP_FILE).src APPUP_TARGET= $(EBIN)/$(APPUP_FILE) - + # ---------------------------------------------------- # Targets # ---------------------------------------------------- - + debug opt: $(OBJECTS) all: $(OBJECTS) @@ -52,6 +55,8 @@ clean: rm -f $(OBJECTS) rm -f core *~ +docs: + distclean: clean realclean: clean @@ -62,10 +67,10 @@ $(EBIN)/%.$(EMULATOR):%.erl # ---------------------------------------------------- # Special Build Targets # ---------------------------------------------------- - + $(APP_TARGET): $(APP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ - + $(APPUP_TARGET): $(APPUP_SRC) ../vsn.mk sed -e 's;%VSN%;$(VSN);' $< > $@ 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(). diff --git a/lib/syntax_tools/vsn.mk b/lib/syntax_tools/vsn.mk index 53c13440f3..2ba5eac582 100644 --- a/lib/syntax_tools/vsn.mk +++ b/lib/syntax_tools/vsn.mk @@ -1 +1 @@ -SYNTAX_TOOLS_VSN = 1.6.4 +SYNTAX_TOOLS_VSN = 1.6.5 |