⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xref_base.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 4 页
字号:
%% ``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 via the world wide web 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.%% %% The Initial Developer of the Original Code is Ericsson Utvecklings AB.%% Portions created by Ericsson are Copyright 2000, Ericsson Utvecklings%% AB. All Rights Reserved.''%% %%     $Id $%%-module(xref_base).-export([new/0, new/1, delete/1,	 add_directory/2, add_directory/3,	 add_module/2, add_module/3,	 add_application/2, add_application/3,	 replace_module/3, replace_module/4,	 replace_application/3, replace_application/4,	 remove_module/2, remove_application/2, remove_release/2,	 add_release/2, add_release/3,	 get_library_path/1, set_library_path/2, set_library_path/3,	 set_up/1, set_up/2,	 q/2, q/3, info/1, info/2, info/3, update/1, update/2, 	 forget/1, forget/2, variables/1, variables/2,	 analyze/2, analyze/3, analysis/1,	 get_default/2, set_default/3,	 get_default/1, set_default/2]).-export([format_error/1]).%% The following functions are exported for testing purposes only:-export([do_add_module/4, do_add_application/2, do_add_release/2, 	 do_remove_module/2]).-import(lists, 	[filter/2, flatten/1, foldl/3, keysearch/3, map/2, mapfoldl/3,          member/2, reverse/1, sort/1, usort/1]).-import(sofs, 	[constant_function/2, converse/1, difference/2, domain/1,         empty_set/0, family/1, family_difference/2, intersection/2,         family_projection/2, family_to_relation/1, family_union/1,         family_union/2, from_sets/1, from_term/1, a_function/1,         image/2, family_intersection/2, inverse/1, is_empty_set/1,         multiple_relative_product/2, no_elements/1,         partition_family/2, projection/2, range/1, relation/1,         relation_to_family/1, relative_product1/2, restriction/2,         restriction/3, set/1, specification/2, substitution/2,         to_external/1, union/1, union/2, union_of_family/1]).-include("xref.hrl").-define(Suffix, ".beam").%-define(debug, true).-ifdef(debug).-define(FORMAT(P, A), io:format(P, A)).-else.-define(FORMAT(P, A), ok).-endif.%%%%  Exported functions%%new() ->    new([]).%% -> {ok, InitialState}new(Options) ->    Modes = [functions,modules,function,module],    case xref_utils:options(Options, [{xref_mode,Modes}]) of	{[[function]], []} ->	    {ok, #xref{mode = functions}};	{[[module]], []} ->	    {ok, #xref{mode = modules}};	{[[OM]], []} ->	    {ok, #xref{mode = OM}};	_ ->	    error({invalid_options, Options})    end.%% -> ok%% Need not be called by the server.delete(State) when State#xref.variables =:= not_set_up ->    ok;delete(State) ->    Fun = fun({X, _}) ->		  case catch digraph:info(X) of		      Info when is_list(Info) ->			  true = digraph:delete(X);		      _Else ->			  ok		  end	     end,    map(Fun, dict:to_list(State#xref.variables)),    ok.add_directory(State, Dir) ->    add_directory(State, Dir, []).    %% -> {ok, Modules, NewState} | Erroradd_directory(State, Dir, Options) ->    ValOptions = option_values([builtins, recurse, verbose, warnings], State),    case xref_utils:options(Options, ValOptions) of	{[[OB], [OR], [OV], [OW]], []} ->	    catch do_add_directory(Dir, [], OB, OR, OV, OW, State);	_ ->	    error({invalid_options, Options})    end.add_module(State, File) ->    add_module(State, File, []).%% -> {ok, Module, NewState} | Erroradd_module(State, File, Options) ->    ValOptions = option_values([builtins, verbose, warnings], State),    case xref_utils:options(Options, ValOptions) of	{[[OB], [OV], [OW]], []} ->	    case catch do_add_a_module(File, [], OB, OV, OW, State) of		{ok, [Module], NewState} ->		    {ok, Module, NewState};		{ok, [], _NewState} ->		    error({no_debug_info, File});		Error ->		    Error	    end;	_ ->	    error({invalid_options, Options})    end.add_application(State, AppDir) ->    add_application(State, AppDir, []).%% -> {ok, AppName, NewState} | Erroradd_application(State, AppDir, Options) ->    OptVals = option_values([builtins, verbose, warnings], State),    ValidOptions = [{name, ["", fun check_name/1]} | OptVals],    case xref_utils:options(Options, ValidOptions) of	{[ApplName, [OB], [OV], [OW]], []} ->	    catch do_add_application(AppDir, [], ApplName, OB, OV, OW, State);	_ ->	    error({invalid_options, Options})    end.replace_module(State, Module, File) ->    replace_module(State, Module, File, []).%% -> {ok, Module, NewState} | Errorreplace_module(State, Module, File, Options) ->    ValidOptions = option_values([verbose, warnings], State),    case xref_utils:options(Options, ValidOptions) of	{[[OV], [OW]], []} ->	    catch do_replace_module(Module, File, OV, OW, State);	_ ->	    error({invalid_options, Options})    end.replace_application(State, Appl, Dir) ->    replace_application(State, Appl, Dir, []).%% -> {ok, AppName, NewState} | Errorreplace_application(State, Appl, Dir, Options) ->    ValidOptions = option_values([builtins, verbose, warnings], State),    case xref_utils:options(Options, ValidOptions) of	{[[OB], [OV], [OW]], []} ->	    catch do_replace_application(Appl, Dir, OB, OV, OW, State);	_ ->	    error({invalid_options, Options})    end.%% -> {ok, NewState} | Errorremove_module(State, Mod) when is_atom(Mod) ->    remove_module(State, [Mod]);remove_module(State, [Mod | Mods]) ->    case catch do_remove_module(State, Mod) of	{ok, _OldXMod, NewState} ->	    remove_module(NewState, Mods);	Error ->	    Error    end;remove_module(State, []) ->    {ok, State}.%% -> {ok, NewState} | Errorremove_application(State, Appl) when is_atom(Appl) ->    remove_application(State, [Appl]);remove_application(State, [Appl | Appls]) ->    case catch do_remove_application(State, Appl) of	{ok, _OldXApp, NewState} ->	    remove_application(NewState, Appls);	Error ->	    Error    end;remove_application(State, []) ->    {ok, State}.%% -> {ok, NewState} | Errorremove_release(State, Rel) when is_atom(Rel) ->    remove_release(State, [Rel]);remove_release(State, [Rel | Rels]) ->    case catch do_remove_release(State, Rel) of	{ok, _OldXRel, NewState} ->	    remove_release(NewState, Rels);	Error ->	    Error    end;remove_release(State, []) ->    {ok, State}.add_release(State, RelDir) ->    add_release(State, RelDir, []).%% -> {ok, ReleaseName, NewState} | Erroradd_release(State, RelDir, Options) ->    ValidOptions0 = option_values([builtins, verbose, warnings], State),    ValidOptions = [{name, ["", fun check_name/1]} | ValidOptions0],    case xref_utils:options(Options, ValidOptions) of	{[RelName, [OB], [OV], [OW]], []} ->	    catch do_add_release(RelDir, RelName, OB, OV, OW, State);	_ ->	    error({invalid_options, Options})    end.get_library_path(State) ->    {ok, State#xref.library_path}.set_library_path(State, Path) ->    set_library_path(State, Path, []).%% -> {ok, NewState} | Errorset_library_path(State, code_path, _Options) ->    S1 = State#xref{library_path = code_path, libraries = dict:new()},    {ok, take_down(S1)};set_library_path(State, Path, Options) ->    case xref_utils:is_path(Path) of	true ->	    ValidOptions = option_values([verbose], State),	    case xref_utils:options(Options, ValidOptions) of		{[[OV]], []} ->		    do_add_libraries(Path, OV, State);		_ ->		    error({invalid_options, Options})	    end;	false ->	    error({invalid_path, Path})    end.set_up(State) ->    set_up(State, []).%% -> {ok, NewState} | Errorset_up(State, Options) ->    ValidOptions = option_values([verbose], State),    case xref_utils:options(Options, ValidOptions) of	{[[Verbose]], []} ->	    do_set_up(State, Verbose);	_ ->	    error({invalid_options, Options})    end.q(S, Q) ->    q(S, Q, []).%% -> {{ok, Answer}, NewState} | {Error, NewState}q(S, Q, Options) when is_atom(Q) ->    q(S, atom_to_list(Q), Options);q(S, Q, Options) ->    case xref_utils:is_string(Q, 1) of	true -> 	    case set_up(S, Options) of		{ok, S1} ->		    case xref_compiler:compile(Q, S1#xref.variables) of			{NewT, Ans} ->			    {{ok, Ans}, S1#xref{variables = NewT}};			Error ->			    {Error, S1}		    end;		Error ->		    {Error, S}	    end;	false ->	    {error({invalid_query, Q}), S}    end.%% -> InfoListinfo(State) ->    D0 = sort(dict:to_list(State#xref.modules)),    D = map(fun({_M, XMod}) -> XMod end, D0),    NoApps = length(dict:to_list(State#xref.applications)),    NoRels = length(dict:to_list(State#xref.releases)),    No = no_sum(State, D),    [{library_path, State#xref.library_path}, {mode, State#xref.mode},     {no_releases, NoRels}, {no_applications, NoApps}] ++ No.info(State, What) ->    do_info(State, What).%% -> [{what(), InfoList}]info(State, What, Qual) ->    catch do_info(State, What, Qual).update(State) ->    update(State, []).%% -> {ok, NewState, Modules} | Errorupdate(State, Options) ->    ValidOptions = option_values([verbose, warnings], State),    case xref_utils:options(Options, ValidOptions) of	{[[OV],[OW]], []} ->	    catch do_update(OV, OW, State);	_ ->	    error({invalid_options, Options})    end.%% -> {ok, NewState}forget(State) ->    {U, _P} = do_variables(State),    {ok, foldl(fun(V, S) -> {ok, NS} = forget(S, V), NS end, State, U)}.%% -> {ok, NewState} | Errorforget(State, Variable) when State#xref.variables =:= not_set_up ->    error({not_user_variable, Variable});forget(State, Variable) when is_atom(Variable) ->    forget(State, [Variable]);forget(State, Variables) ->    Vars = State#xref.variables,    do_forget(Variables, Vars, Variables, State).    variables(State) ->    variables(State, [user]).%% -> {{ok, Answer}, NewState} | {Error, NewState}%% Answer = [{vartype(), [VariableName]}]variables(State, Options) ->    ValidOptions = option_values([verbose], State),    case xref_utils:options(Options, [user, predefined | ValidOptions]) of	{[User,Predef,[OV]],[]} ->	    case do_set_up(State, OV) of		{ok, NewState} ->		    {U, P} = do_variables(NewState),		    R1 = if User -> [{user, U}]; true -> [] end,		    R = if 			    Predef -> [{predefined,P} | R1]; 			    true -> R1 			end,		    {{ok, R}, NewState};		Error ->		    {Error, State}	    end;	_ ->	    {error({invalid_options, Options}), State}    end.analyze(State, Analysis) ->    analyze(State, Analysis, []).%% -> {{ok, Answer}, NewState} | {Error, NewState}analyze(State, Analysis, Options) ->    case analysis(Analysis, State#xref.mode) of	P when is_list(P) -> 	    q(State, P, Options);	error ->	    R = case analysis(Analysis, functions) of		    error -> unknown_analysis;		    P when is_list(P) -> unavailable_analysis		end,	    Error = error({R, Analysis}),	    {Error, State}    end.analysis(Analysis) ->    analysis(Analysis, functions).%% -> string() | Erroranalysis(undefined_function_calls, functions) ->    "(XC - UC) || (XU - X - B)";analysis(undefined_functions, modules) ->    %% "XU * (L + U)" is equivalent, but the following works when L is    %% not available.    "XU - X - B";analysis(undefined_functions, functions) ->    %% "XU * ((L + U) - range UC)" is equivalent.    "XU - range UC - X - B";analysis(locals_not_used, functions) ->    %% The Inter Call Graph is used to get local functions that are not    %% used (indirectly) from any export: "(domain EE + range EE) * L".    %% But then we only get locals that make some calls, so we add    %% locals that are not used at all: "L * (UU + XU - LU)".    "L * ((UU + XU - LU) + domain EE + range EE)";analysis(exports_not_used, _) ->    %% Local calls are not considered here. "X * UU" would do otherwise.    "X - XU";analysis({call, F}, functions) ->    make_query("range (E | ~w : Fun)", [F]);analysis({use, F}, functions) ->    make_query("domain (E || ~w : Fun)", [F]);analysis({module_call, M}, _) ->    make_query("range (ME | ~w : Mod)", [M]);analysis({module_use, M}, _) ->    make_query("domain (ME || ~w : Mod)", [M]);analysis({application_call, A}, _) ->    make_query("range (AE | ~w : App)", [A]);analysis({application_use, A}, _) ->    make_query("domain (AE || ~w : App)", [A]);analysis({release_call, R}, _) ->    make_query("range (RE | ~w : Rel)", [R]);analysis({release_use, R}, _) ->    make_query("domain (RE || ~w : Rel)", [R]);analysis(deprecated_function_calls, functions) ->    "XC || DF";analysis({deprecated_function_calls,Flag}, functions) ->    case deprecated_flag(Flag) of        undefined -> error;        I -> make_query("XC || DF_~w", [I])    end;analysis(deprecated_functions, _) ->    "XU * DF";analysis({deprecated_functions,Flag}, _) ->    case deprecated_flag(Flag) of        undefined -> error;        I -> make_query("XU * DF_~w", [I])    end;analysis(_, _) ->    error.%% -> {ok, OldValue, NewState} | Errorset_default(State, Option, Value) ->    case get_default(State, Option) of	{ok, OldValue} ->	    Values = option_values([Option], State),	    case xref_utils:options([{Option,Value}], Values) of		{_, []} ->		    NewState = set_def(Option, Value, State),		    {ok, OldValue, NewState};		{_, Unknown} ->		    error({invalid_options, Unknown})	    end;	Error ->	    Error    end.

⌨️ 快捷键说明

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