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

📄 igor.erl

📁 OTP是开放电信平台的简称
💻 ERL
📖 第 1 页 / 共 5 页
字号:
    case sets:is_element(M, Forbid) of	true ->	    false;	false ->	    not sets:is_element(A, Names)    end.%% In this second stage, we resolve any conflicts that may remain%% because of distinct source modules still containing distinct alias%% definitions of the same name - in that case we remove *all* of them%% (mainly for symmetry).alias_expansions_2(Modules, Table) ->    %% Get the set of all alias definitions in all modules (collapsing    %% duplicated but equivalent definitions).    Aliases = lists:foldl(		fun (M, A) ->			ordsets:union(A, M#module.aliases)		end,		ordsets:new(), Modules),        %% Get the set of names with multiple (distinct) definitions.    Names = duplicates([F || {F, _} <- Aliases]),        %% Go through all aliases in all source modules and add necessary    %% entries to the expansion-table. We expect that there is an entry    %% in the table here for each module.    lists:foldl(      fun (M, T) ->	      N = M#module.name,	      lists:foldl(		fun ({A, F}, T1) ->			case ordsets:is_element(A, Names) of			    true ->				T2 = dict:fetch(N, T1),				dict:store(N,					   dict:store(A, F, T2),					   T1);			    false ->				T1			end		end,		T, M#module.aliases)      end,      Table, Modules).%% ---------------------------------------------------------------------%% Merging the source code.%% 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()	       map,		% = ({atom(), int()}) -> {atom(), int()}	       renaming,	% = (atom()) -> ({atom(), int()}) ->				%               {atom(), int()}	       expand,		% = dict({atom(), int()},				%      {atom(), {atom(), int()}})	       redirect		% = dict(atom(), atom())	      }).%% `Trees' must be a list of syntax trees of type `form_list'. The%% result is a pair `{Result, Header}' where `Result' is a `form_list'%% tree representing the merged code, and if the `preserved' flag is%% set, `Header' is the list of forms up to and including the first%% `-module(...)' declaration, but stripped of any `-file(...)'%% attributes - otherwise `Header' is an empty list.merge_code(Trees, Modules, Expansions, Renaming, Env, St) ->    Env1 = #code{target = Env#merge.target,		 sources = sets:from_list(Env#merge.sources),		 static = sets:from_list(Env#merge.static),		 safe = sets:from_list(Env#merge.safe),		 preserved = Env#merge.preserved,		 no_headers = Env#merge.no_headers,		 notes = Env#merge.notes,		 redirect = Env#merge.redirect,		 renaming = Renaming},    Code = order_code(Modules, Trees, Env1),    {Code1, Header} = case Env1#code.preserved of			  true ->			      take_header(Code);			  false ->			      {Code, erl_syntax:form_list([])}		      end,    {Forms, St1} = merge_code_1(Code1, Expansions, Env1, St),    Tree = erl_syntax:form_list(Forms),    {Tree, Header, St1}.merge_code_1(Code, Expansions, Env, St) ->      lists:foldr(	fun ({Module, T}, {Acc, St0}) ->		M = Module#module.name,		Expand = case dict:find(M, Expansions) of			     {ok, Dict} -> Dict;			     error -> dict:new()			 end,		Env1 = Env#code{module = M,				map = (Env#code.renaming)(M),				expand = Expand},		{T1, St1} = transform(T, Env1, St0),		{[section_header(M, T1, Env1) | Acc], St1}	end,	{[], St}, Code).%% Pair module info and source code, in the order we want, and flatten%% the form lists. If the name of the target is the same as one of the%% source modules, and the result should preserve the original module,%% the code for that module should be first in the output.order_code(Modules, Trees, Env) ->    order_code(Modules, Trees, {}, [], Env).order_code([M | Ms], [T | Ts], First, Rest, Env) ->    T1 = erl_syntax:flatten_form_list(T),    case (M#module.name == Env#code.target) and	Env#code.preserved of	true ->	    order_code(Ms, Ts, {M, T1}, Rest, Env);	false ->	    order_code(Ms, Ts, First, [{M, T1} | Rest], Env)    end;order_code([], [], First, Rest, _Env) ->    Rest1 = lists:reverse(Rest),    case First of	{} ->	    Rest1;	M ->	    [M | Rest1]    end.%% Extracting the "original" header (the `-module(...)' declaration is%% sure to exist).take_header([{M, T} | Ms]) ->    Fs = erl_syntax:form_list_elements(T),    {Header, Fs1} = take_header_1(Fs, []),    T1 = erl_syntax:form_list(Fs1),    {[{M, T1} | Ms], Header}.take_header_1([F | Fs], As) ->    case erl_syntax_lib:analyze_form(F) of	{'attribute', {'module', _}} ->	    {lists:reverse([F | As]), Fs};    % done	{'attribute', {'file', _}} ->	    take_header_1(Fs, As);    % discard	_ ->	    take_header_1(Fs, [F | As])    % keep    end.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 ->	    Text = io_lib:fwrite("The following code stems "				 "from module `~w'.", [Name]),	    Header = comment([?COMMENT_BAR, "",			      lists:flatten(Text), ""]),	    erl_syntax:form_list([Header, Tree]);       true ->	    Tree    end.transform(Tree, Env, St) ->    case erl_syntax:type(Tree) of	application ->	    transform_application(Tree, Env, St);	attribute ->	    transform_attribute(Tree, Env, St);  	function ->  	    transform_function(Tree, Env, St); 	implicit_fun -> 	    transform_implicit_fun(Tree, Env, St);  	rule ->  	    transform_rule(Tree, Env, St);  	record_expr ->  	    transform_record(Tree, Env, St);  	record_index_expr ->  	    transform_record(Tree, Env, St);  	record_access ->  	    transform_record(Tree, Env, St);	_ ->	    default_transform(Tree, Env, St)    end.default_transform(Tree, Env, St) ->    case erl_syntax:subtrees(Tree) of	[] ->	    {Tree, St};	Gs ->	    {Gs1, St1} = transform_1(Gs, Env, St),	    Tree1 = rewrite(Tree, erl_syntax:make_tree(				    erl_syntax:type(Tree),				    Gs1)),	    {Tree1, St1}    end.transform_1([G | Gs], Env, St) ->    {G1, St1} = transform_list(G, Env, St),    {Gs1, St2} = transform_1(Gs, Env, St1),    {[G1 | Gs1], St2};transform_1([], _Env, St) ->    {[], St}.transform_list([T | Ts], Env, St) ->    {T1, St1} = transform(T, Env, St),    {Ts1, St2} = transform_list(Ts, Env, St1),    {[T1 | Ts1], St2};transform_list([], _Env, St) ->    {[], St}.%% Renaming function definitionstransform_function(T, Env, St) ->    {T1, St1} = default_transform(T, Env, St),    F = erl_syntax_lib:analyze_function(T1),    {V, Text} = case (Env#code.map)(F) of		    F ->			%% Not renamed			{none, []};		    {Atom, _Arity} ->			%% Renamed			Cs = erl_syntax:function_clauses(T1),			N = rename_atom(			      erl_syntax:function_name(T1),			      Atom),			T2 = erl_syntax:function(N, Cs),			{{value, T2}, renaming_note(Atom)}		end,    {maybe_modified(V, T1, 2, Text, Env), St1}.renaming_note(Name) ->    [lists:flatten(io_lib:fwrite("renamed function to `~w'",				 [Name]))].rename_atom(Node, Atom) ->    rewrite(Node, erl_syntax:atom(Atom)).%% Renaming Mnemosyne rules (just like function definitions)transform_rule(T, Env, St) ->    {T1, St1} = default_transform(T, Env, St),    F = erl_syntax_lib:analyze_rule(T1),    {V, Text} = case (Env#code.map)(F) of		    F ->			%% Not renamed			{none, []};		    {Atom, _Arity} ->			%% Renamed			Cs = erl_syntax:rule_clauses(T1),			N = rename_atom(			      erl_syntax:rule_name(T1),			      Atom),			T2 = rewrite(T1,				     erl_syntax:rule(N, Cs)),			{{value, T2}, renaming_note(Atom)}		end,    {maybe_modified(V, T1, 2, Text, Env), St1}.%% Renaming "implicit fun" expressions (done quietly).transform_implicit_fun(T, Env, St) ->    {T1, St1} = default_transform(T, Env, St),    F = erl_syntax_lib:analyze_implicit_fun(T1),    {V, Text} = case (Env#code.map)(F) of		    F ->			%% Not renamed			{none, []};		    {Atom, Arity} ->			%% Renamed			N = rewrite(			      erl_syntax:implicit_fun_name(T1),			      erl_syntax:arity_qualifier(				erl_syntax:atom(Atom),				erl_syntax:integer(Arity))),			T2 = erl_syntax:implicit_fun(N),			{{value, T2}, ["function was renamed"]}		end,    {maybe_modified_quiet(V, T1, 2, Text, Env), St1}.%% Transforming function applicationstransform_application(T, Env, St) ->    %% We transform the arguments first, so we can concentrate on the    %% application itself after that point.    {As, St1} = transform_list(		  erl_syntax:application_arguments(T),		  Env, St),    F = erl_syntax:application_operator(T),    %% See if the operator is an explicit function name.    %% (Usually, this will be the case.)    case catch {ok, erl_syntax_lib:analyze_function_name(F)} of	{ok, Name} ->	    transform_application_1(Name, F, As, T, Env, St1);	syntax_error ->	    %% Oper is not a function name, but might be any other	    %% expression - we just visit it and reassemble the	    %% application.	    %% We do not handle applications of tuples `{M, F}'.	    {F1, St2} = transform(F, Env, St1),	    {rewrite(T, erl_syntax:application(F1, As)), St2};	{'EXIT', R} ->	    exit(R);	R ->	    throw(R)    end.%% At this point we should have an explicit function name, which might%% or might not be qualified by a module name.transform_application_1(Name, F, As, T, Env, St) ->    %% Before doing anything else, we must unfold any uses of aliases    %% whose definitions have been killed.    Arity = length(As),    {Name1, F1} = expand_operator(Name, Arity, F, Env),    F2 = maybe_modified_quiet(F1, F, 7, ["unfolded alias"], Env),    {V, St1} = transform_application_2(Name1, Arity, F2, As, Env,				       St),    T1 = rewrite(T, erl_syntax:application(F2, As)),    T3 = case V of	     none ->		 T1;	     {value, {T2, Depth, Message}} ->		 maybe_modified_quiet({value, T2}, T1, Depth,				      Message, Env)	 end,    {T3, St1}.%% Here, Name has been expanded if necessary (if so, this is also%% reflected by F), and As have been transformed. We should return%% `{none, State}' if no further rewriting is necessary, and otherwise%% `{{value, {Tree, Depth, Message}}, State}', where `Depth' and%% `Message' are to be passed to `maybe_modified'.transform_application_2(Name, Arity, F, As, Env, St)  when is_atom(Name) ->    transform_atom_application(Name, Arity, F, As, Env, St);transform_application_2({M, N}, Arity, F, As, Env, St)  when is_atom(M), is_atom(N) ->    transform_qualified_application(M, N, Arity, F, As, Env, St);transform_application_2(_Name, _Arity, _F, _As, _Env, St) ->    {none, St}.    % strange name - do nothing.expand_operator(Name, Arity, _F, Env) when is_atom(Name) ->    %% An unqualified function name - must be looked up. However, we    %% must first check that it is not an auto-imported name - these    %% have precedence over normal imports. We do a sanity check on the    %% found arity.    case is_auto_import({Name, Arity}) of	true ->	    {Name, none};    % auto-import - never expand.	false ->	    case dict:find({Name, Arity}, Env#code.expand) of		{ok, {M, {N, A}}} when A =:= Arity ->		    %% Expand to a qualified name.		    F1 = erl_syntax:module_qualifier(			   erl_syntax:atom(M),			   erl_syntax:atom(N)),		    {{M, N}, {value, F1}};		error ->		    %% Not in the table - leave it unchanged		    {Name, none}	    end

⌨️ 快捷键说明

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