<commit_before>(***********************************************************************)
(*                                                                     *)
(*                                OCaml                                *)
(*                                                                     *)
(*            <NAME>, <NAME>, INRIA Rocquencourt         *)
(*                                                                     *)
(*  Copyright 1996 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the Q Public License version 1.0.               *)
(*                                                                     *)
(***********************************************************************)

(* Compute constructor and label descriptions from type declarations,
   determining their representation. *)

open Asttypes
open Types
open Btype

(* Simplified version of Ctype.free_vars *)
let free_vars ty =
  let ret = ref TypeSet.empty in
  let rec loop ty =
    let ty = repr ty in
    if ty.level >= lowest_level then begin
      ty.level <- pivot_level - ty.level;
      match ty.desc with
      | Tvar _ ->
          ret := TypeSet.add ty !ret
      | Tvariant row ->
          let row = row_repr row in
          iter_row loop row;
          if not (static_row row) then loop row.row_more
      | _ ->
          iter_type_expr loop ty
    end
  in
  loop ty;
  unmark_type ty;
  !ret

let newgenconstr path tyl = newgenty (Tconstr (path, tyl, ref Mnil))

let constructor_descrs ty_path decl manifest_decl cstrs =
  let ty_res = newgenconstr ty_path decl.type_params in
  let num_consts = ref 0 and num_nonconsts = ref 0  and num_normal = ref 0 in
  List.iter
    (fun {cd_args; cd_res; _} ->
      if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
      if cd_res = None then incr num_normal)
    cstrs;
  let tdecls = ref [] in
  let rec describe_constructors idx_const idx_nonconst = function
      [] -> []
    | {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
        let ty_res =
          match cd_res with
          | Some ty_res' -> ty_res'
          | None -> ty_res
        in
        let (tag, descr_rem) =
          match cd_args with
            Cstr_tuple [] -> (Cstr_constant idx_const,
                   describe_constructors (idx_const+1) idx_nonconst rem)
          | _  -> (Cstr_block idx_nonconst,
                   describe_constructors idx_const (idx_nonconst+1) rem) in
        let existentials =
          match cd_res with
          | None -> []
          | Some type_ret ->
              let res_vars = free_vars type_ret in
              let tyl =
                match cd_args with
                | Cstr_tuple l -> l
                | Cstr_record (_, l) -> List.map (fun l -> l.ld_type) l
              in
              (* TODO: handle Tpoly *)
              let arg_vars = free_vars (newgenty (Ttuple tyl)) in
              TypeSet.elements (TypeSet.diff arg_vars res_vars)
        in
        let cstr_args, cstr_inlined =
          match cd_args with
          | Cstr_tuple l -> l, false
          | Cstr_record (id, lbls) ->
              let name = Path.last ty_path ^ "." ^ Ident.name cd_id in
              let path =
                match ty_path with
                | Path.Pdot(m, _, _) -> Path.Pdot(m, name, Path.nopos)
                | Path.Pident _ -> Path.Pident id
                | Path.Papply _ -> assert false
              in
              let type_manifest =
                match decl.type_manifest with
                | Some {desc = Tconstr(Path.Pdot (m, name, _), args, _)} ->
                    let p =
                      Path.Pdot (m, name ^ "." ^ Ident.name cd_id, Path.nopos)
                    in
                    Some (newgenconstr p args)
                | Some {desc = Tconstr(Path.Pident _, args, _)} ->
                    begin match manifest_decl with
                    | Some {type_kind = Type_variant cstrs} ->
                        let c =
                          try
                            List.find
                              (fun c -> Ident.name c.cd_id = Ident.name cd_id)
                              cstrs<commit_msg>Polymorphic fields are actually ok.<commit_after>(***********************************************************************)
(*                                                                     *)
(*                                OCaml                                *)
(*                                                                     *)
(*            <NAME>, <NAME>, INRIA Rocquencourt         *)
(*                                                                     *)
(*  Copyright 1996 Institut National de Recherche en Informatique et   *)
(*  en Automatique.  All rights reserved.  This file is distributed    *)
(*  under the terms of the Q Public License version 1.0.               *)
(*                                                                     *)
(***********************************************************************)

(* Compute constructor and label descriptions from type declarations,
   determining their representation. *)

open Asttypes
open Types
open Btype

(* Simplified version of Ctype.free_vars *)
let free_vars ty =
  let ret = ref TypeSet.empty in
  let rec loop ty =
    let ty = repr ty in
    if ty.level >= lowest_level then begin
      ty.level <- pivot_level - ty.level;
      match ty.desc with
      | Tvar _ ->
          ret := TypeSet.add ty !ret
      | Tvariant row ->
          let row = row_repr row in
          iter_row loop row;
          if not (static_row row) then loop row.row_more
      | _ ->
          iter_type_expr loop ty
    end
  in
  loop ty;
  unmark_type ty;
  !ret

let newgenconstr path tyl = newgenty (Tconstr (path, tyl, ref Mnil))

let constructor_descrs ty_path decl manifest_decl cstrs =
  let ty_res = newgenconstr ty_path decl.type_params in
  let num_consts = ref 0 and num_nonconsts = ref 0  and num_normal = ref 0 in
  List.iter
    (fun {cd_args; cd_res; _} ->
      if cd_args = Cstr_tuple [] then incr num_consts else incr num_nonconsts;
      if cd_res = None then incr num_normal)
    cstrs;
  let tdecls = ref [] in
  let rec describe_constructors idx_const idx_nonconst = function
      [] -> []
    | {cd_id; cd_args; cd_res; cd_loc; cd_attributes} :: rem ->
        let ty_res =
          match cd_res with
          | Some ty_res' -> ty_res'
          | None -> ty_res
        in
        let (tag, descr_rem) =
          match cd_args with
            Cstr_tuple [] -> (Cstr_constant idx_const,
                   describe_constructors (idx_const+1) idx_nonconst rem)
          | _  -> (Cstr_block idx_nonconst,
                   describe_constructors idx_const (idx_nonconst+1) rem) in
        let existentials =
          match cd_res with
          | None -> []
          | Some type_ret ->
              let res_vars = free_vars type_ret in
              let tyl =
                match cd_args with
                | Cstr_tuple l -> l
                | Cstr_record (_, l) -> List.map (fun l -> l.ld_type) l
              in
              (* Note: variables bound by Tpoly are Tvar, not Tunivar,
                and thus they are not considered as free, which is
                what we want. *)
              let arg_vars = free_vars (newgenty (Ttuple tyl)) in
              TypeSet.elements (TypeSet.diff arg_vars res_vars)
        in
        let cstr_args, cstr_inlined =
          match cd_args with
          | Cstr_tuple l -> l, false
          | Cstr_record (id, lbls) ->
              let name = Path.last ty_path ^ "." ^ Ident.name cd_id in
              let path =
                match ty_path with
                | Path.Pdot(m, _, _) -> Path.Pdot(m, name, Path.nopos)
                | Path.Pident _ -> Path.Pident id
                | Path.Papply _ -> assert false
              in
              let type_manifest =
                match decl.type_manifest with
                | Some {desc = Tconstr(Path.Pdot (m, name, _), args, _)} ->
                    let p =
                      Path.Pdot (m, name ^ "." ^ Ident.name cd_id, Path.nopos)
                    in
                    Some (newgenconstr p args)
                | Some {desc = Tconstr(Path.Pident _, args, _)} ->
                    begin match manifest_decl with
                    | Some {type_kind = Type_variant cstrs} ->
                        let c =
                          try
                            List.find
                              (fun c -> Ident.name c.cd_id = Ident.name cd_id)
                              cstrs
{'fraction_non_alphanumeric': 0.1076516544117647, 'fraction_numerical': 0.002527573529411765, 'mean_word_length': 1.3337801608579087, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 16, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1413123', 'n_tokens_mistral': 2396, 'n_tokens_neox': 2300, 'n_words': 710}