diff options
Diffstat (limited to 'lib/dialyzer/src/dialyzer_utils.erl')
-rw-r--r-- | lib/dialyzer/src/dialyzer_utils.erl | 65 |
1 files changed, 57 insertions, 8 deletions
diff --git a/lib/dialyzer/src/dialyzer_utils.erl b/lib/dialyzer/src/dialyzer_utils.erl index 3fe026b096..245c099fef 100644 --- a/lib/dialyzer/src/dialyzer_utils.erl +++ b/lib/dialyzer/src/dialyzer_utils.erl @@ -46,6 +46,7 @@ ]). -include("dialyzer.hrl"). +-include("../../compiler/src/core_parse.hrl"). %%-define(DEBUG, true). @@ -751,9 +752,13 @@ pp_hook(Node, Ctxt, Cont) -> map -> pp_map(Node, Ctxt, Cont); literal -> - case is_map(cerl:concrete(Node)) of - true -> pp_map(Node, Ctxt, Cont); - false -> Cont(Node, Ctxt) + case cerl:concrete(Node) of + Map when is_map(Map) -> + pp_map(Node, Ctxt, Cont); + Bitstr when is_bitstring(Bitstr) -> + pp_binary(Node, Ctxt, Cont); + _ -> + Cont(Node, Ctxt) end; _ -> Cont(Node, Ctxt) @@ -761,7 +766,7 @@ pp_hook(Node, Ctxt, Cont) -> pp_binary(Node, Ctxt, Cont) -> prettypr:beside(prettypr:text("<<"), - prettypr:beside(pp_segments(cerl:binary_segments(Node), + prettypr:beside(pp_segments(cerl_binary_segments(Node), Ctxt, Cont), prettypr:text(">>"))). @@ -780,10 +785,29 @@ pp_segment(Node, Ctxt, Cont) -> Unit = cerl:bitstr_unit(Node), Type = cerl:bitstr_type(Node), Flags = cerl:bitstr_flags(Node), - prettypr:beside(Cont(Val, Ctxt), - prettypr:beside(pp_size(Size, Ctxt, Cont), - prettypr:beside(pp_opts(Type, Flags), - pp_unit(Unit, Ctxt, Cont)))). + RestPP = + case {concrete(Unit), concrete(Type), concrete(Flags)} of + {1, integer, [unsigned, big]} -> % Simplify common cases. + case concrete(Size) of + 8 -> prettypr:text(""); + _ -> pp_size(Size, Ctxt, Cont) + end; + {8, binary, [unsigned, big]} -> + SizePP = pp_size(Size, Ctxt, Cont), + prettypr:beside(SizePP, + prettypr:beside(prettypr:text("/"), pp_atom(Type))); + _What -> + SizePP = pp_size(Size, Ctxt, Cont), + UnitPP = pp_unit(Unit, Ctxt, Cont), + OptsPP = pp_opts(Type, Flags), + prettypr:beside(SizePP, prettypr:beside(OptsPP, UnitPP)) + end, + prettypr:beside(Cont(Val, Ctxt), RestPP). + +concrete(Cerl) -> + try cerl:concrete(Cerl) + catch _:_ -> anything_unexpected + end. pp_size(Size, Ctxt, Cont) -> case cerl:is_c_atom(Size) of @@ -859,6 +883,31 @@ seq([H | T], Separator, Ctxt, Fun) -> seq([], _, _, _) -> [prettypr:empty()]. +cerl_binary_segments(#c_literal{val = B}) when is_bitstring(B) -> + segs_from_bitstring(B); +cerl_binary_segments(CBinary) -> + cerl:binary_segments(CBinary). + +%% Copied from core_pp. The function cerl:binary_segments/2 should/could +%% be extended to handle literals, but then the cerl module cannot be +%% HiPE-compiled as of Erlang/OTP 22.0 (due to <<I:N>>). +segs_from_bitstring(<<H,T/bitstring>>) -> + [#c_bitstr{val=#c_literal{val=H}, + size=#c_literal{val=8}, + unit=#c_literal{val=1}, + type=#c_literal{val=integer}, + flags=#c_literal{val=[unsigned,big]}}|segs_from_bitstring(T)]; +segs_from_bitstring(<<>>) -> + []; +segs_from_bitstring(Bitstring) -> + N = bit_size(Bitstring), + <<I:N>> = Bitstring, + [#c_bitstr{val=#c_literal{val=I}, + size=#c_literal{val=N}, + unit=#c_literal{val=1}, + type=#c_literal{val=integer}, + flags=#c_literal{val=[unsigned,big]}}]. + %%------------------------------------------------------------------------------ -spec refold_pattern(cerl:cerl()) -> cerl:cerl(). |