Skip to content

Commit bd1215c

Browse files
committed
Add --occurrences arg to compile-index
This adds the occurrence count to each element of the json index Signed-off-by: Paul-Elliot <[email protected]>
1 parent cb51bef commit bd1215c

File tree

8 files changed

+179
-58
lines changed

8 files changed

+179
-58
lines changed

src/odoc/bin/main.ml

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -408,15 +408,17 @@ module Indexing = struct
408408
| Some file -> Fs.File.of_string file
409409
| None -> Fs.File.of_string "index.json"
410410

411-
let index dst warnings_options inputs_in_file inputs =
411+
let index dst warnings_options inputs_in_file inputs occurrences =
412412
let output = output_file ~dst in
413413
match (inputs_in_file, inputs) with
414414
| [], [] ->
415415
Result.Error
416416
(`Msg
417417
"At least one of --file-list or an .odocl file must be passed to \
418418
odoc compile-index")
419-
| _ -> Indexing.compile ~output ~warnings_options inputs_in_file inputs
419+
| _ ->
420+
Indexing.compile ~output ~warnings_options ~occurrences inputs_in_file
421+
inputs
420422

421423
let cmd =
422424
let dst =
@@ -427,6 +429,13 @@ module Indexing = struct
427429
Arg.(
428430
value & opt (some string) None & info ~docs ~docv:"PATH" ~doc [ "o" ])
429431
in
432+
let occurrences =
433+
let doc = "Occurrence file." in
434+
Arg.(
435+
value
436+
& opt (some convert_fpath) None
437+
& info ~docs ~docv:"PATH" ~doc [ "occurrences" ])
438+
in
430439
let inputs_in_file =
431440
let doc =
432441
"Input text file containing a line-separated list of paths to .odocl \
@@ -442,7 +451,8 @@ module Indexing = struct
442451
in
443452
Term.(
444453
const handle_error
445-
$ (const index $ dst $ warnings_options $ inputs_in_file $ inputs))
454+
$ (const index $ dst $ warnings_options $ inputs_in_file $ inputs
455+
$ occurrences))
446456

447457
let info ~docs =
448458
let doc =

src/odoc/indexing.ml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,19 @@ let parse_input_files input =
3232
(Ok []) input
3333
>>= fun files -> Ok (List.concat files)
3434

35-
let compile ~output ~warnings_options inputs_in_file inputs =
35+
let read_occurrences file =
36+
let ic = open_in_bin file in
37+
let htbl : Odoc_occurrences.Table.t = Marshal.from_channel ic in
38+
htbl
39+
40+
let compile ~output ~warnings_options ~occurrences inputs_in_file inputs =
3641
parse_input_files inputs_in_file >>= fun files ->
3742
let files = List.rev_append inputs files in
43+
let occurrences =
44+
match occurrences with
45+
| None -> None
46+
| Some occurrences -> Some (read_occurrences (Fpath.to_string occurrences))
47+
in
3848
let output_channel =
3949
Fs.Directory.mkdir_p (Fs.File.dirname output);
4050
open_out_bin (Fs.File.to_string output)
@@ -51,7 +61,7 @@ let compile ~output ~warnings_options inputs_in_file inputs =
5161
(fun acc file ->
5262
match
5363
handle_file
54-
~unit:(print Json_search.unit acc)
64+
~unit:(print (Json_search.unit ?occurrences) acc)
5565
~page:(print Json_search.page acc)
5666
file
5767
with

src/odoc/indexing.mli

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ val handle_file :
1111
val compile :
1212
output:Fs.file ->
1313
warnings_options:Odoc_model.Error.warnings_options ->
14+
occurrences:Fs.file option ->
1415
Fs.file list ->
1516
Fs.file list ->
1617
(unit, [> msg ]) result

src/search/json_index/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
(library
22
(name odoc_json_index)
33
(public_name odoc.json_index)
4-
(libraries tyxml odoc_model odoc_search))
4+
(libraries tyxml odoc_model odoc_search odoc_occurrences))

src/search/json_index/json_search.ml

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ let of_doc (doc : Odoc_model.Comment.docs) =
8686
let txt = Text.of_doc doc in
8787
`String txt
8888

89-
let of_entry ({ Entry.id; doc; kind } as entry) html =
89+
let of_entry ({ Entry.id; doc; kind } as entry) html occurrences =
9090
let j_id = of_id id in
9191
let doc = of_doc doc in
9292
let kind =
@@ -167,11 +167,27 @@ let of_entry ({ Entry.id; doc; kind } as entry) html =
167167
("parent_type", `String (Text.of_type parent_type));
168168
]
169169
in
170+
let occurrences =
171+
match occurrences with
172+
| Some occ ->
173+
`Object
174+
[
175+
("direct", `Float (float_of_int occ.Odoc_occurrences.Table.direct));
176+
("indirect", `Float (float_of_int occ.indirect));
177+
]
178+
| None -> `Null
179+
in
170180
match Json_display.of_entry entry html with
171181
| Result.Ok display ->
172182
Result.Ok
173183
(`Object
174-
[ ("id", j_id); ("doc", doc); ("kind", kind); ("display", display) ])
184+
[
185+
("id", j_id);
186+
("doc", doc);
187+
("kind", kind);
188+
("display", display);
189+
("occurrences", occurrences);
190+
])
175191
| Error _ as e -> e
176192

177193
let output_json ppf first entries =
@@ -180,8 +196,8 @@ let output_json ppf first entries =
180196
Format.fprintf ppf "%s\n" str
181197
in
182198
List.fold_left
183-
(fun first (entry, html) ->
184-
let json = of_entry entry html in
199+
(fun first (entry, html, occurrences) ->
200+
let json = of_entry entry html occurrences in
185201
if not first then Format.fprintf ppf ",";
186202
match json with
187203
| Ok json ->
@@ -192,11 +208,20 @@ let output_json ppf first entries =
192208
true)
193209
first entries
194210

195-
let unit ppf u =
211+
let unit ?occurrences ppf u =
212+
let get_occ id =
213+
match occurrences with
214+
| None -> None
215+
| Some occurrences -> Odoc_occurrences.Table.get occurrences id
216+
in
196217
let f (first, id) i =
197218
let entries = Entry.entries_of_item id i in
198219
let entries =
199-
List.map (fun entry -> (entry, Html.of_entry entry)) entries
220+
List.map
221+
(fun entry ->
222+
let occ = get_occ entry.Entry.id in
223+
(entry, Html.of_entry entry, occ))
224+
entries
200225
in
201226
let id =
202227
match i with
@@ -230,7 +255,7 @@ let page ppf (page : Odoc_model.Lang.Page.t) =
230255
Entry.entries_of_item (page.name :> Odoc_model.Paths.Identifier.t) i
231256
in
232257
let entries =
233-
List.map (fun entry -> (entry, Html.of_entry entry)) entries
258+
List.map (fun entry -> (entry, Html.of_entry entry, None)) entries
234259
in
235260
output_json ppf first entries
236261
in
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
(** This module generates json intended to be consumed by search engines. *)
22

3-
val unit : Format.formatter -> Odoc_model.Lang.Compilation_unit.t -> unit
3+
val unit :
4+
?occurrences:Odoc_occurrences.Table.t ->
5+
Format.formatter ->
6+
Odoc_model.Lang.Compilation_unit.t ->
7+
unit
48
val page : Format.formatter -> Odoc_model.Lang.Page.t -> unit

test/occurrences/double_wrapped.t/run.t

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,3 +135,74 @@ We can also include hidden ids:
135135
Main__A was used directly 1 times and indirectly 0 times
136136
Main__B was used directly 1 times and indirectly 0 times
137137
Main__C was used directly 1 times and indirectly 0 times
138+
139+
We can use the generated table when generating the json output:
140+
141+
$ odoc compile-index -o index.json --occurrences occurrences-all.odoc main/main.odocl
142+
143+
$ cat index.json | jq sort | jq '.[]' -c
144+
{"id":[{"kind":"Root","name":"Main"}],"doc":"Handwritten top-level module","kind":{"kind":"Module"},"display":{"url":"Main/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">.</span><span class=\"entry-name\">Main</span></code><div class=\"entry-comment\"><div><p>Handwritten top-level module</p></div></div>"},"occurrences":{"direct":0,"indirect":11}}
145+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"A"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/A/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.</span><span class=\"entry-name\">A</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":4,"indirect":6}}
146+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/B/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.</span><span class=\"entry-name\">B</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":1,"indirect":0}}
147+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Module","name":"M"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/B/M/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.</span><span class=\"entry-name\">M</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
148+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Module","name":"Y"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/B/Y/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.</span><span class=\"entry-name\">Y</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
149+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Module","name":"Z"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/B/Z/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.</span><span class=\"entry-name\">Z</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
150+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Module","name":"Z"},{"kind":"Module","name":"Y"}],"doc":"","kind":{"kind":"Module"},"display":{"url":"Main/B/Z/Y/index.html","html":"<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.Z.</span><span class=\"entry-name\">Y</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
151+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"A"},{"kind":"ModuleType","name":"M"}],"doc":"","kind":{"kind":"ModuleType"},"display":{"url":"Main/A/module-type-M/index.html","html":"<code class=\"entry-kind\">sig</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.A.</span><span class=\"entry-name\">M</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":2,"indirect":0}}
152+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"ModuleType","name":"Y"}],"doc":"","kind":{"kind":"ModuleType"},"display":{"url":"Main/B/module-type-Y/index.html","html":"<code class=\"entry-kind\">sig</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.</span><span class=\"entry-name\">Y</span></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
153+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"A"},{"kind":"Type","name":"t"}],"doc":"","kind":{"kind":"TypeDecl","private":false,"manifest":"string","constraints":[]},"display":{"url":"Main/A/index.html#type-t","html":"<code class=\"entry-kind\">type</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.A.</span><span class=\"entry-name\">t</span><code class=\"entry-rhs\"> = string</code></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":1,"indirect":0}}
154+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"A"},{"kind":"Value","name":"(||>)"}],"doc":"","kind":{"kind":"Value","type":"int -> int -> int"},"display":{"url":"Main/A/index.html#val-(||>)","html":"<code class=\"entry-kind\">val</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.A.</span><span class=\"entry-name\">(||&gt;)</span><code class=\"entry-rhs\"> : int -&gt; int -&gt; int</code></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":1,"indirect":0}}
155+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"A"},{"kind":"Value","name":"x"}],"doc":"","kind":{"kind":"Value","type":"int"},"display":{"url":"Main/A/index.html#val-x","html":"<code class=\"entry-kind\">val</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.A.</span><span class=\"entry-name\">x</span><code class=\"entry-rhs\"> : int</code></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":{"direct":2,"indirect":0}}
156+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Value","name":"y"}],"doc":"","kind":{"kind":"Value","type":"int"},"display":{"url":"Main/B/index.html#val-y","html":"<code class=\"entry-kind\">val</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.</span><span class=\"entry-name\">y</span><code class=\"entry-rhs\"> : int</code></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
157+
{"id":[{"kind":"Root","name":"Main"},{"kind":"Module","name":"B"},{"kind":"Module","name":"Z"},{"kind":"Value","name":"y"}],"doc":"","kind":{"kind":"Value","type":"int"},"display":{"url":"Main/B/Z/index.html#val-y","html":"<code class=\"entry-kind\">val</code><code class=\"entry-title\"><span class=\"prefix-name\">Main.B.Z.</span><span class=\"entry-name\">y</span><code class=\"entry-rhs\"> : int</code></code><div class=\"entry-comment\"><div></div></div>"},"occurrences":null}
158+
159+
$ cat index.json | jq sort | head -n 33
160+
[
161+
{
162+
"id": [
163+
{
164+
"kind": "Root",
165+
"name": "Main"
166+
}
167+
],
168+
"doc": "Handwritten top-level module",
169+
"kind": {
170+
"kind": "Module"
171+
},
172+
"display": {
173+
"url": "Main/index.html",
174+
"html": "<code class=\"entry-kind\">mod</code><code class=\"entry-title\"><span class=\"prefix-name\">.</span><span class=\"entry-name\">Main</span></code><div class=\"entry-comment\"><div><p>Handwritten top-level module</p></div></div>"
175+
},
176+
"occurrences": {
177+
"direct": 0,
178+
"indirect": 11
179+
}
180+
},
181+
{
182+
"id": [
183+
{
184+
"kind": "Root",
185+
"name": "Main"
186+
},
187+
{
188+
"kind": "Module",
189+
"name": "A"
190+
}
191+
],
192+
"doc": "",
193+
194+
$ cat index.json | jq -r '.[] | "\(.id | map("\(.kind)-\(.name)") | join(".")), direct: \(.occurrences.direct), indirect: \(.occurrences.indirect)"' | sort
195+
Root-Main, direct: 0, indirect: 11
196+
Root-Main.Module-A, direct: 4, indirect: 6
197+
Root-Main.Module-A.ModuleType-M, direct: 2, indirect: 0
198+
Root-Main.Module-A.Type-t, direct: 1, indirect: 0
199+
Root-Main.Module-A.Value-(||>), direct: 1, indirect: 0
200+
Root-Main.Module-A.Value-x, direct: 2, indirect: 0
201+
Root-Main.Module-B, direct: 1, indirect: 0
202+
Root-Main.Module-B.Module-M, direct: null, indirect: null
203+
Root-Main.Module-B.Module-Y, direct: null, indirect: null
204+
Root-Main.Module-B.Module-Z, direct: null, indirect: null
205+
Root-Main.Module-B.Module-Z.Module-Y, direct: null, indirect: null
206+
Root-Main.Module-B.Module-Z.Value-y, direct: null, indirect: null
207+
Root-Main.Module-B.ModuleType-Y, direct: null, indirect: null
208+
Root-Main.Module-B.Value-y, direct: null, indirect: null

0 commit comments

Comments
 (0)