Skip to content

Commit cdda288

Browse files
committed
Move the shape lookup code into xref2, where other resolution happens
Also simplify the interfaces of the loader a bit.
1 parent 4875372 commit cdda288

24 files changed

+164
-201
lines changed

src/loader/implementation.ml

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -455,13 +455,10 @@ let anchor_of_identifier id =
455455
in
456456
anchor_of_identifier [] id |> String.concat "."
457457

458-
let of_cmt (source_id_opt : Odoc_model.Paths.Identifier.SourcePage.t option)
459-
(id : Odoc_model.Paths.Identifier.RootModule.t) (cmt : Cmt_format.cmt_infos)
458+
let of_cmt (source_id : Odoc_model.Paths.Identifier.SourcePage.t)
459+
(id : Odoc_model.Paths.Identifier.RootModule.t) (structure : Typedtree.structure)
460+
(uid_to_loc : Warnings.loc Types.Uid.Tbl.t)
460461
=
461-
let ttree = cmt.cmt_annots in
462-
match (source_id_opt, ttree, cmt.cmt_impl_shape) with
463-
| Some source_id, Cmt_format.Implementation structure, Some shape ->
464-
let uid_to_loc = cmt.cmt_uid_to_loc in
465462
let env = Ident_env.empty () in
466463
let vs =
467464
Analysis.structure (env, uid_to_loc)
@@ -504,14 +501,10 @@ let of_cmt (source_id_opt : Odoc_model.Paths.Identifier.SourcePage.t option)
504501
uid_to_loc_map
505502
in
506503

507-
( Some (shape, uid_to_id),
508-
postprocess_poses source_id vs uid_to_id uid_to_loc )
509-
| None, _, Some shape ->
510-
(Some (shape, Shape.Uid.Map.empty), [] (* At least preserve the shape *))
511-
| _ -> (None, [])
504+
(uid_to_id, postprocess_poses source_id vs uid_to_id uid_to_loc )
512505

513506
#else
514507

515-
let of_cmt _ _ _ = None, []
508+
let of_cmt _ _ _ _ = []
516509

517510
#endif

src/loader/implementation.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
val of_cmt :
2-
Odoc_model.Paths.Identifier.SourcePage.t option ->
2+
Odoc_model.Paths.Identifier.SourcePage.t ->
33
Odoc_model.Paths.Identifier.RootModule.t ->
4-
Cmt_format.cmt_infos ->
5-
Lookup_def.t option * Odoc_model.Lang.Source_info.infos
4+
Typedtree.structure -> Warnings.loc Types.Uid.Tbl.t ->
5+
Odoc_model.Paths.Identifier.Id.source_location Odoc_model.Compat.shape_uid_map * Odoc_model.Lang.Source_info.infos
66
(** Extract all implementation information from a [cmt]: the shape, and the
77
{{!Odoc_model.Lang.Source_info.infos}source infos} (local and global
88
definitions and occurrences).

src/loader/odoc_loader.ml

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
open Result
22
module Error = Odoc_model.Error
33

4-
module Lookup_def = Lookup_def
5-
64
let read_string parent_definition filename text =
75
let location =
86
let pos =
@@ -46,9 +44,17 @@ exception Make_root_error of string
4644

4745
(** [cmt_info.cmt_annots = Implementation _] *)
4846
let read_cmt_infos' source_id_opt id cmt_info =
49-
match Implementation.of_cmt source_id_opt id cmt_info with
50-
| None, _ -> None
51-
| Some shape, jmp_infos -> Some (shape, jmp_infos)
47+
match Odoc_model.Compat.shape_of_cmt_infos cmt_info with
48+
| Some shape -> begin
49+
let uid_to_loc = cmt_info.cmt_uid_to_loc in
50+
match source_id_opt, cmt_info.cmt_annots with
51+
| Some source_id, Implementation impl ->
52+
let (map, source_infos) = Implementation.of_cmt source_id id impl uid_to_loc in
53+
(Some shape, map, Some { Odoc_model.Lang.Source_info.id=source_id; infos = source_infos})
54+
| _, _ ->
55+
(Some shape, Odoc_model.Compat.empty_map, None)
56+
end
57+
| None -> (None, Odoc_model.Compat.empty_map, None)
5258

5359
let read_cmt_infos source_id_opt id ~filename () =
5460
match Cmt_format.read_cmt filename with
@@ -59,7 +65,7 @@ let read_cmt_infos source_id_opt id ~filename () =
5965
| _ -> raise Not_an_implementation)
6066

6167
let make_compilation_unit ~make_root ~imports ~interface ?sourcefile ~name ~id
62-
?canonical content =
68+
?canonical ?shape ~uid_to_id ~source_info content =
6369
let open Odoc_model.Lang.Compilation_unit in
6470
let interface, digest =
6571
match interface with
@@ -95,16 +101,18 @@ let make_compilation_unit ~make_root ~imports ~interface ?sourcefile ~name ~id
95101
expansion = None;
96102
linked = false;
97103
canonical;
98-
source_info = None;
104+
source_info;
105+
shape;
106+
uid_to_id;
99107
}
100108

101109
let compilation_unit_of_sig ~make_root ~imports ~interface ?sourcefile ~name ~id
102-
?canonical sg =
110+
?canonical ?shape ~uid_to_id sg =
103111
let content = Odoc_model.Lang.Compilation_unit.Module sg in
104112
make_compilation_unit ~make_root ~imports ~interface ?sourcefile ~name ~id
105-
?canonical content
113+
?canonical ?shape ~uid_to_id content
106114

107-
let read_cmti ~make_root ~parent ~filename () =
115+
let read_cmti ~make_root ~parent ~filename ~cmt_filename_opt ~source_id_opt () =
108116
let cmt_info = Cmt_format.read_cmt filename in
109117
match cmt_info.cmt_annots with
110118
| Interface intf -> (
@@ -118,8 +126,15 @@ let read_cmti ~make_root ~parent ~filename () =
118126
cmt_info.cmt_builddir )
119127
in
120128
let id, sg, canonical = Cmti.read_interface parent name intf in
129+
let (shape, uid_to_id, source_info) =
130+
match cmt_filename_opt with
131+
| Some cmt_filename ->
132+
read_cmt_infos source_id_opt id ~filename:cmt_filename ()
133+
| None ->
134+
(None, Odoc_model.Compat.empty_map, None)
135+
in
121136
compilation_unit_of_sig ~make_root ~imports:cmt_info.cmt_imports
122-
~interface ~sourcefile ~name ~id ?canonical sg)
137+
~interface ~sourcefile ~name ~id ?shape ~uid_to_id ~source_info ?canonical sg)
123138
| _ -> raise Not_an_interface
124139

125140
let read_cmt ~make_root ~parent ~filename ~source_id_opt () =
@@ -161,14 +176,14 @@ let read_cmt ~make_root ~parent ~filename ~source_id_opt () =
161176
items
162177
in
163178
let content = Odoc_model.Lang.Compilation_unit.Pack items in
164-
( make_compilation_unit ~make_root ~imports ~interface ~sourcefile
165-
~name ~id content,
166-
None )
179+
make_compilation_unit ~make_root ~imports ~interface ~sourcefile
180+
~name ~id ~uid_to_id:Odoc_model.Compat.empty_map ~source_info:None content
167181
| Implementation impl ->
168182
let id, sg, canonical = Cmt.read_implementation parent name impl in
169-
( compilation_unit_of_sig ~make_root ~imports ~interface ~sourcefile
170-
~name ~id ?canonical sg,
171-
read_cmt_infos' source_id_opt id cmt_info )
183+
let (shape, uid_to_id, source_info) =
184+
read_cmt_infos source_id_opt id ~filename () in
185+
compilation_unit_of_sig ~make_root ~imports ~interface ~sourcefile
186+
~name ~id ?canonical ?shape ~uid_to_id ~source_info sg
172187
| _ -> raise Not_an_implementation)
173188

174189
let read_cmi ~make_root ~parent ~filename () =
@@ -179,7 +194,7 @@ let read_cmi ~make_root ~parent ~filename () =
179194
Cmi.read_interface parent name
180195
(Odoc_model.Compat.signature cmi_info.cmi_sign)
181196
in
182-
compilation_unit_of_sig ~make_root ~imports ~interface ~name ~id sg
197+
compilation_unit_of_sig ~make_root ~imports ~interface ~name ~id ~source_info:None ~uid_to_id:Odoc_model.Compat.empty_map sg
183198
| _ -> raise Corrupted
184199

185200
(** Catch errors from reading the object files and some internal errors *)
@@ -195,11 +210,8 @@ let wrap_errors ~filename f =
195210
| Not_an_interface -> not_an_interface filename
196211
| Make_root_error m -> error_msg filename m)
197212

198-
let read_cmt_infos source_id_opt id ~filename =
199-
wrap_errors ~filename (read_cmt_infos source_id_opt id ~filename)
200-
201-
let read_cmti ~make_root ~parent ~filename =
202-
wrap_errors ~filename (read_cmti ~make_root ~parent ~filename)
213+
let read_cmti ~make_root ~parent ~filename ~source_id_opt ~cmt_filename_opt =
214+
wrap_errors ~filename (read_cmti ~make_root ~parent ~filename ~source_id_opt ~cmt_filename_opt)
203215

204216
let read_cmt ~make_root ~parent ~filename ~source_id_opt =
205217
wrap_errors ~filename (read_cmt ~make_root ~parent ~filename ~source_id_opt)

src/loader/odoc_loader.mli

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,6 @@ open Result
22
open Odoc_model
33
open Odoc_model.Paths
44

5-
module Lookup_def = Lookup_def
6-
75
type make_root =
86
module_name:string ->
97
digest:Digest.t ->
@@ -15,30 +13,22 @@ val read_string :
1513
string ->
1614
(Comment.docs_or_stop, Error.t) result Error.with_warnings
1715

18-
val read_cmt_infos :
19-
Identifier.SourcePage.t option ->
20-
Identifier.RootModule.t ->
21-
filename:string ->
22-
((Lookup_def.t * Lang.Source_info.infos) option, Error.t) result
23-
Error.with_warnings
24-
(** Read the shape from a .cmt file. *)
25-
2616
val read_cmti :
2717
make_root:make_root ->
2818
parent:Identifier.ContainerPage.t option ->
2919
filename:string ->
20+
source_id_opt:Identifier.SourcePage.t option ->
21+
cmt_filename_opt:string option ->
3022
(Lang.Compilation_unit.t, Error.t) result Error.with_warnings
3123

3224
val read_cmt :
3325
make_root:make_root ->
3426
parent:Identifier.ContainerPage.t option ->
3527
filename:string ->
3628
source_id_opt:Identifier.SourcePage.t option ->
37-
( Lang.Compilation_unit.t * (Lookup_def.t * Lang.Source_info.infos) option,
38-
Error.t )
29+
( Lang.Compilation_unit.t, Error.t )
3930
result
4031
Error.with_warnings
41-
(** The shape is not returned in case of a pack. *)
4232

4333
val read_cmi :
4434
make_root:make_root ->

src/model/compat.cppo.ml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,27 @@ and modtype_declaration : Types.modtype_declaration -> modtype_declaration = fun
223223

224224

225225
#endif
226+
227+
(* Shapes were introduced in OCaml 4.14.0. They're used for resolving to source-code
228+
locations *)
229+
#if OCAML_VERSION >= (4,14,0)
230+
231+
type shape = Shape.t
232+
233+
type 'a shape_uid_map = 'a Shape.Uid.Map.t
234+
235+
let empty_map = Shape.Uid.Map.empty
236+
237+
let shape_of_cmt_infos : Cmt_format.cmt_infos -> shape option = fun x -> x.cmt_impl_shape
238+
239+
#else
240+
241+
type shape = unit
242+
243+
type 'a shape_uid_map = unit
244+
245+
let empty_map = ()
246+
247+
let shape_of_cmt_infos : Cmt_format.cmt_infos -> shape option = fun _ -> None
248+
249+
#endif

src/model/lang.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,8 @@ module rec Compilation_unit : sig
486486
linked : bool; (** Whether this unit has been linked. *)
487487
canonical : Path.Module.t option;
488488
source_info : Source_info.t option;
489+
shape : Compat.shape option;
490+
uid_to_id : Paths.Identifier.SourceLocation.t Compat.shape_uid_map;
489491
}
490492
end =
491493
Compilation_unit

src/odoc/bin/main.ml

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -168,18 +168,13 @@ end = struct
168168

169169
let compile hidden directories resolve_fwd_refs dst package_opt
170170
parent_name_opt open_modules children input warnings_options
171-
source_parent_file source_name source_cmt =
171+
source_parent_file source_name cmt_filename_opt =
172172
let open Or_error in
173173
let resolver =
174174
Resolver.create ~important_digests:(not resolve_fwd_refs) ~directories
175175
~open_modules
176176
in
177-
let input = Fs.File.of_string input
178-
and source_cmt =
179-
match source_cmt with
180-
| None -> None
181-
| Some cmt -> Some (Fs.File.of_string cmt)
182-
in
177+
let input = Fs.File.of_string input in
183178
let output = output_file ~dst ~input in
184179
let parent_cli_spec =
185180
match (parent_name_opt, package_opt) with
@@ -193,39 +188,26 @@ end = struct
193188
in
194189
let source =
195190
match
196-
(source_parent_file, source_name, source_cmt, Fs.File.get_ext input)
191+
(source_parent_file, source_name)
197192
with
198-
| Some parent, Some name, None, ".cmt" -> Ok (Some (parent, name, input))
199-
| Some parent, Some name, Some cmt, ".cmt" ->
200-
if Fpath.equal cmt input then Ok (Some (parent, name, input))
201-
else
202-
Error
203-
(`Cli_error
204-
"--cmt has to be equal to the input file when this one has \
205-
.cmt extension.")
206-
| Some parent, Some name, Some cmt, _ -> Ok (Some (parent, name, cmt))
207-
| Some _, Some _, None, _ ->
208-
Error
209-
(`Cli_error
210-
"--cmt has to be passed when --source-parent-file and \
211-
--source-name are passed and the input file is not a cmt file.")
212-
| Some _, None, _, _ | None, Some _, _, _ ->
193+
| Some parent, Some name -> Ok (Some (parent, name))
194+
| Some _, None | None, Some _ ->
213195
Error
214196
(`Cli_error
215197
"--source-parent-file and --source-name must be passed at the \
216198
same time.")
217-
| None, None, Some _, _ ->
218-
Error
219-
(`Cli_error
220-
"--cmt should only be passed when --source-parent-file and \
221-
--source-name are passed.")
222-
| None, None, _, _ -> Ok None
199+
| None, None -> Ok None
223200
in
201+
begin
202+
if Fs.File.get_ext input = ".cmt" && cmt_filename_opt <> None then
203+
Error (`Cli_error "--cmt is redundant if the input is a cmt file")
204+
else Ok ()
205+
end >>= fun () ->
224206
parent_cli_spec >>= fun parent_cli_spec ->
225207
source >>= fun source ->
226208
Fs.Directory.mkdir_p (Fs.File.dirname output);
227209
Compile.compile ~resolver ~parent_cli_spec ~hidden ~children ~output
228-
~warnings_options ~source input
210+
~warnings_options ~source ~cmt_filename_opt input
229211

230212
let input =
231213
let doc = "Input $(i,.cmti), $(i,.cmt), $(i,.cmi) or $(i,.mld) file." in

0 commit comments

Comments
 (0)