Source file cms_format.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
(** cms and cmsi files format. *)
module Uid = Shape.Uid
let read_magic_number ic =
let len_magic_number = String.length Config.cms_magic_number in
really_input_string ic len_magic_number
type cms_infos = {
cms_modname : Compilation_unit.t;
cms_comments : (string * Location.t) list;
cms_sourcefile : string option;
cms_builddir : string;
cms_source_digest : Digest.t option;
cms_initial_env : Env.t option;
cms_uid_to_loc : string Location.loc Shape.Uid.Tbl.t;
cms_uid_to_attributes : Parsetree.attributes Shape.Uid.Tbl.t;
cms_shape_format : Clflags.shape_format;
cms_impl_shape : Shape.t option;
cms_ident_occurrences :
(Longident.t Location.loc * Shape_reduce.result) array;
cms_declaration_dependencies :
(Cmt_format.dependency_kind * Uid.t * Uid.t) list;
cms_externals: Vicuna_value_shapes.extfun array;
}
type error =
Not_a_shape of string
exception Error of error
let input_cms ic = (input_value ic : cms_infos)
let output_cms oc cms =
output_string oc Config.cms_magic_number;
output_value oc (cms : cms_infos)
let read filename =
let ic = open_in_bin filename in
Misc.try_finally
~always:(fun () -> close_in ic)
(fun () ->
let magic_number = read_magic_number ic in
if magic_number = Config.cms_magic_number then
input_cms ic
else
raise (Error (Not_a_shape filename))
)
let toplevel_attributes = ref []
let register_toplevel_attributes uid ~attributes ~loc =
let loc : _ Location.loc = { txt = ""; loc } in
toplevel_attributes := (uid, loc, attributes) :: !toplevel_attributes
let uid_tables_of_binary_annots binary_annots =
let cms_uid_to_loc = Types.Uid.Tbl.create 42 in
let cms_uid_to_attributes = Types.Uid.Tbl.create 42 in
List.iter (fun (uid, loc, attrs) ->
Types.Uid.Tbl.add cms_uid_to_loc uid loc;
Types.Uid.Tbl.add cms_uid_to_attributes uid attrs)
!toplevel_attributes;
Cmt_format.iter_declarations binary_annots
~f:(fun uid decl ->
let loc = Typedtree.loc_of_decl ~uid decl in
let attrs =
match decl with
| Value v -> v.val_attributes
| Value_binding v -> v.vb_attributes
| Type v -> v.typ_attributes
| Constructor v -> v.cd_attributes
| Extension_constructor v -> v.ext_attributes
| Label v -> v.ld_attributes
| Module v -> v.md_attributes
| Module_substitution v -> v.ms_attributes
| Module_binding v -> v.mb_attributes
| Module_type v -> v.mtd_attributes
| Class v -> v.ci_attributes
| Class_type v -> v.ci_attributes
| Jkind v -> v.jkind_attributes
in
Types.Uid.Tbl.add cms_uid_to_loc uid loc;
Types.Uid.Tbl.add cms_uid_to_attributes uid attrs
);
cms_uid_to_loc, cms_uid_to_attributes
let externals_of_binary_annots binary_annots =
match binary_annots with
| Cmt_format.Implementation str ->
Vicuna_traverse_typed_tree.extract_from_typed_tree str |> Array.of_list
| _ -> [| |]
let save_cms target modname binary_annots initial_env shape
cms_declaration_dependencies =
if (!Clflags.binary_annotations_cms && not !Clflags.print_types) then begin
Misc.output_to_file_via_temporary
~mode:[Open_binary] (Unit_info.Artifact.filename target)
(fun _temp_file_name oc ->
let sourcefile = Unit_info.Artifact.raw_source_file target in
let source_digest = Option.map Digest.file sourcefile in
let cms_ident_occurrences, cms_initial_env =
if !Clflags.store_occurrences then
let cms_ident_occurrences = Cmt_format.index_occurrences binary_annots in
let cms_initial_env = if Cmt_format.need_to_clear_env
then Env.keep_only_summary initial_env else initial_env in
cms_ident_occurrences, Some cms_initial_env
else
[| |], None
in
let cms_uid_to_loc, cms_uid_to_attributes =
uid_tables_of_binary_annots binary_annots
in
let cms_externals = externals_of_binary_annots binary_annots in
let cms = {
cms_modname = modname;
cms_comments = [];
cms_sourcefile = sourcefile;
cms_builddir = Location.rewrite_absolute_path (Sys.getcwd ());
cms_source_digest = source_digest;
cms_initial_env;
cms_uid_to_loc;
cms_uid_to_attributes;
cms_shape_format = !Clflags.shape_format;
cms_impl_shape = shape;
cms_ident_occurrences;
cms_declaration_dependencies;
cms_externals;
} in
output_cms oc cms)
end
let clear () = ()
let shape_format_to_string =
function
| Clflags.Old_merlin -> "old-merlin"
| Clflags.Debugging_shapes -> "debugging-shapes"