@@ -144,10 +144,11 @@ module IdentHashtbl = Hashtbl.Make (struct
144
144
let hash = Hashtbl. hash
145
145
end )
146
146
147
- (* generate a [loc_to_id] and an [ident_to_id] map *)
148
- let local_maps source_id poses =
149
- let loc_tbl = LocHashtbl. create 10 and ident_to_id = IdentHashtbl. create 10 in
150
- List. iter
147
+ (* populate a [loc_to_id] and an [ident_to_id] map with local informations. Also
148
+ removes the definitions from the list, since their information has been taken
149
+ into account *)
150
+ let process_local_defs source_id poses loc_tbl ident_to_id =
151
+ List. filter_map
151
152
(function
152
153
| Typedtree_traverse.Analysis. Definition id , loc ->
153
154
let name =
@@ -158,43 +159,13 @@ let local_maps source_id poses =
158
159
Odoc_model.Paths.Identifier.Mk. source_location_int (source_id, name)
159
160
in
160
161
IdentHashtbl. add ident_to_id id identifier;
161
- LocHashtbl. add loc_tbl loc identifier
162
- | _ -> () )
163
- poses;
164
- (loc_tbl, ident_to_id)
165
-
166
- let postprocess_poses poses ident_to_id loc_to_id uid_to_id uid_to_loc :
167
- Odoc_model.Lang.Source_info. infos =
168
- let poses =
169
- List. filter_map
170
- (function
171
- | Typedtree_traverse.Analysis. Definition id , loc ->
172
- Some
173
- ( Odoc_model.Lang.Source_info. Definition
174
- (IdentHashtbl. find ident_to_id id),
175
- pos_of_loc loc )
176
- | Value (LocalValue uniq ), loc -> (
177
- match IdentHashtbl. find_opt ident_to_id uniq with
178
- | Some anchor -> Some (Value anchor, pos_of_loc loc)
179
- | None -> None )
180
- | Value (DefJmp x ), loc -> (
181
- match Shape.Uid.Map. find_opt x uid_to_id with
182
- | Some id -> Some (Value id, pos_of_loc loc)
183
- | None -> None ))
184
- poses
185
- in
186
- let defs =
187
- Shape.Uid.Map. fold
188
- (fun uid id acc ->
189
- let loc_opt = Shape.Uid.Tbl. find_opt uid_to_loc uid in
190
- match loc_opt with
191
- | Some loc when not (LocHashtbl. mem loc_to_id loc) ->
192
- (Odoc_model.Lang.Source_info. Definition id, pos_of_loc loc) :: acc
193
- | _ -> acc)
194
- uid_to_id []
195
- in
196
- defs @ poses
162
+ LocHashtbl. add loc_tbl loc identifier;
163
+ None
164
+ | x -> Some x)
165
+ poses
197
166
167
+ (* In order to turn an identifier into a source identifier, we need to generate
168
+ a unique anchor for any identifier. *)
198
169
let anchor_of_identifier id =
199
170
let open Odoc_document.Url in
200
171
let open Odoc_model.Paths in
@@ -272,41 +243,65 @@ let anchor_of_identifier id =
272
243
in
273
244
anchor_of_identifier [] id |> String. concat " ."
274
245
275
- (* * Returns an environment (containing a [loc] to [id] map) and an [uid] to [id]
276
- maps. *)
277
- let id_map_of_cmt env (source_id : Odoc_model.Paths.Identifier.SourcePage.t )
278
- (uid_to_loc : Warnings.loc Types.Uid.Tbl.t ) local_loc_to_id =
279
- let uid_to_loc_map = Shape.Uid.Tbl. to_map uid_to_loc in
280
- let mk_id name =
281
- Some
282
- (Odoc_model.Paths.Identifier.Mk. source_location (source_id, name)
283
- :> Odoc_model.Paths.Identifier.SourceLocation. t)
246
+ (* Adds the global defs from the odoc environment to [loc_to_id] table *)
247
+ let process_global_defs env source_id loc_to_id =
248
+ let mk_src_id id =
249
+ let name = Odoc_model.Names.DefName. make_std (anchor_of_identifier id) in
250
+ (Odoc_model.Paths.Identifier.Mk. source_location (source_id, name)
251
+ :> Odoc_model.Paths.Identifier.SourceLocation. t)
284
252
in
285
- let uid_to_id : Odoc_model.Paths.Identifier.SourceLocation.t Shape.Uid.Map.t =
286
- Shape.Uid.Map. filter_map
287
- (fun uid loc ->
288
- if loc.Location. loc_ghost then None
289
- else
290
- let identifier = Ident_env. identifier_of_loc env loc in
291
- match identifier with
292
- | Some x ->
293
- mk_id (Odoc_model.Names.DefName. make_std (anchor_of_identifier x))
294
- | None -> (
295
- match uid with
296
- | Compilation_unit _ -> None
297
- | Item _ -> (
298
- match LocHashtbl. find_opt local_loc_to_id loc with
299
- | Some anchor -> Some anchor
300
- | None ->
301
- let name =
302
- Odoc_model.Names.DefName. make_std
303
- (Printf. sprintf " def_%d" (counter () ))
304
- in
305
- mk_id name)
306
- | _ -> None ))
307
- uid_to_loc_map
253
+ Ident_env. iter_located_identifier env @@ fun loc id ->
254
+ LocHashtbl. add loc_to_id loc (mk_src_id id)
255
+
256
+ (* The [uid_to_id] is useful as when resolving a shape, we get the uid. *)
257
+ let build_uid_to_id source_id uid_to_loc loc_to_id =
258
+ let uid_to_loc_map = Shape.Uid.Tbl. to_map uid_to_loc in
259
+ let mk_src_id () =
260
+ let name =
261
+ Odoc_model.Names.DefName. make_std (Printf. sprintf " def_%d" (counter () ))
262
+ in
263
+ (Odoc_model.Paths.Identifier.Mk. source_location (source_id, name)
264
+ :> Odoc_model.Paths.Identifier.SourceLocation. t)
308
265
in
309
- uid_to_id
266
+ Shape.Uid.Map. filter_map
267
+ (fun uid loc ->
268
+ if loc.Location. loc_ghost then None
269
+ else
270
+ match LocHashtbl. find_opt loc_to_id loc with
271
+ | Some id -> Some id
272
+ | None -> (
273
+ (* In case there is no entry for the location of the uid, we add one. *)
274
+ match uid with
275
+ | Item _ ->
276
+ let id = mk_src_id () in
277
+ LocHashtbl. add loc_to_id loc id;
278
+ Some id
279
+ | Compilation_unit _ -> None
280
+ | _ -> None ))
281
+ uid_to_loc_map
282
+
283
+ (* Turns [Typedtree_traverse] occurrence information into proper source infos *)
284
+ let process_occurrences poses uid_to_id ident_to_id =
285
+ List. filter_map
286
+ (function
287
+ | Typedtree_traverse.Analysis. Value (LocalValue uniq ), loc -> (
288
+ match IdentHashtbl. find_opt ident_to_id uniq with
289
+ | Some anchor ->
290
+ Some (Odoc_model.Lang.Source_info. Value anchor, pos_of_loc loc)
291
+ | None -> None )
292
+ | Value (DefJmp x ), loc -> (
293
+ match Shape.Uid.Map. find_opt x uid_to_id with
294
+ | Some id -> Some (Value id, pos_of_loc loc)
295
+ | None -> None )
296
+ | Definition _ , _ -> None )
297
+ poses
298
+
299
+ (* Add definition source info from the [loc_to_id] table *)
300
+ let add_definitions occurrences loc_to_id =
301
+ LocHashtbl. fold
302
+ (fun loc id acc ->
303
+ (Odoc_model.Lang.Source_info. Definition id, pos_of_loc loc) :: acc)
304
+ loc_to_id occurrences
310
305
311
306
let read_cmt_infos source_id_opt id cmt_info =
312
307
match Odoc_model.Compat. shape_of_cmt_infos cmt_info with
@@ -322,12 +317,18 @@ let read_cmt_infos source_id_opt id cmt_info =
322
317
numbers, so that adding some content at the end of a file does
323
318
not modify the anchors for existing anchors. *)
324
319
in
325
- let loc_to_id, ident_to_id = local_maps source_id occ_infos in
326
- let map = id_map_of_cmt env source_id uid_to_loc loc_to_id in
327
- let source_infos =
328
- postprocess_poses occ_infos ident_to_id loc_to_id map uid_to_loc
320
+ let loc_to_id = LocHashtbl. create 10
321
+ and ident_to_id = IdentHashtbl. create 10 in
322
+ let occurrences =
323
+ process_local_defs source_id occ_infos loc_to_id ident_to_id
324
+ in
325
+ let () = process_global_defs env source_id loc_to_id in
326
+ let uid_to_id = build_uid_to_id source_id uid_to_loc loc_to_id in
327
+ let occurrences =
328
+ process_occurrences occurrences uid_to_id ident_to_id
329
329
in
330
- ( Some (shape, map),
330
+ let source_infos = add_definitions occurrences loc_to_id in
331
+ ( Some (shape, uid_to_id),
331
332
Some
332
333
{
333
334
Odoc_model.Lang.Source_info. id = source_id;
0 commit comments