···11+module Table = Table
22+33+let of_impl ~include_hidden unit htbl =
44+ let incr tbl p =
55+ let open Odoc_model.Paths.Path.Resolved in
66+ let p = (p :> t) in
77+ let id = identifier p in
88+ if (not (is_hidden p)) || include_hidden then Table.add tbl id
99+ in
1010+ let open Odoc_model.Lang in
1111+ List.iter
1212+ (function
1313+ | Source_info.Module { documentation = Some (`Resolved p); _ }, _ ->
1414+ incr htbl p
1515+ | Value { documentation = Some (`Resolved p); _ }, _ -> incr htbl p
1616+ | ModuleType { documentation = Some (`Resolved p); _ }, _ -> incr htbl p
1717+ | Type { documentation = Some (`Resolved p); _ }, _ -> incr htbl p
1818+ | _ -> ())
1919+ unit.Implementation.source_info
2020+2121+let aggregate ~tbl ~data =
2222+ Table.iter
2323+ (fun id { Table.direct; _ } -> Table.add ~quantity:direct tbl id)
2424+ data
+9
src/occurrences/odoc_occurrences.mli
···11+open Odoc_model.Lang
22+33+module Table = Table
44+55+val of_impl : include_hidden:bool -> Implementation.t -> Table.t -> unit
66+(** Add all occurrences from implementation of a compilation unit into a table *)
77+88+val aggregate : tbl:Table.t -> data:Table.t -> unit
99+(** Aggregate [data] into [tbl] *)
+86
src/occurrences/table.ml
···11+module H = Hashtbl.Make (Odoc_model.Paths.Identifier)
22+33+type t = item H.t
44+and item = { direct : int; indirect : int; sub : item H.t }
55+type key = Odoc_model.Paths.Identifier.t
66+77+let v_item () = { direct = 0; indirect = 0; sub = H.create 0 }
88+99+let v () = H.create 0
1010+1111+let add ?(quantity = 1) tbl id =
1212+ let rec add ?(kind = `Indirect) id =
1313+ let incr htbl id =
1414+ let { direct; indirect; sub } =
1515+ try H.find htbl id with Not_found -> v_item ()
1616+ in
1717+ let direct, indirect =
1818+ match kind with
1919+ | `Direct -> (direct + quantity, indirect)
2020+ | `Indirect -> (direct, indirect + quantity)
2121+ in
2222+ H.replace htbl id { direct; indirect; sub };
2323+ sub
2424+ in
2525+ let do_ parent =
2626+ let htbl = add (parent :> key) in
2727+ incr htbl id
2828+ in
2929+ match id.iv with
3030+ | `InstanceVariable (parent, _) -> do_ parent
3131+ | `Parameter (parent, _) -> do_ parent
3232+ | `Module (parent, _) -> do_ parent
3333+ | `ModuleType (parent, _) -> do_ parent
3434+ | `Method (parent, _) -> do_ parent
3535+ | `Field (parent, _) -> do_ parent
3636+ | `Extension (parent, _) -> do_ parent
3737+ | `Type (parent, _) -> do_ parent
3838+ | `CoreType _ -> incr tbl id
3939+ | `Constructor (parent, _) -> do_ parent
4040+ | `Exception (parent, _) -> do_ parent
4141+ | `ExtensionDecl (parent, _, _) -> do_ parent
4242+ | `Class (parent, _) -> do_ parent
4343+ | `Value (parent, _) -> do_ parent
4444+ | `ClassType (parent, _) -> do_ parent
4545+ | `Root _ -> incr tbl id
4646+ | `SourcePage _ | `Page _ | `LeafPage _ | `SourceLocation _
4747+ | `CoreException _ | `Label _ | `SourceLocationMod _ | `Result _
4848+ | `AssetFile _ | `SourceDir _ | `SourceLocationInternal _ ->
4949+ assert false
5050+ in
5151+ let _htbl = add ~kind:`Direct id in
5252+ ()
5353+5454+let rec get t id =
5555+ let do_ parent =
5656+ get t (parent :> key) |> function
5757+ | None -> None
5858+ | Some { sub; _ } -> ( try Some (H.find sub id) with Not_found -> None)
5959+ in
6060+ match id.iv with
6161+ | `InstanceVariable (parent, _) -> do_ parent
6262+ | `Parameter (parent, _) -> do_ parent
6363+ | `Module (parent, _) -> do_ parent
6464+ | `ModuleType (parent, _) -> do_ parent
6565+ | `Method (parent, _) -> do_ parent
6666+ | `Field (parent, _) -> do_ parent
6767+ | `Extension (parent, _) -> do_ parent
6868+ | `ExtensionDecl (parent, _, _) -> do_ parent
6969+ | `Type (parent, _) -> do_ parent
7070+ | `Constructor (parent, _) -> do_ parent
7171+ | `Exception (parent, _) -> do_ parent
7272+ | `Class (parent, _) -> do_ parent
7373+ | `Value (parent, _) -> do_ parent
7474+ | `ClassType (parent, _) -> do_ parent
7575+ | `Root _ -> ( try Some (H.find t id) with Not_found -> None)
7676+ | `SourcePage _ | `Page _ | `LeafPage _ | `CoreType _ | `SourceLocation _
7777+ | `CoreException _ | `Label _ | `SourceLocationMod _ | `Result _
7878+ | `AssetFile _ | `SourceDir _ | `SourceLocationInternal _ ->
7979+ assert false
8080+8181+let rec iter f tbl =
8282+ H.iter
8383+ (fun id v ->
8484+ iter f v.sub;
8585+ f id v)
8686+ tbl
+11
src/occurrences/table.mli
···11+type t
22+type item = { direct : int; indirect : int; sub : t }
33+type key = Odoc_model.Paths.Identifier.t
44+55+val v : unit -> t
66+77+val add : ?quantity:int -> t -> key -> unit
88+99+val iter : (key -> item -> unit) -> t -> unit
1010+1111+val get : t -> key -> item option
···3434 acc dir)
3535 (Ok init)
36363737-module H = Hashtbl.Make (Odoc_model.Paths.Identifier)
3838-3939-module Occtbl : sig
4040- type item = { direct : int; indirect : int; sub : item H.t }
4141- type t = item H.t
4242- type key = Odoc_model.Paths.Identifier.t
4343- val v : unit -> t
4444-4545- val add : t -> key -> unit
4646-4747- val iter : (key -> item -> unit) -> t -> unit
4848-4949- val get : t -> key -> item option
5050-end = struct
5151- type item = { direct : int; indirect : int; sub : item H.t }
5252- type t = item H.t
5353- type key = Odoc_model.Paths.Identifier.t
5454-5555- let v_item () = { direct = 0; indirect = 0; sub = H.create 0 }
5656-5757- let v () = H.create 0
5858-5959- let add tbl id =
6060- let rec add ?(kind = `Indirect) id =
6161- let incr htbl id =
6262- let { direct; indirect; sub } =
6363- try H.find htbl id with Not_found -> v_item ()
6464- in
6565- let direct, indirect =
6666- match kind with
6767- | `Direct -> (direct + 1, indirect)
6868- | `Indirect -> (direct, indirect + 1)
6969- in
7070- H.replace htbl id { direct; indirect; sub };
7171- sub
7272- in
7373- let do_ parent =
7474- let htbl = add (parent :> key) in
7575- incr htbl id
7676- in
7777- match id.iv with
7878- | `InstanceVariable (parent, _) -> do_ parent
7979- | `Parameter (parent, _) -> do_ parent
8080- | `Module (parent, _) -> do_ parent
8181- | `ModuleType (parent, _) -> do_ parent
8282- | `Method (parent, _) -> do_ parent
8383- | `Field (parent, _) -> do_ parent
8484- | `Extension (parent, _) -> do_ parent
8585- | `Type (parent, _) -> do_ parent
8686- | `CoreType _ -> incr tbl id
8787- | `Constructor (parent, _) -> do_ parent
8888- | `Exception (parent, _) -> do_ parent
8989- | `ExtensionDecl (parent, _, _) -> do_ parent
9090- | `Class (parent, _) -> do_ parent
9191- | `Value (parent, _) -> do_ parent
9292- | `ClassType (parent, _) -> do_ parent
9393- | `Root _ -> incr tbl id
9494- | `SourcePage _ | `Page _ | `LeafPage _ | `SourceLocation _
9595- | `CoreException _ | `Label _ | `SourceLocationMod _ | `Result _
9696- | `AssetFile _ | `SourceDir _ | `SourceLocationInternal _ ->
9797- assert false
9898- in
9999- let _htbl = add ~kind:`Direct id in
100100- ()
101101-102102- let rec get t id =
103103- let do_ parent =
104104- get t (parent :> key) |> function
105105- | None -> None
106106- | Some { sub; _ } -> ( try Some (H.find sub id) with Not_found -> None)
107107- in
108108- match id.iv with
109109- | `InstanceVariable (parent, _) -> do_ parent
110110- | `Parameter (parent, _) -> do_ parent
111111- | `Module (parent, _) -> do_ parent
112112- | `ModuleType (parent, _) -> do_ parent
113113- | `Method (parent, _) -> do_ parent
114114- | `Field (parent, _) -> do_ parent
115115- | `Extension (parent, _) -> do_ parent
116116- | `ExtensionDecl (parent, _, _) -> do_ parent
117117- | `Type (parent, _) -> do_ parent
118118- | `Constructor (parent, _) -> do_ parent
119119- | `Exception (parent, _) -> do_ parent
120120- | `Class (parent, _) -> do_ parent
121121- | `Value (parent, _) -> do_ parent
122122- | `ClassType (parent, _) -> do_ parent
123123- | `Root _ -> ( try Some (H.find t id) with Not_found -> None)
124124- | `SourcePage _ | `Page _ | `LeafPage _ | `CoreType _ | `SourceLocation _
125125- | `CoreException _ | `Label _ | `SourceLocationMod _ | `Result _
126126- | `AssetFile _ | `SourceDir _ | `SourceLocationInternal _ ->
127127- assert false
128128-129129- let rec iter f tbl =
130130- H.iter
131131- (fun id v ->
132132- iter f v.sub;
133133- f id v)
134134- tbl
135135-end
136136-13737let count ~dst ~warnings_options:_ directories include_hidden =
138138- let htbl = H.create 100 in
3838+ let htbl = Odoc_occurrences.Table.v () in
13939 let f () (unit : Odoc_model.Lang.Implementation.t) =
140140- let incr tbl p =
141141- let p = (p :> Odoc_model.Paths.Path.Resolved.t) in
142142- let id = Odoc_model.Paths.Path.Resolved.identifier p in
143143- if (not (Odoc_model.Paths.Path.Resolved.is_hidden p)) || include_hidden
144144- then Occtbl.add tbl id
145145- in
146146- let () =
147147- List.iter
148148- (function
149149- | ( Odoc_model.Lang.Source_info.Module
150150- { documentation = Some (`Resolved p); _ },
151151- _ ) ->
152152- incr htbl p
153153- | Value { documentation = Some (`Resolved p); _ }, _ -> incr htbl p
154154- | ModuleType { documentation = Some (`Resolved p); _ }, _ ->
155155- incr htbl p
156156- | Type { documentation = Some (`Resolved p); _ }, _ -> incr htbl p
157157- | _ -> ())
158158- unit.source_info
159159- in
160160- ()
4040+ Odoc_occurrences.of_impl ~include_hidden unit htbl
16141 in
16242 fold_dirs ~dirs:directories ~f ~init:() >>= fun () ->
16343 Fs.Directory.mkdir_p (Fs.File.dirname dst);
···18868 try
18969 parse_input_files file_list >>= fun new_files ->
19070 let files = files @ new_files in
191191- let from_file file : Occtbl.t =
7171+ let from_file file : Odoc_occurrences.Table.t =
19272 let ic = open_in_bin (Fs.File.to_string file) in
19373 Marshal.from_channel ic
19474 in
195195- let rec loop n f =
196196- if n > 0 then (
197197- f ();
198198- loop (n - 1) f)
199199- else ()
200200- in
20175 let occtbl =
20276 match files with
203203- | [] -> H.create 0
204204- | file1 :: files ->
205205- let acc = from_file file1 in
7777+ | [] -> Odoc_occurrences.Table.v ()
7878+ | file :: files ->
7979+ let acc = from_file file in
20680 List.iter
20781 (fun file ->
208208- Occtbl.iter
209209- (fun id { direct; _ } ->
210210- loop direct (fun () -> Occtbl.add acc id))
211211- (from_file file))
8282+ Odoc_occurrences.aggregate ~tbl:acc ~data:(from_file file))
21283 files;
21384 acc
21485 in
+3-3
test/odoc_print/occurrences_print.ml
···2233let run inp =
44 let ic = open_in_bin inp in
55- let htbl : Odoc_odoc.Occurrences.Occtbl.t = Marshal.from_channel ic in
66- Odoc_odoc.Occurrences.Occtbl.iter
77- (fun id { Odoc_odoc.Occurrences.Occtbl.direct; indirect; _ } ->
55+ let htbl : Odoc_occurrences.Table.t = Marshal.from_channel ic in
66+ Odoc_occurrences.Table.iter
77+ (fun id { Odoc_occurrences.Table.direct; indirect; _ } ->
88 let id = String.concat "." (Odoc_model.Paths.Identifier.fullname id) in
99 Format.printf "%s was used directly %d times and indirectly %d times\n" id
1010 direct indirect)