You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.9 KiB
67 lines
1.9 KiB
4 years ago
|
#!/usr/bin/env escript
|
||
|
% Copyright (c) Facebook, Inc. and its affiliates.
|
||
|
%
|
||
|
% This source code is licensed under the MIT license found in the
|
||
|
% LICENSE file in the root directory of this source tree.
|
||
|
%
|
||
|
%
|
||
|
|
||
|
usage() ->
|
||
|
Usage =
|
||
|
"Usage:\n"
|
||
|
" extract.escript <compiled_list_path> <outdir>\n"
|
||
|
"\n"
|
||
|
"This script extracts in <outdir> the AST of all compiled\n"
|
||
|
"BEAM files listed in <compiled_list_path>",
|
||
|
io:format("~s", [Usage]),
|
||
|
halt(1).
|
||
|
|
||
|
main([ListPath, OutDir]) ->
|
||
|
Beams =
|
||
|
case file:consult(ListPath) of
|
||
|
{ok, Contents} -> Contents;
|
||
|
Error ->
|
||
|
io:format("error while reading file `~s`: ~p~n", [ListPath, Error]),
|
||
|
halt(1)
|
||
|
end,
|
||
|
process_beams(Beams, OutDir);
|
||
|
main(_) ->
|
||
|
usage().
|
||
|
|
||
|
process_beams([], _) -> ok;
|
||
|
process_beams([BeamFilePath | L], OutDir) ->
|
||
|
case get_ast(BeamFilePath) of
|
||
|
{ok, Module, Forms} ->
|
||
|
OutFilePath = filename:join(OutDir, atom_to_list(Module) ++ ".json"),
|
||
|
dump_ast_as_json(Forms, OutFilePath);
|
||
|
{error, What} ->
|
||
|
io:format("error while getting AST from `~s`: ~p~n",[BeamFilePath, What])
|
||
|
end,
|
||
|
process_beams(L, OutDir).
|
||
|
|
||
|
get_ast(BeamFilePath) ->
|
||
|
case beam_lib:chunks(BeamFilePath, [abstract_code]) of
|
||
|
{ok, {Module, [{abstract_code, {_, Forms}}]}} ->
|
||
|
{ok, Module, Forms};
|
||
|
{error, _, What} ->
|
||
|
{error, What}
|
||
|
end.
|
||
|
|
||
|
dump_ast_as_json(Forms, OutFilePath) ->
|
||
|
Object = ast_to_json(Forms),
|
||
|
Contents = jsone:encode(Object),
|
||
|
file:write_file(OutFilePath, Contents).
|
||
|
|
||
|
ast_to_json([]) ->
|
||
|
[];
|
||
|
ast_to_json(Node) when is_list(Node) ->
|
||
|
case lists:all(fun(Item) -> is_integer(Item) end, Node) of
|
||
|
true -> unicode:characters_to_binary(Node);
|
||
|
false -> [ast_to_json(Child) || Child <- Node]
|
||
|
end;
|
||
|
ast_to_json(Node) when is_tuple(Node) ->
|
||
|
L = tuple_to_list(Node),
|
||
|
ast_to_json(L);
|
||
|
ast_to_json(Node) ->
|
||
|
Node.
|