Add dont_unfold option to type inference function
This commit is contained in:
parent
1ed40f1cca
commit
8a16bd4fa1
@ -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}) ->
|
||||||
|
Loading…
x
Reference in New Issue
Block a user