Open andytill opened 6 years ago
So I have an initial results, I have yet to convert the params from their ast form. But in their lies the crux, we have complex params like process_info2 on line 79, size_to_bytes on line 118 and record fields on line 155.
Here is a diff:
diff --git a/src/main/resources/erlyberly/beam/erlyberly.erl b/src/main/resources/erlyberly/beam/erlyberly.erl
index 633d35c..bb9a4b0 100644
--- a/src/main/resources/erlyberly/beam/erlyberly.erl
+++ b/src/main/resources/erlyberly/beam/erlyberly.erl
@@ -26,6 +26,7 @@
-export([get_source_code/1]).
-export([load_modules_on_path/1]).
-export([load_module_records/1]).
+-export([load_module_functions/1]).
-export([module_functions/0]).
-export([process_info/0]).
-export([saleyn_fun_src/1]).
@@ -174,6 +175,13 @@ load_module_records(Mod) ->
Records = [{Tag, record_fields(Fields)} || {attribute,_,record,{Tag,Fields}} <- Forms],
{ok, Records}.
+load_module_functions(Mod) ->
+ {ok, Forms} = load_module_forms(Mod),
+ Functions = [
+ {Function,Params} || {function,_,Function,_,FunctionBody} <- Forms,
+ {clause,_,Params, _Guard, _Body} <- FunctionBody],
+ {ok, Functions}.
+
%%% ============================================================================
%%% module function tree
%%% ============================================================================
I can of course just extract the vars, if you want ;)
Thanks @olafura! Yes the return should be a flat list of binding names, it is very difficult to take this apart in Java, like an untyped XML DOM. The function clause combinations do get very complex. In the example case we can get the binding names from the dialyzer spec initially, and then use the function clause to fill in the blanks.
So for example, in this function.
myfunc(0, Acc) -> Acc
myfunc(Index, _) -> myfunc(Index-1, 2).
The list of returned arguments should be ["Index", "Acc"]
. If there were two different names for the same argument e.g.
myfunc(0, Acc) -> Acc
myfunc(Index, X) -> myfunc(Index-1, X+1).
Then we could return ["Index", "Acc|X"]
. Names in the dialyzer spec should probably override this, unless we don't trust that the spec is being kept upto date!? Maybe we should return that too if it is different to the names in the clause.
Erlyberly could show the names of function arguments above the values for function arguments in the term tree. Below is a screenshot of annotated records, it might look similar to this.
Module AST is already parsed for record metadata. Finding function argument names would be an expansion of that.
https://github.com/andytill/erlyberly/blob/master/src/main/resources/erlyberly/beam/erlyberly.erl#L172
For example, given the function in
lists
.The function may return something like.
The dialyzer spec can be used but it may not exist. Functions can have multiple clauses. A binding name should be accepted over
_
or a literal e.g.Index
is more useful than0
both of which may be present in different function clauses. There are many variations in function clauses, the AST parser should attempt to return something useful but could return a blank if the argument was too complex or long.If anyone wants to attempt this, post a comment. I can help with the UI for anyone that doesn't want to code java! :D