Skip to content

Commit 43cb046

Browse files
committed
T7915: add compiler alerts and annotations
1 parent 0ac562e commit 43cb046

20 files changed

+1039
-112
lines changed

src/config_diff.ml

Lines changed: 118 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -154,26 +154,40 @@ let rec diff (path : string list) (f : 'a diff_func) (res: 'a result) ((left_nod
154154

155155
(* copy node paths between trees *)
156156
let rec clone_path ?(recurse=true) ?(set_values=None) old_root new_root path_done path_remaining =
157+
(* raises:
158+
[Vytree.Nonexistent_path]
159+
alert exn Vytree.get:
160+
[Vytree.Empty_path] not possible as clone_path called by clone with non-empty path
161+
[Vytree.Nonexistent_path] allow raise
162+
alert exn Vytree.insert:
163+
[Vytree.Empty_path] not possible as clone_path called by clone with non-empty path
164+
[Not_found] not possible for postion=Lexical
165+
[Vytree.Duplicate_child] not possible as calls are on path complement
166+
[Vytree.Insert_error] not possible as calls are on path_existing @ [name]
167+
*)
157168
match path_remaining with
158169
| [] | [_] ->
159170
let path_total = path_done @ path_remaining in
160-
let old_node = Vytree.get old_root path_total in
171+
let old_node = (Vytree.get[@alert "-exn"]) old_root path_total in
161172
let data =
162173
match set_values with
163174
| Some v -> { (data_of old_node) with Config_tree.values = v }
164175
| None -> data_of old_node
165176
in
166177
if recurse then
167-
Vytree.insert ~position:Lexical ~children:(children_of old_node) new_root path_total data
178+
(Vytree.insert[@alert "-exn"]) ~position:Lexical ~children:(children_of old_node) new_root path_total data
168179
else
169-
Vytree.insert ~position:Lexical new_root path_total data
180+
(Vytree.insert[@alert "-exn"]) ~position:Lexical new_root path_total data
170181
| name :: names ->
171182
let path_done = path_done @ [name] in
172-
let old_node = Vytree.get old_root path_done in
173-
let new_root = Vytree.insert ~position:Lexical new_root path_done (data_of old_node) in
183+
let old_node = (Vytree.get[@alert "-exn"]) old_root path_done in
184+
let new_root = (Vytree.insert[@alert "-exn"]) ~position:Lexical new_root path_done (data_of old_node) in
174185
clone_path ~recurse:recurse ~set_values:set_values old_root new_root path_done names
175186

176187
let clone ?(recurse=true) ?(set_values=None) old_root new_root path =
188+
(* raises:
189+
[Vytree.Nonexistent_path] from clone_path
190+
*)
177191
match path with
178192
| [] -> if recurse then old_root else new_root
179193
| _ ->
@@ -183,6 +197,12 @@ let clone ?(recurse=true) ?(set_values=None) old_root new_root path =
183197

184198
(* define the diff_func *)
185199
let decorate_trees ?(recurse=true) (path : string list) (Diff_tree res) (m : change) =
200+
(* raises no exception:
201+
clone will always be called on extant path of left or right
202+
alert exn Vytree.get_values:
203+
[Vytree.Empty_path] not possible as pattern Updated implies non-empty path
204+
[Vytree.Nonexistent_path] not possible as pattern Updated implies path exists
205+
*)
186206
match m with
187207
| Added -> Diff_tree {res with add = clone res.right res.add path; }
188208
| Subtracted ->
@@ -192,7 +212,7 @@ let decorate_trees ?(recurse=true) (path : string list) (Diff_tree res) (m : cha
192212
Diff_tree {res with inter = clone ~recurse:recurse res.left res.inter path; }
193213
| Updated v ->
194214
(* if in this case, node at path is guaranteed to exist *)
195-
let ov = Config_tree.get_values res.left path in
215+
let ov = (Config_tree.get_values[@alert "-exn"]) res.left path in
196216
match ov, v with
197217
| [_], [_] -> Diff_tree {res with sub = clone res.left res.sub path;
198218
del = clone res.left res.del path;
@@ -236,13 +256,24 @@ let decorate_trees ?(recurse=true) (path : string list) (Diff_tree res) (m : cha
236256

237257
(* get sub trees for path-relative comparison *)
238258
let tree_at_path path node =
259+
(* raises:
260+
[Vytree.Empty_path]
261+
[Empty_comparison]
262+
alert exn Vytree.get:
263+
[Vytree.Empty_path] allow raise
264+
[Vytree.Nonexistent_path] catch and raise Empty_comparison
265+
*)
239266
try
240-
let node = Vytree.get node path in
267+
let node = (Vytree.get[@alert "-exn"]) node path in
241268
make Config_tree.default_data "" [node]
242269
with Vytree.Nonexistent_path -> raise Empty_comparison
243270

244271
(* call recursive diff on config_trees with decorate_trees as the diff_func *)
245272
let compare path left right =
273+
(* raises:
274+
[Empty_comparison] from tree_at_path
275+
[Incommensurable]
276+
*)
246277
if (name_of left) <> (name_of right) then
247278
raise Incommensurable
248279
else
@@ -254,6 +285,10 @@ let compare path left right =
254285

255286
(* wrapper to return diff trees *)
256287
let diff_tree path left right =
288+
(* raises:
289+
[Incommensurable],
290+
[Empty_comparison] from compare
291+
*)
257292
let trees = compare path left right in
258293
let add_node = make Config_tree.default_data "add" (children_of (trees.add)) in
259294
let sub_node = make Config_tree.default_data "sub" (children_of (trees.sub)) in
@@ -266,20 +301,36 @@ let diff_tree path left right =
266301
we need a hybrid tree between the 'del' tree and the 'sub' tree, namely:
267302
in case the del tree has a terminal tag node (== all tag values have
268303
been removed) add tag node values for proper removal in commit execution
269-
*)
304+
*)
270305

271306
let get_tagged_delete_tree dt =
272-
let del_tree = Config_tree.get_subtree dt ["del"] in
273-
let sub_tree = Config_tree.get_subtree dt ["sub"] in
307+
(* alert exn Config_tree.get_subtree:
308+
[Vytree.Empty_path] not possible as non-empty path given
309+
alert exn Config_tree.is_tag:
310+
[Vytree.Empty_path] not possible in pattern non-empty path
311+
[Vytree.Nonexistent_path] not possible in fold_tree_with_path
312+
alert exn Vytree.is_terminal_path:
313+
[Vytree.Empty_path] not possible in pattern non-empty path
314+
alert exn Vytree.children_of_path:
315+
[Vytree.Empty_path] not possible in pattern non-empty path
316+
[Vytree.Nonexistent_path] not possible in super-tree of fold_tree_with_path arg
317+
alert exn Vytree.insert:
318+
[Vytree.Empty_path]: not possible since called on pattern path non-empty
319+
[Not_found]: not possible for postion=Lexical
320+
[Vytree.Duplicate_child]: not possible by condition is_terminal_path
321+
[Vytree.Insert_error]: not possible since constructed iteratively from existing path
322+
*)
323+
let del_tree = (Config_tree.get_subtree[@alert "-exn"]) dt ["del"] in
324+
let sub_tree = (Config_tree.get_subtree[@alert "-exn"]) dt ["sub"] in
274325
let f (p, a) _t =
275326
let q = List.rev p in
276327
match q with
277328
| [] -> (p, a)
278329
| _ ->
279-
if Config_tree.is_tag a q && Vytree.is_terminal_path a q then
280-
let children = Vytree.children_of_path sub_tree q in
330+
if (Config_tree.is_tag[@alert "-exn"]) a q && (Vytree.is_terminal_path[@alert "-exn"]) a q then
331+
let children = (Vytree.children_of_path[@alert "-exn"]) sub_tree q in
281332
let insert_child path node name =
282-
Vytree.insert ~position:Lexical node (path @ [name]) Config_tree.default_data
333+
(Vytree.insert[@alert "-exn"]) ~position:Lexical node (path @ [name]) Config_tree.default_data
283334
in
284335
let a' = List.fold_left (insert_child q) a children in
285336
(p, a')
@@ -307,14 +358,20 @@ let marked_render mark node =
307358
String.concat "\n" m
308359

309360
let added_lines ?(cmds=false) node path =
361+
(* alert exn Config_tree.render_commands:
362+
[Vytree.Nonexistent_path] not possible on root path
363+
*)
310364
if not cmds then marked_render "+ " (tree_at_path path node)
311365
else
312-
(Config_tree.render_commands ~op:Set node []) ^ "\n"
366+
((Config_tree.render_commands[@alert "-exn"]) ~op:Set node []) ^ "\n"
313367

314368
let removed_lines ?(cmds=false) node path =
369+
(* alert exn Config_tree.render_commands:
370+
[Vytree.Nonexistent_path] not possible on root path
371+
*)
315372
if not cmds then marked_render "- " (tree_at_path path node)
316373
else
317-
(Config_tree.render_commands ~op:Delete node []) ^ "\n"
374+
((Config_tree.render_commands[@alert "-exn"]) ~op:Delete node []) ^ "\n"
318375

319376
let order_commands (strl: string) =
320377
let l = String.split_on_char '\n' strl in
@@ -323,6 +380,12 @@ let order_commands (strl: string) =
323380
(String.concat "\n" del) ^ "\n" ^ (String.concat "\n" set) ^ "\n"
324381

325382
let unified_diff ?(cmds=false) ?recurse:_ (path : string list) (Diff_string res) (m : change) =
383+
(* raises no exception:
384+
clone will always be called on extant path of left or right
385+
alert exn Vytree.get_values:
386+
[Vytree.Empty_path] not possible as pattern Updated implies non-empty path
387+
[Vytree.Nonexistent_path] not possible as pattern Updated implies path exists
388+
*)
326389
let ppath_l = list_but_last path
327390
in
328391
let ppath_s =
@@ -348,7 +411,7 @@ let unified_diff ?(cmds=false) ?recurse:_ (path : string list) (Diff_string res)
348411
Diff_string { res with ppath = ppath_l; udiff = str_diff; }
349412
| Unchanged -> Diff_string (res)
350413
| Updated v ->
351-
let ov = Config_tree.get_values res.left path in
414+
let ov = (Config_tree.get_values[@alert "-exn"]) res.left path in
352415
match ov, v with
353416
| [_], [_] ->
354417
let str_diff =
@@ -405,6 +468,10 @@ let compare_at_path_maybe_empty left right path =
405468
in (left, right)
406469

407470
let show_diff ?(cmds=false) path left right =
471+
(* raises:
472+
[Incommensurable],
473+
[Empty_comparison] from compare_at_path_maybe_empty
474+
*)
408475
if (name_of left) <> (name_of right) then
409476
raise Incommensurable
410477
else
@@ -425,19 +492,34 @@ let show_diff ?(cmds=false) path left right =
425492

426493
(* mask function; mask applied on right *)
427494
let mask_func ?recurse:_ (path : string list) (Diff_tree res) (m : change) =
495+
(* alert exn Vytree.delete:
496+
[Vytree.Empty_path] not possible since Unchanged pattern is only empty path
497+
[Vytree.Nonexistent_path] not possible as called on existing config paths (res.left)
498+
alert exn Vytree.is_terminal_path:
499+
[Vytree.Empty_path] not possible since Unchanged pattern is only empty path
500+
*)
428501
match m with
429502
| Added -> Diff_tree (res)
430503
| Subtracted ->
431504
(match path with
432-
| [_] -> Diff_tree {res with left = Vytree.delete res.left path}
433-
| _ -> if not (Vytree.is_terminal_path res.right (list_but_last path)) then
434-
Diff_tree {res with left = Vytree.delete res.left path}
435-
else Diff_tree (res))
505+
| [_] ->
506+
Diff_tree {res with left = (Vytree.delete[@alert "-exn"]) res.left path}
507+
| _ ->
508+
if not ((Vytree.is_terminal_path[@alert "-exn"]) res.right (list_but_last path)) then
509+
Diff_tree {res with left = (Vytree.delete[@alert "-exn"]) res.left path}
510+
else Diff_tree (res))
436511
| Unchanged -> Diff_tree (res)
437512
| Updated _ -> Diff_tree (res)
438513

439514
(* call recursive diff with mask_func; mask applied on right *)
440515
let mask_tree left right =
516+
(* raises:
517+
[Empty_comparison] from diff
518+
[Incommensurable]
519+
*)
520+
if (name_of left) <> (name_of right) then
521+
raise Incommensurable
522+
else
441523
let trees = make_diff_trees left right in
442524
let d = diff [] mask_func trees (Option.some left, Option.some right)
443525
in
@@ -450,19 +532,33 @@ let union_of_values (n : Config_tree.t) (m : Config_tree.t) =
450532
ValueS.elements (ValueS.union set_n set_m)
451533

452534
let tree_union s t =
535+
(* raises:
536+
[Tree_alg.Incompatible_union]
537+
[Tree_alg.Nonexistent_child] should not be reachable
538+
alert exn Tree_alg.ConfigAlg.tree_union:
539+
[Tree_alg.Incompatible_union] allow raise
540+
[Tree_alg.Nonexistent_child] allow raise; should not be reachable
541+
*)
453542
let f u v =
454543
let values = union_of_values u v in
455544
let data = {(data_of v) with Config_tree.values = values} in
456545
Vytree.make_full data (name_of v) (children_of v)
457546
in
458-
Tree_alg.ConfigAlg.tree_union s t f
547+
(Tree_alg.ConfigAlg.tree_union[@alert "-exn"]) s t f
459548

460549
let tree_merge ?(destructive=false) s t =
550+
(* raises:
551+
[Tree_alg.Incompatible_union]
552+
[Tree_alg.Nonexistent_child] should not be reachable
553+
alert exn Tree_alg.ConfigAlg.tree_union:
554+
[Tree_alg.Incompatible_union] allow raise
555+
[Tree_alg.Nonexistent_child] allow raise; should not be reachable
556+
*)
461557
let f u v =
462558
let data =
463559
match destructive with
464560
| false -> data_of u
465561
| true -> data_of v
466562
in Vytree.make_full data (name_of v) (children_of v)
467563
in
468-
Tree_alg.ConfigAlg.tree_union s t f
564+
(Tree_alg.ConfigAlg.tree_union[@alert "-exn"]) s t f

src/config_diff.mli

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,28 @@ exception Empty_comparison
4242
exception Nonexistent_child
4343

4444
val clone : ?recurse:bool -> ?set_values:string list option -> Config_tree.t -> Config_tree.t ->string list -> Config_tree.t
45+
[@@alert exn "Vytree.Nonexistent_path"]
46+
4547
val diff_tree : string list -> Config_tree.t -> Config_tree.t -> Config_tree.t
48+
[@@alert exn "Config_diff.Incommensurable"]
49+
[@@alert exn "Config_diff.Empty_comparison"]
50+
4651
val show_diff : ?cmds:bool -> string list -> Config_tree.t -> Config_tree.t -> string
52+
[@@alert exn "Config_diff.Incommensurable"]
53+
[@@alert exn "Config_diff.Empty_comparison"]
54+
4755
val tree_union : Config_tree.t -> Config_tree.t -> Config_tree.t
56+
[@@alert exn "Tree_alg.Incompatible_union"]
57+
[@@alert exn "Tree_alg.Nonexistent_child"]
58+
4859
val tree_merge : ?destructive:bool -> Config_tree.t -> Config_tree.t -> Config_tree.t
60+
[@@alert exn "Tree_alg.Incompatible_union"]
61+
[@@alert exn "Tree_alg.Nonexistent_child"]
62+
4963
val mask_tree : Config_tree.t -> Config_tree.t -> Config_tree.t
64+
[@@alert exn "Config_diff.Incommensurable"]
65+
[@@alert exn "Config_diff.Empty_comparison"]
66+
5067
val make_diff_cstore : Config_tree.t -> Config_tree.t -> int -> Diff_cstore.t result
68+
5169
val get_tagged_delete_tree : Config_tree.t -> Config_tree.t

src/config_file.ml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ let strip_version s =
2727
| [] -> Error "Failure stripping version string from config"
2828

2929
let load_config file =
30+
(* alert exn Parser.from_string:
31+
[Util.Syntax_error] caught
32+
*)
3033
try
3134
let chan = open_in file in
3235
let s = really_input_string chan (in_channel_length chan) in
@@ -36,7 +39,7 @@ let load_config file =
3639
| Ok t -> escape_backslash t
3740
| Error msg -> raise (Sys_error msg)
3841
in
39-
let config = Parser.from_string s in
42+
let config = (Parser.from_string[@alert "-exn"]) s in
4043
Ok config
4144
with
4245
| Sys_error msg -> Error msg

0 commit comments

Comments
 (0)