(**
   plt file reader and writer (OTP-21.1.1)
   @see <-21.1.1/lib/dialyzer/src/dialyzer_plt.erl>

   TODO:
   - read info
   - read types
   - read callbacks
   - read exported_types
   - writer
 *)

open Base
module Format = Caml.Format

type contract_constraint =
  | Subtyping of {lhs : Erl_type.var_id; rhs : Erl_type.t}
[@@deriving sexp_of]

type contract_pair =
  {f : Erl_type.t; constraints : contract_constraint list}
[@@deriving sexp_of]

type contract = {
    contracts: contract_pair list;
    args : Erl_type.t list;
TODO : ( Etf.t * Etf.t ) list ; ( * ? ? ?
  }
[@@deriving sexp_of]

* 
 { v 
 -record(plt , { info       : : ets : tid ( ) , % % {  ( ) | integer ( ) , ret_args_types ( ) } 
               types      : : ets : tid ( ) , % % { module ( ) , erl_types : type_table ( ) } 
               contracts : : ets : tid ( ) , % % {  ( ) , # contract { } } 
               callbacks : : ets : tid ( ) , % % { module ( ) , 
                                       % %   [ { mfa ( ) , 
                                       % %   dialyzer_contracts : file_contract ( ) } ] 
               exported_types : : ets : tid ( ) % % { module ( ) , sets : set ( ) } 
              } ) . 
 v } 
 @see < -21.1.1/lib/dialyzer/src/dialyzer_plt.erl#L78 > 
 
{v
-record(plt, {info      :: ets:tid(), %% {mfa() | integer(), ret_args_types()}
              types     :: ets:tid(), %% {module(), erl_types:type_table()}
              contracts :: ets:tid(), %% {mfa(), #contract{}}
              callbacks :: ets:tid(), %% {module(),
                                      %%  [{mfa(),
                                      %%  dialyzer_contracts:file_contract()}]
              exported_types :: ets:tid() %% {module(), sets:set()}
             }).
v}
@see <-21.1.1/lib/dialyzer/src/dialyzer_plt.erl#L78>
 *)
type t = {
    info : unit;
    types : unit;
    contracts : contract Poly_map.OnMfa.t;
    callbacks : unit;
    exported_types : unit;
  }
[@@deriving sexp_of]

val of_etf : Obeam.External_term_format.t -> (t, exn) Result.t
val of_file : string -> (t, exn) Result.t

*
   plt file reader and writer (OTP-21.1.1)
   @see <-21.1.1/lib/dialyzer/src/dialyzer_plt.erl>

   TODO:
   - read info
   - read types
   - read callbacks
   - read exported_types
   - writer
 

open Base
module Format = Caml.Format

type contract_constraint =
  | Subtyping of {lhs : Erl_type.var_id; rhs : Erl_type.t}
[@@deriving sexp_of]

type contract_pair =
  {f : Erl_type.t; constraints : contract_constraint list}
[@@deriving sexp_of]

type contract = {
    contracts: contract_pair list;
    args : Erl_type.t list;
TODO : ( Etf.t * Etf.t ) list ; ( * ? ? ?
  }
[@@deriving sexp_of]

* 
 { v 
 -record(plt , { info       : : ets : tid ( ) , % % {  ( ) | integer ( ) , ret_args_types ( ) } 
               types      : : ets : tid ( ) , % % { module ( ) , erl_types : type_table ( ) } 
               contracts : : ets : tid ( ) , % % {  ( ) , # contract { } } 
               callbacks : : ets : tid ( ) , % % { module ( ) , 
                                       % %   [ { mfa ( ) , 
                                       % %   dialyzer_contracts : file_contract ( ) } ] 
               exported_types : : ets : tid ( ) % % { module ( ) , sets : set ( ) } 
              } ) . 
 v } 
 @see < -21.1.1/lib/dialyzer/src/dialyzer_plt.erl#L78 > 
 
{v
-record(plt, {info      :: ets:tid(), %% {mfa() | integer(), ret_args_types()}
              types     :: ets:tid(), %% {module(), erl_types:type_table()}
              contracts :: ets:tid(), %% {mfa(), #contract{}}
              callbacks :: ets:tid(), %% {module(),
                                      %%  [{mfa(),
                                      %%  dialyzer_contracts:file_contract()}]
              exported_types :: ets:tid() %% {module(), sets:set()}
             }).
v}
@see <-21.1.1/lib/dialyzer/src/dialyzer_plt.erl#L78>
 *)
type t = {
    info : unit;
    types : unit;
    contracts : contract Poly_map.OnMfa.t;
    callbacks : unit;
    exported_types : unit;
  }
[@@deriving sexp_of]

val of_etf : Obeam.External_term_format.t -> (t, exn) Result.t
val of_file : string -> (t, exn) Result.t
