diff options
author | Magnus Lång <[email protected]> | 2016-02-27 18:26:07 +0100 |
---|---|---|
committer | Hans Bolinder <[email protected]> | 2016-04-28 16:14:24 +0200 |
commit | ee6a551e593b9788e433f7a99857729acdd5dd53 (patch) | |
tree | 5b6b44908401fd569fb0e9874f16d50b1b76d96b /lib/hipe/cerl/erl_types.erl | |
parent | 252df5612032cfba71285b5886937e88ba176529 (diff) | |
download | otp-ee6a551e593b9788e433f7a99857729acdd5dd53.tar.gz otp-ee6a551e593b9788e433f7a99857729acdd5dd53.tar.bz2 otp-ee6a551e593b9788e433f7a99857729acdd5dd53.zip |
erl_bif_types: Add a selection of maps BIFs
* maps:from_list/1
* maps:get/2
* maps:is_key/2
* maps:merge/2
* maps:put/3
* maps:size/1
* maps:to_list/1
* maps:update/3
Diffstat (limited to 'lib/hipe/cerl/erl_types.erl')
-rw-r--r-- | lib/hipe/cerl/erl_types.erl | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/lib/hipe/cerl/erl_types.erl b/lib/hipe/cerl/erl_types.erl index 6c4386892d..ea69e54c83 100644 --- a/lib/hipe/cerl/erl_types.erl +++ b/lib/hipe/cerl/erl_types.erl @@ -158,6 +158,9 @@ t_map_entries/2, t_map_entries/1, t_map_def_key/2, t_map_def_key/1, t_map_def_val/2, t_map_def_val/1, + t_map_get/2, t_map_get/3, + t_map_is_key/2, t_map_is_key/3, + t_map_update/2, t_map_update/3, t_map_put/2, t_map_put/3, t_matchstate/0, t_matchstate/2, @@ -1851,6 +1854,93 @@ map_put({Key, Value}, ?map(Pairs,DefK,DefV), Opaques) -> end end. +-spec t_map_update({erl_type(), erl_type()}, erl_type()) -> erl_type(). + +t_map_update(KV, Map) -> + t_map_update(KV, Map, 'universe'). + +-spec t_map_update({erl_type(), erl_type()}, erl_type(), opaques()) -> erl_type(). + +t_map_update(_, ?none, _) -> ?none; +t_map_update(KV={Key, _}, M, Opaques) -> + case t_is_subtype(t_atom('true'), t_map_is_key(Key, M, Opaques)) of + false -> ?none; + true -> t_map_put(KV, M, Opaques) + end. + +-spec t_map_get(erl_type(), erl_type()) -> erl_type(). + +t_map_get(Key, Map) -> + t_map_get(Key, Map, 'universe'). + +-spec t_map_get(erl_type(), erl_type(), opaques()) -> erl_type(). + +t_map_get(Key, Map, Opaques) -> + do_opaque(Map, Opaques, + fun(UM) -> + do_opaque(Key, Opaques, fun(UK) -> map_get(UK, UM) end) + end). + +map_get(_, ?none) -> ?none; +map_get(Key, ?map(Pairs, DefK, DefV)) -> + DefRes = + case t_do_overlap(DefK, Key) of + false -> t_none(); + true -> DefV + end, + case t_is_singleton(Key) of + false -> + lists:foldl(fun({K, _, V}, Res) -> + case t_do_overlap(K, Key) of + false -> Res; + true -> t_sup(Res, V) + end + end, DefRes, Pairs); + true -> + case lists:keyfind(Key, 1, Pairs) of + false -> DefRes; + {_, _, ValType} -> ValType + end + end. + +-spec t_map_is_key(erl_type(), erl_type()) -> erl_type(). + +t_map_is_key(Key, Map) -> + t_map_is_key(Key, Map, 'universe'). + +-spec t_map_is_key(erl_type(), erl_type(), opaques()) -> erl_type(). + +t_map_is_key(Key, Map, Opaques) -> + do_opaque(Map, Opaques, + fun(UM) -> + do_opaque(Key, Opaques, fun(UK) -> map_is_key(UK, UM) end) + end). + +map_is_key(_, ?none) -> ?none; +map_is_key(Key, ?map(Pairs, DefK, _DefV)) -> + case t_is_singleton(Key) of + true -> + case lists:keyfind(Key, 1, Pairs) of + {Key, ?mand, _} -> t_atom(true); + {Key, ?opt, ?none} -> t_atom(false); + {Key, ?opt, _} -> t_boolean(); + false -> + case t_do_overlap(DefK, Key) of + false -> t_atom(false); + true -> t_boolean() + end + end; + false -> + case t_do_overlap(DefK, Key) + orelse lists:any(fun({_,_,?none}) -> false; + ({K,_,_}) -> t_do_overlap(K, Key) + end, Pairs) + of + true -> t_boolean(); + false -> t_atom(false) + end + end. + %%----------------------------------------------------------------------------- %% Tuples %% @@ -3931,6 +4021,11 @@ subtype_is_equal(T1, T2) -> t_is_instance(ConcreteType, Type) -> t_is_subtype(ConcreteType, t_unopaque(Type)). +-spec t_do_overlap(erl_type(), erl_type()) -> boolean(). + +t_do_overlap(TypeA, TypeB) -> + not (t_is_none_or_unit(t_inf(TypeA, TypeB))). + -spec t_unopaque(erl_type()) -> erl_type(). t_unopaque(T) -> |