Query Erlang code base for certain code patterns?

Let’s say I wanted to query a code base for functions that only have one external call to another module but no other code. Is that possible? I.e. I want to detect intermediary functions like this:

-module(foo).
-export([bar/1]).
bar(X) -> qux:bar(X).

Is it possible to query Xref or maybe even Dialyzer for patterns like this? Or do no such tool exist?

This should be possible with ELP - cc @alanz @robertoaloi

1 Like

Yes, that should be simple to query in ELP.

1 Like

Any hints of how to achieve this? Can’t find much about any such feature in the READMEs of either elp or eqwalizer

We still have work to do when it comes to documentation, I hope to start producing tutorials/docs soon to show how something like this would look like in practice.
A different question is how you’d like the interface for this to be. What’s the practical goal? E.g. if it’s for refactoring purposes (e.g. remove un-necessary proxy calls) we already have the infra for that in place. But if this needs to be fed into a separate tool, we should think of a query command or similar which returns results in a programmable way.

If by “no other code” you mean “no other function calls, either local or remote” than this is the solution:

xref:start(s),
xref:add_application/release for each app/release you have
{ok, Calls} = xref:q(s, "E"),
Groups = maps:groups_from_list(fun({K,_V}) -> K end, fun({_K,V}) -> V end, Calls),
Intermediary = maps:filter(fun(_, Val) -> length(Val) == 1 end, Groups).

Result is a map where key is MFA (where you call from) and value is 1-sized lists of MFA (what you call).
Prolly you can put this into some escript.

Very curious about ELP solution tho :smiley:

1 Like

The use case I have is that I have a code base I’d like to query with as low effort as possible, preferably via a CLI tool.