diff options
author | Björn Gustavsson <[email protected]> | 2016-09-02 14:13:18 +0200 |
---|---|---|
committer | Björn Gustavsson <[email protected]> | 2016-09-02 14:13:18 +0200 |
commit | 61b53af84200b52a5b91c4266e91ebc6ba0173ee (patch) | |
tree | 2d28327d41a41375a9258fa64d99bc3bd8d9c518 /lib/stdlib/src/erl_internal.erl | |
parent | 49381b90620e88bda2d3f3edce25c8e841ded9c1 (diff) | |
parent | 6ba91ac62a8cffd9ea274ce8b9023abbcb8d9b67 (diff) | |
download | otp-61b53af84200b52a5b91c4266e91ebc6ba0173ee.tar.gz otp-61b53af84200b52a5b91c4266e91ebc6ba0173ee.tar.bz2 otp-61b53af84200b52a5b91c4266e91ebc6ba0173ee.zip |
Merge branch 'bjorn/eliminate-sys_pre_expand/OTP-13856'
* bjorn/eliminate-sys_pre_expand/OTP-13856:
Remove sys_pre_expand
xref: Eliminate use of sys_pre_expand
debugger: Eliminate use of sys_pre_expand
compiler: Eliminate use of sys_pre_expand
shell_SUITE: Eliminate references to sys_pre_expand in comments
qlc_pt: Simplify code because of updated erl_expand_records
Teach erl_expand_records to translate module-less calls
erl_internal: Add add_predefined_functions/1
cover: Remove always stale comment
Diffstat (limited to 'lib/stdlib/src/erl_internal.erl')
-rw-r--r-- | lib/stdlib/src/erl_internal.erl | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/lib/stdlib/src/erl_internal.erl b/lib/stdlib/src/erl_internal.erl index 46059f42a5..5d6aa0ebe8 100644 --- a/lib/stdlib/src/erl_internal.erl +++ b/lib/stdlib/src/erl_internal.erl @@ -54,6 +54,8 @@ -export([is_type/2]). +-export([add_predefined_functions/1]). + %%--------------------------------------------------------------------------- %% Erlang builtin functions allowed in guards. @@ -569,3 +571,68 @@ is_type(term, 0) -> true; is_type(timeout, 0) -> true; is_type(tuple, 0) -> true; is_type(_, _) -> false. + +%%% +%%% Add and export the pre-defined functions: +%%% +%%% module_info/0 +%%% module_info/1 +%%% behaviour_info/1 (optional) +%%% + +-spec add_predefined_functions(Forms) -> UpdatedForms when + Forms :: [erl_parse:abstract_form() | erl_parse:form_info()], + UpdatedForms :: [erl_parse:abstract_form() | erl_parse:form_info()]. + +add_predefined_functions(Forms) -> + Forms ++ predefined_functions(Forms). + +predefined_functions(Forms) -> + Attrs = [{Name,Val} || {attribute,_,Name,Val} <- Forms], + {module,Mod} = lists:keyfind(module, 1, Attrs), + Callbacks = [Callback || {callback,Callback} <- Attrs], + OptionalCallbacks = get_optional_callbacks(Attrs), + Mpf1 = module_predef_func_beh_info(Callbacks, OptionalCallbacks), + Mpf2 = module_predef_funcs_mod_info(Mod), + Mpf = [erl_parse:new_anno(F) || F <- Mpf1++Mpf2], + Exp = [{F,A} || {function,_,F,A,_} <- Mpf], + [{attribute,0,export,Exp}|Mpf]. + +get_optional_callbacks(Attrs) -> + L = [O || {optional_callbacks,O} <- Attrs, is_fa_list(O)], + lists:append(L). + +is_fa_list([{FuncName, Arity}|L]) + when is_atom(FuncName), is_integer(Arity), Arity >= 0 -> + is_fa_list(L); +is_fa_list([]) -> true; +is_fa_list(_) -> false. + +module_predef_func_beh_info([], _) -> + []; +module_predef_func_beh_info(Callbacks0, OptionalCallbacks) -> + Callbacks = [FA || {{_,_}=FA,_} <- Callbacks0], + List = make_list(Callbacks), + OptionalList = make_list(OptionalCallbacks), + [{function,0,behaviour_info,1, + [{clause,0,[{atom,0,callbacks}],[],[List]}, + {clause,0,[{atom,0,optional_callbacks}],[],[OptionalList]}]}]. + +make_list([]) -> {nil,0}; +make_list([{Name,Arity}|Rest]) -> + {cons,0, + {tuple,0, + [{atom,0,Name}, + {integer,0,Arity}]}, + make_list(Rest)}. + +module_predef_funcs_mod_info(Mod) -> + ModAtom = {atom,0,Mod}, + [{function,0,module_info,0, + [{clause,0,[],[], + [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}}, + [ModAtom]}]}]}, + {function,0,module_info,1, + [{clause,0,[{var,0,'X'}],[], + [{call,0,{remote,0,{atom,0,erlang},{atom,0,get_module_info}}, + [ModAtom,{var,0,'X'}]}]}]}]. |