edoc_extract.erl

来自「OTP是开放电信平台的简称」· ERL 代码 · 共 582 行 · 第 1/2 页

ERL
582
字号
%% =====================================================================%% This library is free software; you can redistribute it and/or modify%% it under the terms of the GNU Lesser General Public License as%% published by the Free Software Foundation; either version 2 of the%% License, or (at your option) any later version.%%%% This library is distributed in the hope that it will be useful, but%% WITHOUT ANY WARRANTY; without even the implied warranty of%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU%% Lesser General Public License for more details.%%%% You should have received a copy of the GNU Lesser General Public%% License along with this library; if not, write to the Free Software%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307%% USA%%%% $Id$%%%% @copyright 2001-2003 Richard Carlsson%% @author Richard Carlsson <richardc@csd.uu.se>%% @see edoc%% @end%% =====================================================================%% @doc EDoc documentation extraction.-module(edoc_extract).-export([source/3, source/4, source/5, header/3, header/4, header/5,	 file/4, text/4]).-import(edoc_report, [report/3, warning/3]).%% %% @headerfile "edoc.hrl" (disabled until it can be made private)-include("edoc.hrl").%% @type filename() = file:filename()%% @spec source(File::filename(), Env::edoc_env(), Options::proplist())%%             -> {ModuleName, edoc_module()}%%    ModuleName = atom()%%    proplist() = [term()]%%%% @doc Like {@link source/5}, but reads the syntax tree and the%% comments from the specified file.%%%% @see edoc:read_comments/2%% @see edoc:read_source/2%% @see source/4source(File, Env, Opts) ->    Forms = edoc:read_source(File, Opts),    Comments = edoc:read_comments(File, Opts),    source(Forms, Comments, File, Env, Opts).%% @spec source(Forms, Comments::[comment()], File::filename(),%%              Env::edoc_env(), Options::proplist()) ->%%           {ModuleName, edoc_module()}%%%%    Forms = syntaxTree() | [syntaxTree()]%%    comment() = {Line, Column, Indentation, Text}%%    Line = integer()%%    Column = integer()%%    Indentation = integer()%%    Text = [string()]%%    ModuleName = atom()%%%% @doc Like {@link source/4}, but first inserts the given comments in%% the syntax trees. The syntax trees must contain valid position%% information. (Cf. {@link edoc:read_comments/2}.)%%%% @see edoc:read_comments/2%% @see edoc:read_source/2%% @see source/3%% @see source/4%% @see //syntax_tools/erl_recommentsource(Forms, Comments, File, Env, Opts) when is_list(Forms) ->    Forms1 = erl_syntax:form_list(Forms),    source(Forms1, Comments, File, Env, Opts);source(Forms, Comments, File, Env, Opts) ->    Tree = erl_recomment:quick_recomment_forms(Forms, Comments),    source(Tree, File, Env, Opts).%% @spec source(Forms, File::filename(), Env::edoc_env(),%%              Options::proplist()) ->%%           {ModuleName, edoc_module()}%%%%	    Forms = syntaxTree() | [syntaxTree()]%%	    ModuleName = atom()%%          edoc_module() = edoc:edoc_module()%% @type edoc_env() = edoc_lib:edoc_env()%%%% @doc Extracts EDoc documentation from commented source code syntax%% trees. The given `Forms' must be a single syntax tree of%% type `form_list', or a list of syntax trees representing%% "program forms" (cf. {@link edoc:read_source/2}.%% `Env' is an environment created by {@link%% edoc_lib:get_doc_env/4}. The `File' argument is used for%% error reporting and output file name generation only.%%%% See {@link edoc:get_doc/2} for descriptions of the `def',%% `hidden', `private', and `todo' options.%%%% @see edoc:read_comments/2%% @see edoc:read_source/2%% @see source/5%% @see //syntax_tools/erl_recomment%% Note that the actual module name found in the source file will be%% used for generating the documentation, creating relative links, etc.%% INHERIT-OPTIONS: add_macro_defs/3%% INHERIT-OPTIONS: edoc_data:module/4source(Forms, File, Env, Opts) when is_list(Forms) ->    source(erl_syntax:form_list(Forms), File, Env, Opts);source(Tree, File0, Env, Opts) ->    Forms = preprocess_forms(Tree),    File = edoc_lib:filename(File0),    Module = get_module_info(Tree, File),    {Header, Footer, Entries} = collect(Forms, Module),    Name = Module#module.name,    Package = list_to_atom(packages:strip_last(Name)),    Env1 = Env#env{module = Name,		   package = Package,		   root = edoc_refs:relative_package_path('', Package)},    Env2 = add_macro_defs(module_macros(Env1), Opts, Env1),    Entries1 = get_tags([Header, Footer | Entries], Env2, File),    Data = edoc_data:module(Module, Entries1, Env2, Opts),    {Name, Data}.%% @spec header(File::filename(), Env::edoc_env(), Options::proplist())%%             -> {ok, Tags} | {error, Reason}%%   Tags = [term()]%%   Reason = term()%%%% @doc Similar to {@link header/5}, but reads the syntax tree and the%% comments from the specified file.%%%% @see edoc:read_comments/2%% @see edoc:read_source/2%% @see header/4header(File, Env, Opts) ->    Forms = edoc:read_source(File),    Comments = edoc:read_comments(File),    header(Forms, Comments, File, Env, Opts).%% @spec header(Forms, Comments::[comment()], File::filename(),%%              Env::edoc_env(), Options::proplist()) ->%%       {ok, Tags} | {error, Reason}%%   Forms = syntaxTree() | [syntaxTree()]%%   Tags = [term()]%%   Reason = term()%%%% @doc Similar to {@link header/4}, but first inserts the given%% comments in the syntax trees. The syntax trees must contain valid%% position information. (Cf. {@link edoc:read_comments/2}.)%%%% @see header/3%% @see header/4%% @see //syntax_tools/erl_recommentheader(Forms, Comments, File, Env, Opts) when is_list(Forms) ->    Forms1 = erl_syntax:form_list(Forms),    header(Forms1, Comments, File, Env, Opts);header(Forms, Comments, File, Env, Opts) ->    Tree = erl_recomment:quick_recomment_forms(Forms, Comments),    header(Tree, File, Env, Opts).%% @spec header(Forms, File::filename(), Env::edoc_env(),%%              Options::proplist()) ->%%       {ok, Tags} | {error, Reason}%%   Forms = syntaxTree() | [syntaxTree()]%%   Tags = [term()]%%   Reason = term()%%%% @doc Extracts EDoc documentation from commented header file syntax%% trees. Similar to {@link source/5}, but ignores any documentation%% that occurs before a module declaration or a function definition.%% (Warning messages are printed if content may be ignored.) `Env' is%% assumed to already be set up with a suitable module context.%%%% @see header/5%% @see //syntax_tools/erl_recommentheader(Forms, File, Env, Opts) when is_list(Forms) ->    header(erl_syntax:form_list(Forms), File, Env, Opts);header(Tree, File0, Env, _Opts) ->    Forms = preprocess_forms(Tree),    File = edoc_lib:filename(File0),    Module = #module{name = Env#env.module},  % a dummy module record    %% We take only "footer" tags, i.e., any kind of definition will    %% kill all the information above it up to that point. Then we call    %% this the 'header' to make error reports make better sense.    {Header, Footer, Entries} = collect(Forms, Module),    if Header#entry.data /= [] ->	    warning(File, "documentation before module declaration is ignored by @headerfile", []);       true -> ok    end,    if Entries /= [] ->	    warning(File, "documentation before function definitions is ignored by @headerfile", []);       true -> ok    end,    [Entry] = get_tags([Footer#entry{name = header}], Env, File),    Entry#entry.data.%% NEW-OPTIONS: def%% DEFER-OPTIONS: source/4add_macro_defs(Defs0, Opts, Env) ->    Defs = proplists:append_values(def, Opts),    edoc_macros:check_defs(Defs),    Env#env{macros = Defs ++ Defs0 ++ Env#env.macros}.%% @spec file(File::filename(), Context, Env::edoc_env(),%%            Options::proplist()) -> {ok, Tags} | {error, Reason}%%   Context = overview | package%%   Tags = [term()]%%   Reason = term()%%%% @doc Reads a text file and returns the list of tags in the file. Any%% lines of text before the first tag are ignored. `Env' is an%% environment created by {@link edoc_lib:get_doc_env/4}. Upon error,%% `Reason' is an atom returned from the call to {@link%% //kernel/file:read_file/1}.%%%% See {@link text/4} for options.%% INHERIT-OPTIONS: text/4file(File, Context, Env, Opts) ->    case file:read_file(File) of	{ok, Bin} ->	    {ok, text(binary_to_list(Bin), Context, Env, Opts, File)};	{error, R} ->	    {error, R}    end.%% @spec (Text::string(), Context, Env::edoc_env(),%%        Options::proplist()) -> Tags%%     Context = overview | package%%     Tags = [term()]%%%% @doc Returns the list of tags in the text. Any lines of text before%% the first tag are ignored. `Env' is an environment created by {@link%% edoc_lib:get_doc_env/4}.%%%% See {@link source/4} for a description of the `def' option.%% INHERIT-OPTIONS: add_macro_defs/3%% DEFER-OPTIONS: source/4text(Text, Context, Env, Opts) ->    text(Text, Context, Env, Opts, "").text(Text, Context, Env, Opts, Where) ->    Env1 = add_macro_defs(file_macros(Context, Env), Opts, Env),    Cs = edoc_lib:lines(Text),    Ts0 = edoc_tags:scan_lines(Cs, 1),    Tags = sets:from_list(edoc_tags:tag_names()),    Ts1 = edoc_tags:filter_tags(Ts0, Tags, Where),    Single = sets:from_list(edoc_tags:tags(single)),    Allow = sets:from_list(edoc_tags:tags(Context)),    case edoc_tags:check_tags(Ts1, Allow, Single, Where) of	true ->	    exit(error);	false ->	    Ts2 = edoc_macros:expand_tags(Ts1, Env1, Where),	    How = dict:from_list(edoc_tags:tag_parsers()),	    edoc_tags:parse_tags(Ts2, How, Env1, Where)    end.%% @spec (Forms::[syntaxTree()], File::filename()) -> moduleInfo()%% @doc Initialises a module-info record with data about the module%% represented by the list of forms. Exports are guaranteed to exist in%% the set of defined names.get_module_info(Forms, File) ->    L = case catch {ok, erl_syntax_lib:analyze_forms(Forms)} of	    {ok, L1} ->		L1;	    syntax_error ->		report(File, "syntax error in input.", []),		exit(error);	    {'EXIT', R} ->

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?