From 3ea11105b445579324ab52f4772b7d8b78eb307c Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 9 Jun 2023 13:38:51 +0300 Subject: [PATCH] Remove file committed by mistake --- src/aeso_code_analysis.erl | 214 ------------------------------------- 1 file changed, 214 deletions(-) delete mode 100644 src/aeso_code_analysis.erl diff --git a/src/aeso_code_analysis.erl b/src/aeso_code_analysis.erl deleted file mode 100644 index 5c78f0f..0000000 --- a/src/aeso_code_analysis.erl +++ /dev/null @@ -1,214 +0,0 @@ --module(aeso_code_analysis). - --export([analyze/1]). - -%-record(env, {vars = [] :: list()}). -% -%-type env() :: #env{}. - --record(analysis, - { defined_types = sets:new() :: sets:set() - , defined_funs = sets:new() :: sets:set() - , used_types = sets:new() :: sets:set() - , used_funs = sets:new() :: sets:set() - , used_includes = sets:new() :: sets:set() - , unused_stateful = sets:new() :: sets:set() - %, used_vars = [] :: list() - %, defined_vars = [] :: list() - %, used_consts = [] :: list() - %, shadowing_pairs = [] :: list() - %, unused_retval = [] :: list() - }). - -%-type analysis() :: #analysis{}. - --define(P(X), io:format(??X ++ ":\n~p\n", [X])). - --record(alg, - { zero :: A - , plus :: fun((A, A) -> A) - , scoped :: fun((A, A) -> A) }). - -work(expr, X = {qid, Ann, Fun}) -> - ?P(X), - ?P(aeso_syntax:get_ann(stateful, Ann, none)), - ?P(""), - #analysis{used_funs = sets:from_list([Fun])}; -work(type, {qid, _, Type}) -> - #analysis{used_types = sets:from_list([Type])}; -work(bind_type, {id, _, Type}) -> - #analysis{defined_types = sets:from_list([Type])}; -work(_, _) -> - #analysis{}. - --spec analyze(aeso_syntax:ast()) -> ok. -analyze([{Contract, _Ann, {con, _, _ConName}, _Impls, Decls} | Rest]) - when Contract == contract_main; - Contract == contract_child -> - analyze_contract(Decls), - analyze(Rest); -analyze([{namespace, _Ann, {con, _, _NSName}, Decls} | Rest]) -> - analyze_contract(Decls), - analyze(Rest); -analyze([]) -> - error("End of code analysis"). - -analyze_contract(Decls) -> - Funs = [ Fun || Fun = {letfun, _, _, _, _, _} <- Decls], - _Types = [ Def || Def = {type_def, _, _, _, _} <- Decls ], - _Consts = [ Const || Const = {letval, _, _, _} <- Decls ], - - Alg = - #alg{ zero = #analysis{} - , plus = fun merge/2 - , scoped = fun merge/2 }, - Res0 = aeso_syntax_utils:fold( - Alg, - fun work/2, - decl, - Decls), - Res = merge(Res0, #analysis{defined_funs = Funs}), - UsedTypes = sets:to_list(Res#analysis.used_types), - UsedFuns = sets:to_list(Res#analysis.used_funs), - ?P(UsedFuns), - ?P(UsedTypes), - - %Res = [ {Name, analyze_fun(Fun)} || Fun = {letfun, _, {id, _, Name}, _, _, _} <- Funs ], - - ?P(Res). -% -%analyze_fun({letfun, _, _FunId, _Args, _, GuardedBodies}) -> -% lists:foldl(fun merge/2, #analysis{}, [(analyze_expr(#env{}, Body)) || {guarded, _, _, Body} <- GuardedBodies ]). -% -%-spec analyze_expr(env(), aeso_syntax:expr()) -> analysis(). -%analyze_expr(Env, {lam, _, Args, Expr}) -> -% NewVars = [ Id || {arg, _, Id, _} <- Args ], -% Env1 = lists:foldl(fun bind_var/2, Env, NewVars), -% Analysis = analyze_expr(Env1, Expr), -% Analysis#analysis{defined_vars = Analysis#analysis.defined_vars ++ NewVars}; -%%analyze_expr(Env, {'if', ann(), expr(), expr(), expr()}) -> -%% ok; -%%analyze_expr(Env, {switch, ann(), expr(), [alt()]}) -> -%% ok; -%analyze_expr(Env, {app, _, Expr, _Args}) -> -% analyze_expr(Env, Expr); -%%analyze_expr(Env, {proj, ann(), expr(), id()}) -> -%% ok; -%analyze_expr(Env, {tuple, _, Exprs}) -> -% lists:foldl(fun merge/2, #analysis{}, [ analyze_expr(Env, Expr) || Expr <- Exprs ]); -%%analyze_expr(Env, {list, ann(), [expr()]}) -> -%% ok; -%%analyze_expr(Env, {list_comp, ann(), expr(), [comprehension_exp()]}) -> -%% ok; -%analyze_expr(Env, {typed, _, Expr, Type}) -> -% merge(analyze_expr(Env, Expr), analyze_type(Env, Type)); -%%analyze_expr(Env, {record_or_map(), ann(), [field(expr())]}) -> -%% ok; -%%analyze_expr(Env, {record_or_map(), ann(), expr(), [field(expr())]}) -> -%% ok; -%%analyze_expr(Env, {map, ann(), [{expr(), expr()}]}) -> -%% ok; -%%analyze_expr(Env, {map_get, ann(), expr(), expr()}) -> -%% ok; -%%analyze_expr(Env, {map_get, ann(), expr(), expr(), expr()}) -> -%% ok; -%analyze_expr(Env, {block, _, Stmts}) -> -% analyze_block(Env, Stmts); -%%analyze_expr(Env, {op(), ann()}) -> -%% ok; -%analyze_expr(_Env, {int, _, _}) -> -% #analysis{}; -%analyze_expr(Env, Id = {id, _, _}) -> -% #analysis{used_vars = [lookup_var(Id, Env)]}; -%analyze_expr(_Env, {qcon, _, _}) -> -% #analysis{}. -%%analyze_expr(Env, QId = {qid, _, _}) -> -%% #analysis{used_funs = lookup_fun(QId, Env)}. -%%analyze_expr(Env, qid() | con() | qcon()) -> -%% ok; -%%analyze_expr(Env, constant()) -> -%% ok; -%%analyze_expr(Env, letpat()) -> -%% ok. -% -%analyze_block(_Env, []) -> -% #analysis{}; -%analyze_block(Env, [E]) -> -% analyze_expr(Env, E); -%analyze_block(Env, [{letval, _, {typed, _, Id = {id, _, _}, _}, Expr} | Stmts]) -> -% Env1 = bind_var(Id, Env), -% Analysis = analyze_block(Env1, Stmts), -% Analysis2 = merge(Analysis, analyze_expr(Env1, Expr)), -% Analysis2#analysis{defined_vars = Analysis2#analysis.defined_vars ++ [Id]}. -% -%analyze_type(_Env, {id, _, Id}) -> -% #analysis{used_types = [Id]}; -%analyze_type(_Env, {qid, _, QId}) -> -% #analysis{used_types = [QId]}; -%analyze_type(Env, {fun_t, _, _, Types, Type}) -> -% merge(lists:foldl(fun merge/2, #analysis{}, [analyze_type(Env, T) || T <- Types]), analyze_type(Env, Type)); -%analyze_type(_Env, {tuple_t, _, _}) -> -% #analysis{}. -% -%bind_var(VarId, Env = #env{vars = Vars}) -> -% check_shadowing(VarId, Vars), -% Env#env{vars = [VarId | Vars]}. -% -%check_shadowing(Var = {id, _, VarName}, Ids) -> -% Shadowed = -% lists:search(fun({id, _, Name}) when Name == VarName -> true; -% (_) -> false -% end, Ids), -% case Shadowed of -% false -> -% #analysis{}; -% {value, ShadowedVar} -> -% #analysis{shadowing_pairs = [{Var, ShadowedVar}]} -% end. -% -%lookup_var({id, _, VarName}, Env) -> -% {value, Var}= -% lists:search( -% fun({id, _, Name}) when Name == VarName -> true; -% (_) -> false -% end, Env#env.vars), -% Var. - - -merge(A1, A2) -> - #analysis{ used_types = sets:union(A1#analysis.used_types, A2#analysis.used_types) - , used_funs = sets:union(A1#analysis.used_funs, A2#analysis.used_funs) }. - - -%% the set of unused functions is the different between the 2 sets: -%% - In a contract: -%% * all user-defined functions -%% * all function calls -%% - In a namespace: -%% * all user-defined private functions -%% * all function calls -%% Note: this only applies to functions, not entrypoints - -%% Unused variables: -%% ----------------- -%% Scope: function -%% Algo: if a variable is not used in its current scope, then it's reported. -%% Functions that are declared in one scope but not used, and then declared -%% in a different scope and used, should be considered. -%% -%% Unused stateful: -%% ---------------- -%% Scope: function -%% Algo: check all function calls in the function, if none of them requires -%% stateful, then we say that it's unused. -%% -%% Unused constants: -%% ----------------- -%% Scope: contract or namespace -%% Algo: same as variables, but the scope is fixed to the contract or the namespace. -%% -%% Unused typedefs: -%% ---------------- -%% Scope: contract or namespace -%% Algo: check the types of all expressions in the contract or namespace, if the type -%% doesn't show up anywhere, then the typedef is not used.