Re: erl-complete ...
[email protected] Sat, 15 Sep 2007 05:49:46 +0100
| Newsgroups | gmane.comp.lang.erlang.distel.devel |
|---|---|
| Message-ID | <[email protected]> |
--=-=-= Bill, Bill Clementson <[email protected]> writes: > I was asking about a patch for the Call Graph code that you wrote > previously. At the moment, the "who calls" support doesn't work for > BIF's. Oh I see. Is it really that useful to have that? I don't often find myself wondering who calls a particular BIF. I added builtins to the call graph xref server - see attached patch - but it doesn't seem to make a difference. I suspect BIFs are only added as unconnected vertices. >>>> (except distel's completion currently isn't using xref, but it should) > Does the attached patch do what you wanted? Thanks for the patch. I've made the following changes: - don't add otp release - the otp modules are part of the code path and hence get loaded anyway - filter duplicates (due to different arity) from function completion - avoid duplication of code between who_calls and completion - add rebuild_{completions, call_graph} functions - there is nothing on the emacs side that calls them, but you can call them manually - minor cosmetic changes See attachment for the revised patch. One remaining problem with this code is that it doesn't automatically handle the addition/removal of modules or changes to the code load path - you have to invoke the aforementioned rebuild functions manually for this. Matthias. --=-=-= Content-Type: text/x-diff Content-Disposition: attachment; filename=distel_xref_complete.patch Index: distel.erl =================================================================== --- distel.erl (revision 38) +++ distel.erl (working copy) @@ -20,6 +20,7 @@ debug_toggle/2, debug_subscribe/1, debug_add/1, break_toggle/2, break_delete/2, break_add/2, break_restore/1, modules/1, functions/2, who_calls/3, + rebuild_completions/0, rebuild_call_graph/0, free_vars/1, free_vars/2, apropos/1, apropos/2, describe/3, describe/4]). @@ -647,44 +648,33 @@ %% ---------------------------------------------------------------------- %% Completion support %% ---------------------------------------------------------------------- +-define(COMPLETION_SERVER, distel_complete). +-define(COMPLETION_SERVER_OPTS, {xref_mode, modules}). +rebuild_completions() -> + rebuild(?COMPLETION_SERVER, ?COMPLETION_SERVER_OPTS). + %% Returns: [ModName] of all modules starting with Prefix. %% ModName = Prefix = string() modules(Prefix) -> -% FIXME: have to decide which approach is better - all loaded or all in path -% i, of course, prefer all in path (mbj) - Dirs = code:get_path(), - {ok, sort(foldl(fun(Dir, Acc) -> fm_dir(Dir, Prefix, Acc) end, [], Dirs))}. - -fm_dir(Dir, Prefix, Acc) -> - case file:list_dir(Dir) of - {ok, Files} -> - Mods = [basename(F, ".beam") || F <- Files, - lists:prefix(Prefix, F), - lists:suffix(".beam", F)], - Mods ++ Acc; + case xref_q(?COMPLETION_SERVER, ?COMPLETION_SERVER_OPTS, + '"~s.*" : Mod', [Prefix]) of + {ok, Mods} -> + {ok, [atom_to_list(Mod) || Mod <- Mods]}; _ -> - Acc + {error, fmt("Can't find any matches for ~p", [Prefix])} end. %% Returns: [FunName] of all exported functions of Mod starting with Prefix. %% Mod = atom() %% Prefix = string() functions(Mod, _Prefix) -> -% FIXME: have to decide which approach is better - all loaded or all in path -% i, of course, prefer all in path (mbj) - case beamfile(Mod) of - {ok, BeamFile} -> - case get_exports(BeamFile) of - {ok, Exports0} -> - Exports = Exports0 -- [{"module_info",0},{"module_info",1}], - Fns = [Fun || {Fun, _Arity} <- Exports], - {ok, ordsets:to_list(ordsets:from_list(Fns))}; - error -> - {error, fmt("Can't get export list for ~p", [Mod])} - end; + case xref_q(?COMPLETION_SERVER, ?COMPLETION_SERVER_OPTS, + "(X+B) * ~p:_/_", [Mod]) of + {ok, Res} -> + {ok, lists:usort([atom_to_list(Fun) || {_Mod, Fun, _Arity} <- Res])}; _ -> - {error, fmt("Can't find beam file for ~p", [Mod])} + {error, fmt("Can't find module ~p", [Mod])} end. %% ---------------------------------------------------------------------- @@ -995,8 +985,12 @@ %%----------------------------------------------------------------- %% Call graph %%----------------------------------------------------------------- --define(SERVER, distel_xref). +-define(CALL_GRAPH_SERVER, distel_call_graph). +-define(CALL_GRAPH_SERVER_OPTS, []). +rebuild_call_graph() -> + rebuild(?CALL_GRAPH_SERVER, ?CALL_GRAPH_SERVER_OPTS). + %% Ret: [{M,F,A,Line}], M = F = binary() who_calls(M, F, A) -> [{fmt("~p", [Mod]), fmt("~p", [Fun]), Aa, Line} @@ -1004,33 +998,41 @@ %% {M,F,A} -> [{{M,F,A},Line}] calls_to(MFA) -> - ensure_started(), - {ok, Res} = - xref:q(?SERVER, string_format("(Lin)(domain (E || ~p))", [MFA])), + {ok, Res} = xref_q(?CALL_GRAPH_SERVER, ?CALL_GRAPH_SERVER_OPTS, + "(Lin)(domain (E || ~p))", [MFA]), Res. string_format(S) -> S. string_format(S, A) -> lists:flatten(io_lib:fwrite(S, A)). -rebuild() -> - stop(), - ensure_started(). +%%----------------------------------------------------------------- +%% Support code for completion and call graph +%%----------------------------------------------------------------- -stop() -> - case whereis(?SERVER) of +rebuild(Server, Opts) -> + stop(Server), + ensure_started(Server, Opts). + +stop(Server) -> + case whereis(Server) of undefined -> ok; - _ -> xref:stop(?SERVER), + _ -> xref:stop(Server), ok end. -ensure_started() -> - case whereis(?SERVER) of +xref_q(Server, Opts, Query, Args) -> + ensure_started(Server, Opts), + xref:q(Server, string_format(Query, Args)). + +ensure_started(Server, Opts) -> + case whereis(Server) of undefined -> - xref:start(?SERVER), - foreach(fun (Dir) -> xref:add_directory(?SERVER, Dir) end, + xref:start(Server, Opts), + xref:set_default(Server, builtins, true), + foreach(fun (Dir) -> xref:add_directory(Server, Dir) end, get_code_path()); _ -> - xref:update(?SERVER), + xref:update(Server), ok end. --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline ------------------------------------------------------------------------- This SF.net email is sponsored by: Microsoft Defy all challenges. Microsoft(R) Visual Studio 2005. http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/ --=-=-= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Distel-hackers mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/distel-hackers --=-=-=--