zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

call_without_opaque.ex (2294B)


      1 defmodule Dialyxir.Warnings.CallWithoutOpaque do
      2   @moduledoc """
      3   Function call without opaqueness type mismatch.
      4 
      5   ## Example
      6 
      7       defmodule OpaqueStruct do
      8         defstruct [:opaque]
      9 
     10         @opaque t :: %OpaqueStruct{}
     11       end
     12 
     13       defmodule Example do
     14         @spec error(OpaqueStruct.t()) :: :error
     15         def error(struct = %OpaqueStruct{}) do
     16           do_error(struct)
     17         end
     18 
     19         @spec do_error(OpaqueStruct.t()) :: :error
     20         defp do_error(_) do
     21           :error
     22         end
     23       end
     24   """
     25 
     26   @behaviour Dialyxir.Warning
     27 
     28   @impl Dialyxir.Warning
     29   @spec warning() :: :call_without_opaque
     30   def warning(), do: :call_without_opaque
     31 
     32   @impl Dialyxir.Warning
     33   @spec format_short([String.t()]) :: String.t()
     34   def format_short([_module, function | _]) do
     35     "Type mismatch in call without opaque term in #{function}."
     36   end
     37 
     38   @impl Dialyxir.Warning
     39   @spec format_long([String.t()]) :: String.t()
     40   def format_long([module, function, args, expected_triples]) do
     41     expected = form_expected_without_opaque(expected_triples)
     42     pretty_module = Erlex.pretty_print(module)
     43     pretty_args = Erlex.pretty_print_args(args)
     44 
     45     """
     46     Function call without opaqueness type mismatch.
     47 
     48     Call does not have expected #{expected}.
     49 
     50     #{pretty_module}.#{function}#{pretty_args}
     51     """
     52   end
     53 
     54   # We know which positions N are to blame;
     55   # the list of triples will never be empty.
     56   defp form_expected_without_opaque([{position, type, type_string}]) do
     57     pretty_type = Erlex.pretty_print_type(type_string)
     58     form_position_string = Dialyxir.WarningHelpers.form_position_string([position])
     59 
     60     if :erl_types.t_is_opaque(type) do
     61       "opaque term of type #{pretty_type} in the #{form_position_string} position"
     62     else
     63       "term of type #{pretty_type} (with opaque subterms) in the #{form_position_string} position"
     64     end
     65   end
     66 
     67   # TODO: can do much better here
     68   defp form_expected_without_opaque(expected_triples) do
     69     {arg_positions, _typess, _type_strings} = :lists.unzip3(expected_triples)
     70     form_position_string = Dialyxir.WarningHelpers.form_position_string(arg_positions)
     71     "opaque terms in the #{form_position_string} position"
     72   end
     73 
     74   @impl Dialyxir.Warning
     75   @spec explain() :: String.t()
     76   def explain() do
     77     @moduledoc
     78   end
     79 end