Skip to content

Commit 75efadc

Browse files
committed
Merge changes from ocaml/ocaml#13308
[tooling] Remember linked declarations
1 parent 395af5f commit 75efadc

File tree

14 files changed

+353
-147
lines changed

14 files changed

+353
-147
lines changed

Changes

+5
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,11 @@ OCaml 5.2.0
665665
provenance: either an implementation or an interface.
666666
(Ulysse Gérard, review by Florian Angeletti and Leo White)
667667

668+
- #13308: keep track of relations between declaration in the cmt files. This is
669+
useful information for external tools for navigation and analysis purposis.
670+
(Ulysse Gérard, Florian Angeletti, review by Florian Angeletti and Gabriel
671+
Scherer)
672+
668673
### Build system:
669674

670675
- #12198, #12321, #12586, #12616, #12706, #13048: continue the merge of the

driver/compile_common.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ let typecheck_intf info ast =
8585
Format.(fprintf std_formatter) "%a@."
8686
(Printtyp.printed_signature (Unit_info.source_file info.target))
8787
sg);
88-
ignore (Includemod.signatures info.env ~mark:Mark_both
88+
ignore (Includemod.signatures info.env ~mark:true
8989
~modes:(Legacy None) sg sg);
9090
Typecore.force_delayed_checks ();
9191
Builtin_attributes.warn_unused ();

file_formats/cmt_format.ml

+8-8
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ and binary_part =
4545
| Partial_signature_item of signature_item
4646
| Partial_module_type of module_type
4747

48+
type dependency_kind = Definition_to_declaration | Declaration_to_declaration
4849
type cmt_infos = {
4950
cmt_modname : Compilation_unit.t;
5051
cmt_annots : binary_annots;
51-
cmt_value_dependencies :
52-
(Types.value_description * Types.value_description) list;
52+
cmt_declaration_dependencies : (dependency_kind * Uid.t * Uid.t) list;
5353
cmt_comments : (string * Location.t) list;
5454
cmt_args : string array;
5555
cmt_sourcefile : string option;
@@ -452,19 +452,19 @@ let read_cmi filename =
452452
| Some cmi, _ -> cmi
453453

454454
let saved_types = ref []
455-
let value_deps = ref []
455+
let uids_deps : (dependency_kind * Uid.t * Uid.t) list ref = ref []
456456

457457
let clear () =
458458
saved_types := [];
459-
value_deps := []
459+
uids_deps := []
460460

461461
let add_saved_type b = saved_types := b :: !saved_types
462462
let get_saved_types () = !saved_types
463463
let set_saved_types l = saved_types := l
464464

465-
let record_value_dependency vd1 vd2 =
466-
if vd1.Types.val_loc <> vd2.Types.val_loc then
467-
value_deps := (vd1, vd2) :: !value_deps
465+
let record_declaration_dependency (rk, uid1, uid2) =
466+
if not (Uid.equal uid1 uid2) then
467+
uids_deps := (rk, uid1, uid2) :: !uids_deps
468468

469469
let save_cmt target cu binary_annots initial_env cmi shape =
470470
if !Clflags.binary_annotations && not !Clflags.print_types then begin
@@ -499,7 +499,7 @@ let save_cmt target cu binary_annots initial_env cmi shape =
499499
let cmt = {
500500
cmt_modname = cu;
501501
cmt_annots;
502-
cmt_value_dependencies = !value_deps;
502+
cmt_declaration_dependencies = !uids_deps;
503503
cmt_comments = Lexer.comments ();
504504
cmt_args = Sys.argv;
505505
cmt_sourcefile = sourcefile;

file_formats/cmt_format.mli

+3-4
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@ and binary_part =
4848
| Partial_signature_item of signature_item
4949
| Partial_module_type of module_type
5050

51+
type dependency_kind = Definition_to_declaration | Declaration_to_declaration
5152
type cmt_infos = {
5253
cmt_modname : Compilation_unit.t;
5354
cmt_annots : binary_annots;
54-
cmt_value_dependencies :
55-
(Types.value_description * Types.value_description) list;
55+
cmt_declaration_dependencies : (dependency_kind * Uid.t * Uid.t) list;
5656
cmt_comments : (string * Location.t) list;
5757
cmt_args : string array;
5858
cmt_sourcefile : string option;
@@ -108,8 +108,7 @@ val add_saved_type : binary_part -> unit
108108
val get_saved_types : unit -> binary_part list
109109
val set_saved_types : binary_part list -> unit
110110

111-
val record_value_dependency:
112-
Types.value_description -> Types.value_description -> unit
111+
val record_declaration_dependency: dependency_kind * Uid.t * Uid.t -> unit
113112

114113
val index_occurrences :
115114
binary_annots -> (Longident.t Location.loc * Shape_reduce.result) array
+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
(* TEST
2+
3+
flags = "-bin-annot -bin-annot-occurrences";
4+
compile_only = "true";
5+
setup-ocamlc.byte-build-env;
6+
all_modules = "link_intf_impl.mli link_intf_impl.ml";
7+
ocamlc.byte;
8+
check-ocamlc.byte-output;
9+
10+
program = "-quiet -uid-deps link_intf_impl.cmt";
11+
output = "out_objinfo";
12+
ocamlobjinfo;
13+
14+
check-program-output;
15+
*)
16+
17+
let x (* 0 *) = 42
18+
19+
type t (* 1 *) = int
20+
21+
module type S (* 3 *) = sig
22+
val y (* 2 *) : t
23+
end
24+
25+
module M (* 5 *) : S = struct
26+
let y (* 4 *) = 36
27+
end
28+
29+
module N (* 8 *) : sig
30+
val y (* 7 *) : int
31+
end = struct
32+
let y (* 6 *) = 2
33+
end
34+
35+
let _ = (module N : S)
36+
37+
module P (* 10 *)= struct
38+
let y (* 9 *) = 12
39+
end
40+
41+
module F (* 12 *) (X (* 11 *) : S) = X
42+
43+
module G (* 13 *) = F(P)
44+
45+
module type Initial (* 16 *) = sig
46+
module type Nested (* 15 *) = sig
47+
type t (* 14 *)
48+
end
49+
end
50+
51+
module MF (* 23 *) : sig
52+
module F (* 22 *) (X (* 21 *) : sig val x (* 20 *) : int end) : sig end
53+
end = struct
54+
module F (* 19 *) (X (* 18 *) : sig val x (* 17 *) : int end) = struct end
55+
end
56+
57+
module FMT (* 27 *) (X (* 26 *) : sig
58+
module type MT (* 25 *) = sig val x (* 24 *) : int end
59+
end) : sig end = struct end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
type t (* 0 *)
2+
3+
val x (* 1 *) : t
4+
5+
module type S (* 3 *) = sig
6+
val y (* 2 *) : t
7+
end
8+
9+
module M (* 4 *) : S
10+
11+
module type Initial (* 7 *) = sig
12+
module type Nested (* 6 *) = sig
13+
type t (* 5 *)
14+
end
15+
end
16+
17+
module FMT (* 11 *) (X (* 10 *) : sig
18+
module type MT (* 9 *) = sig val x (* 8 *) : int end
19+
end) : sig end
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
Uid dependencies:
3+
Link_intf_impl.0 <- [intf]Link_intf_impl.1
4+
Link_intf_impl.1 <- [intf]Link_intf_impl.0
5+
Link_intf_impl.2 <-> [intf]Link_intf_impl.2
6+
Link_intf_impl.3 <- [intf]Link_intf_impl.3
7+
Link_intf_impl.4 <- Link_intf_impl.2
8+
Link_intf_impl.5 <- [intf]Link_intf_impl.4
9+
Link_intf_impl.6 <- Link_intf_impl.7
10+
Link_intf_impl.7 <-> Link_intf_impl.2
11+
Link_intf_impl.9 <-> Link_intf_impl.2
12+
Link_intf_impl.14 <-> [intf]Link_intf_impl.5
13+
Link_intf_impl.15 <-> [intf]Link_intf_impl.6
14+
Link_intf_impl.16 <- [intf]Link_intf_impl.7
15+
Link_intf_impl.17 <-> Link_intf_impl.20
16+
Link_intf_impl.19 <- Link_intf_impl.22
17+
Link_intf_impl.24 <-> [intf]Link_intf_impl.8
18+
Link_intf_impl.25 <-> [intf]Link_intf_impl.9
19+
Link_intf_impl.27 <- [intf]Link_intf_impl.11

tools/objinfo.ml

+24
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ let no_crc = ref false
3939
let shape = ref false
4040
let index = ref false
4141
let decls = ref false
42+
let uid_deps = ref false
4243

4344
module Magic_number = Misc.Magic_number
4445
module String = Misc.Stdlib.String
@@ -213,6 +214,27 @@ let print_cmt_infos cmt =
213214
cmt.cmt_ident_occurrences;
214215
Format.print_flush ()
215216
end;
217+
if !uid_deps then begin
218+
printf "\nUid dependencies:\n";
219+
let arr = Array.of_list cmt.cmt_declaration_dependencies in
220+
let () =
221+
Array.sort (fun (_tr, u1, u2) (_tr', u1', u2') ->
222+
match Shape.Uid.compare u1 u1' with
223+
| 0 -> Shape.Uid.compare u2 u2'
224+
| n -> n) arr
225+
in
226+
Format.printf "@[<v>";
227+
Array.iter (fun (rk, u1, u2) ->
228+
let rk = match rk with
229+
| Definition_to_declaration -> "<-"
230+
| Declaration_to_declaration -> "<->"
231+
in
232+
Format.printf "@[<h>%a %s %a@]@;"
233+
Shape.Uid.print u1
234+
rk
235+
Shape.Uid.print u2) arr;
236+
Format.printf "@]";
237+
end;
216238
if !decls then begin
217239
printf "\nUid of decls:\n";
218240
let decls = Array.of_list (Shape.Uid.Tbl.to_list cmt.cmt_uid_to_decl) in
@@ -571,6 +593,8 @@ let arg_list = [
571593
" Print a list of all usages of values, types, etc. in the module";
572594
"-decls", Arg.Set decls,
573595
" Print a list of all declarations in the module";
596+
"-uid-deps", Arg.Set uid_deps,
597+
" Print the declarations' uids dependencies of the module";
574598
"-null-crc", Arg.Set no_crc, " Print a null CRC for imported interfaces";
575599
"-args", Arg.Expand Arg.read_arg,
576600
"<file> Read additional newline separated command line arguments \n\

toplevel/byte/topeval.ml

+1-2
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,7 @@ let execute_phrase print_outcome ppf phr =
125125
in
126126
if !Clflags.dump_typedtree then Printtyped.implementation ppf str;
127127
let sg' = Typemod.Signature_names.simplify newenv sn sg in
128-
ignore (Includemod.signatures ~mark:Mark_positive oldenv
129-
~modes:(Legacy None) sg sg');
128+
Includemod.check_implementation oldenv ~modes:(Legacy None) sg sg';
130129
Typecore.force_delayed_checks ();
131130
let shape = Shape_reduce.local_reduce Env.empty shape in
132131
if !Clflags.dump_shape then Shape.print ppf shape;

toplevel/native/opttoploop.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ let execute_phrase print_outcome ppf phr =
401401
if !Clflags.dump_typedtree then Printtyped.implementation ppf str;
402402
let sg' = Typemod.Signature_names.simplify newenv names sg in
403403
let coercion =
404-
Includemod.signatures oldenv ~mark:Mark_positive
404+
Includemod.signatures oldenv ~mark:true
405405
~modes:(Legacy None) sg sg'
406406
in
407407
Typecore.force_delayed_checks ();

toplevel/native/topeval.ml

+1-1
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ let execute_phrase print_outcome ppf phr =
185185
in
186186
if !Clflags.dump_typedtree then Printtyped.implementation ppf str;
187187
let sg' = Typemod.Signature_names.simplify newenv names sg in
188-
ignore (Includemod.signatures oldenv ~mark:Mark_positive sg sg');
188+
Includemod.check_implementation oldenv ~modes:(Legacy None) sg sg';
189189
Typecore.force_delayed_checks ();
190190
let shape = Shape_reduce.local_reduce Env.empty shape in
191191
if !Clflags.dump_shape then Shape.print ppf shape;

0 commit comments

Comments
 (0)