Add dont_unfold option to type inference function

This commit is contained in:
Hans Svensson 2019-05-27 16:00:08 +02:00
parent 1ed40f1cca
commit 8a16bd4fa1

View File

@ -514,7 +514,7 @@ map_t(As, K, V) -> {app_t, As, {id, As, "map"}, [K, V]}.
infer(Contracts) -> infer(Contracts) ->
infer(Contracts, []). infer(Contracts, []).
-type option() :: return_env. -type option() :: return_env | dont_unfold.
-spec init_env(list(option())) -> env(). -spec init_env(list(option())) -> env().
init_env(_Options) -> global_env(). init_env(_Options) -> global_env().
@ -526,7 +526,7 @@ infer(Contracts, Options) ->
Env = init_env(Options), Env = init_env(Options),
create_options(Options), create_options(Options),
ets_new(type_vars, [set]), ets_new(type_vars, [set]),
{Env1, Decls} = infer1(Env, Contracts, []), {Env1, Decls} = infer1(Env, Contracts, [], Options),
case proplists:get_value(return_env, Options, false) of case proplists:get_value(return_env, Options, false) of
false -> Decls; false -> Decls;
true -> {Env1, Decls} true -> {Env1, Decls}
@ -535,21 +535,22 @@ infer(Contracts, Options) ->
clean_up_ets() clean_up_ets()
end. end.
-spec infer1(env(), [aeso_syntax:decl()], [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}. -spec infer1(env(), [aeso_syntax:decl()], [aeso_syntax:decl()], list(option())) ->
infer1(Env, [], Acc) -> {Env, lists:reverse(Acc)}; {env(), [aeso_syntax:decl()]}.
infer1(Env, [{contract, Ann, ConName, Code} | Rest], Acc) -> infer1(Env, [], Acc, _Options) -> {Env, lists:reverse(Acc)};
infer1(Env, [{contract, Ann, ConName, Code} | Rest], Acc, Options) ->
%% do type inference on each contract independently. %% do type inference on each contract independently.
check_scope_name_clash(Env, contract, ConName), check_scope_name_clash(Env, contract, ConName),
{Env1, Code1} = infer_contract_top(push_scope(contract, ConName, Env), contract, Code), {Env1, Code1} = infer_contract_top(push_scope(contract, ConName, Env), contract, Code, Options),
Contract1 = {contract, Ann, ConName, Code1}, Contract1 = {contract, Ann, ConName, Code1},
Env2 = pop_scope(Env1), Env2 = pop_scope(Env1),
Env3 = bind_contract(Contract1, Env2), Env3 = bind_contract(Contract1, Env2),
infer1(Env3, Rest, [Contract1 | Acc]); infer1(Env3, Rest, [Contract1 | Acc], Options);
infer1(Env, [{namespace, Ann, Name, Code} | Rest], Acc) -> infer1(Env, [{namespace, Ann, Name, Code} | Rest], Acc, Options) ->
check_scope_name_clash(Env, namespace, Name), check_scope_name_clash(Env, namespace, Name),
{Env1, Code1} = infer_contract_top(push_scope(namespace, Name, Env), namespace, Code), {Env1, Code1} = infer_contract_top(push_scope(namespace, Name, Env), namespace, Code, Options),
Namespace1 = {namespace, Ann, Name, Code1}, Namespace1 = {namespace, Ann, Name, Code1},
infer1(pop_scope(Env1), Rest, [Namespace1 | Acc]). infer1(pop_scope(Env1), Rest, [Namespace1 | Acc], Options).
check_scope_name_clash(Env, Kind, Name) -> check_scope_name_clash(Env, Kind, Name) ->
case get_scope(Env, qname(Name)) of case get_scope(Env, qname(Name)) of
@ -560,13 +561,16 @@ check_scope_name_clash(Env, Kind, Name) ->
destroy_and_report_type_errors(Env) destroy_and_report_type_errors(Env)
end. end.
-spec infer_contract_top(env(), contract | namespace, [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}. -spec infer_contract_top(env(), contract | namespace, [aeso_syntax:decl()], list(option())) ->
infer_contract_top(Env, Kind, Defs0) -> {env(), [aeso_syntax:decl()]}.
infer_contract_top(Env, Kind, Defs0, Options) ->
Defs = desugar(Defs0), Defs = desugar(Defs0),
{Env1, Defs1} = infer_contract(Env, Kind, Defs), {Env1, Defs1} = infer_contract(Env, Kind, Defs),
Env2 = on_current_scope(Env1, fun(Scope) -> unfold_record_types(Env1, Scope) end), case proplists:get_value(dont_unfold, Options, false) of
Defs2 = unfold_record_types(Env2, Defs1), true -> {Env1, Defs1};
{Env2, Defs2}. false -> Env2 = on_current_scope(Env1, fun(Scope) -> unfold_record_types(Env1, Scope) end),
{Env2, unfold_record_types(Env2, Defs1)}
end.
%% TODO: revisit %% TODO: revisit
infer_constant({letval, Attrs,_Pattern, Type, E}) -> infer_constant({letval, Attrs,_Pattern, Type, E}) ->