diff options
Diffstat (limited to 'lib/dialyzer/src/dialyzer_dataflow.erl')
-rw-r--r-- | lib/dialyzer/src/dialyzer_dataflow.erl | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/lib/dialyzer/src/dialyzer_dataflow.erl b/lib/dialyzer/src/dialyzer_dataflow.erl index 3591d5be8e..4d614320c2 100644 --- a/lib/dialyzer/src/dialyzer_dataflow.erl +++ b/lib/dialyzer/src/dialyzer_dataflow.erl @@ -67,7 +67,9 @@ t_to_string/2, t_to_tlist/1, t_tuple/0, t_tuple/1, t_tuple_args/1, t_tuple_args/2, t_tuple_subtypes/2, - t_unit/0, t_unopaque/2]). + t_unit/0, t_unopaque/2, + t_map/1 + ]). %%-define(DEBUG, true). %%-define(DEBUG_PP, true). @@ -305,6 +307,12 @@ traverse(Tree, Map, State) -> handle_try(Tree, Map, State); tuple -> handle_tuple(Tree, Map, State); + map -> + handle_map(Tree, Map, State); + map_pair_assoc -> + handle_map_pair_assoc(Tree, Map, State); + map_pair_exact -> + handle_map_pair_exact(Tree, Map, State); values -> Elements = cerl:values_es(Tree), {State1, Map1, EsType} = traverse_list(Elements, Map, State), @@ -657,7 +665,8 @@ is_opaque_type_test_problem(Fun, Args, ArgTypes, State) -> FN =:= is_float; FN =:= is_function; FN =:= is_integer; FN =:= is_list; FN =:= is_number; FN =:= is_pid; FN =:= is_port; - FN =:= is_reference; FN =:= is_tuple -> + FN =:= is_reference; FN =:= is_tuple; + FN =:= is_map -> type_test_opaque_arg(Args, ArgTypes, State#state.opaques); {erlang, FN, 2} when FN =:= is_function -> type_test_opaque_arg(Args, ArgTypes, State#state.opaques); @@ -1054,6 +1063,23 @@ handle_try(Tree, Map, State) -> %%---------------------------------------- +handle_map(Tree,Map,State) -> + Pairs = cerl:map_es(Tree), + {State1, Map1, TypePairs} = traverse_list(Pairs,Map,State), + {State1, Map1, t_map(TypePairs)}. + +handle_map_pair_assoc(Tree,Map,State) -> + Elements = cerl:map_pair_assoc_es(Tree), + {State1, Map1, [K,V]} = traverse_list(Elements,Map,State), + {State1, Map1, {K,V}}. + +handle_map_pair_exact(Tree,Map,State) -> + Elements = cerl:map_pair_exact_es(Tree), + {State1, Map1, [K,V]} = traverse_list(Elements,Map,State), + {State1, Map1, {K,V}}. + +%%---------------------------------------- + handle_tuple(Tree, Map, State) -> Elements = cerl:tuple_es(Tree), {State1, Map1, EsType} = traverse_list(Elements, Map, State), @@ -1431,6 +1457,30 @@ bind_pat_vars([Pat|PatLeft], [Type|TypeLeft], Acc, Map, State, Rev) -> bind_opaque_pats(Literal, Type, Pat, Map, State, Rev); false -> {Map, Literal} end; + map -> + {Map, t_map([])}; +% Pairs = [ cerl:map_pair_es(Pair) || Pair <- cerl:map_es(Pat) ], +% MapType = t_inf(t_map([]), Type), +% case t_is_none(MapType) of +% true -> +% bind_opaque_pats(MapType, Type, Pat, Map, State, Rev); +% false -> +% MapJ = join_maps_begin(Map), +% Results = case Rev of +% true -> +% [bind_pat_vars_reverse(Pair, [t_any(),t_any()], [], MapJ, State) || Pair <- Pairs]; +% false -> +% [bind_pat_vars(Pair, [t_any(),t_any()], [], MapJ, State) || Pair <- Pairs] +% end, +% case [M || {M, _} <- Results, M =/= error] of +% [] -> bind_error([Pat], MapType, t_none(), bind); +% Maps -> +% Map1 = join_maps_end(Maps, MapJ), +% _PairTypes = [{Ktype,Vtype} || {M, [Ktype,Vtype]} <- Results, M =/= error], +% % add t_sup +% {Map1, t_map([])} +% end +% end; tuple -> Es = cerl:tuple_es(Pat), {TypedRecord, Prototype} = @@ -1641,6 +1691,8 @@ bind_guard(Guard, Map, Env, Eval, State) -> Es0 = cerl:tuple_es(Guard), {Map1, Es} = bind_guard_list(Es0, Map, Env, dont_know, State), {Map1, t_tuple(Es)}; + map -> + {Map, t_map([])}; 'let' -> Arg = cerl:let_arg(Guard), [Var] = cerl:let_vars(Guard), |