Skip to content

Commit e079d62

Browse files
committed
T7915: add compiler alerts and annotations
1 parent 2cf367d commit e079d62

20 files changed

+1042
-112
lines changed

src/config_diff.ml

Lines changed: 114 additions & 20 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,34 @@ 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 =
307+
(* alert exn Config_tree.is_tag:
308+
[Vytree.Empty_path] not possible in pattern non-empty path
309+
[Vytree.Nonexistent_path] not possible in fold_tree_with_path
310+
alert exn Vytree.is_terminal_path:
311+
[Vytree.Empty_path] not possible in pattern non-empty path
312+
alert exn Vytree.children_of_path:
313+
[Vytree.Empty_path] not possible in pattern non-empty path
314+
[Vytree.Nonexistent_path] not possible in super-tree of fold_tree_with_path arg
315+
alert exn Vytree.insert:
316+
[Vytree.Empty_path]: not possible since called on pattern path non-empty
317+
[Not_found]: not possible for postion=Lexical
318+
[Vytree.Duplicate_child]: not possible by condition is_terminal_path
319+
[Vytree.Insert_error]: not possible since constructed iteratively from existing path
320+
*)
272321
let del_tree = Config_tree.get_subtree dt ["del"] in
273322
let sub_tree = Config_tree.get_subtree dt ["sub"] in
274323
let f (p, a) _t =
275324
let q = List.rev p in
276325
match q with
277326
| [] -> (p, a)
278327
| _ ->
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
328+
if (Config_tree.is_tag[@alert "-exn"]) a q && (Vytree.is_terminal_path[@alert "-exn"]) a q then
329+
let children = (Vytree.children_of_path[@alert "-exn"]) sub_tree q in
281330
let insert_child path node name =
282-
Vytree.insert ~position:Lexical node (path @ [name]) Config_tree.default_data
331+
(Vytree.insert[@alert "-exn"]) ~position:Lexical node (path @ [name]) Config_tree.default_data
283332
in
284333
let a' = List.fold_left (insert_child q) a children in
285334
(p, a')
@@ -307,14 +356,20 @@ let marked_render mark node =
307356
String.concat "\n" m
308357

309358
let added_lines ?(cmds=false) node path =
359+
(* alert exn Config_tree.render_commands:
360+
[Vytree.Nonexistent_path] not possible on root path
361+
*)
310362
if not cmds then marked_render "+ " (tree_at_path path node)
311363
else
312-
(Config_tree.render_commands ~op:Set node []) ^ "\n"
364+
((Config_tree.render_commands[@alert "-exn"]) ~op:Set node []) ^ "\n"
313365

314366
let removed_lines ?(cmds=false) node path =
367+
(* alert exn Config_tree.render_commands:
368+
[Vytree.Nonexistent_path] not possible on root path
369+
*)
315370
if not cmds then marked_render "- " (tree_at_path path node)
316371
else
317-
(Config_tree.render_commands ~op:Delete node []) ^ "\n"
372+
((Config_tree.render_commands[@alert "-exn"]) ~op:Delete node []) ^ "\n"
318373

319374
let order_commands (strl: string) =
320375
let l = String.split_on_char '\n' strl in
@@ -323,6 +378,12 @@ let order_commands (strl: string) =
323378
(String.concat "\n" del) ^ "\n" ^ (String.concat "\n" set) ^ "\n"
324379

325380
let unified_diff ?(cmds=false) ?recurse:_ (path : string list) (Diff_string res) (m : change) =
381+
(* raises no exception:
382+
clone will always be called on extant path of left or right
383+
alert exn Vytree.get_values:
384+
[Vytree.Empty_path] not possible as pattern Updated implies non-empty path
385+
[Vytree.Nonexistent_path] not possible as pattern Updated implies path exists
386+
*)
326387
let ppath_l = list_but_last path
327388
in
328389
let ppath_s =
@@ -348,7 +409,7 @@ let unified_diff ?(cmds=false) ?recurse:_ (path : string list) (Diff_string res)
348409
Diff_string { res with ppath = ppath_l; udiff = str_diff; }
349410
| Unchanged -> Diff_string (res)
350411
| Updated v ->
351-
let ov = Config_tree.get_values res.left path in
412+
let ov = (Config_tree.get_values[@alert "-exn"]) res.left path in
352413
match ov, v with
353414
| [_], [_] ->
354415
let str_diff =
@@ -405,6 +466,10 @@ let compare_at_path_maybe_empty left right path =
405466
in (left, right)
406467

407468
let show_diff ?(cmds=false) path left right =
469+
(* raises:
470+
[Incommensurable],
471+
[Empty_comparison] from compare_at_path_maybe_empty
472+
*)
408473
if (name_of left) <> (name_of right) then
409474
raise Incommensurable
410475
else
@@ -425,19 +490,34 @@ let show_diff ?(cmds=false) path left right =
425490

426491
(* mask function; mask applied on right *)
427492
let mask_func ?recurse:_ (path : string list) (Diff_tree res) (m : change) =
493+
(* alert exn Vytree.delete:
494+
[Vytree.Empty_path] not possible since Unchanged pattern is only empty path
495+
[Vytree.Nonexistent_path] not possible as called on existing config paths (res.left)
496+
alert exn Vytree.is_terminal_path:
497+
[Vytree.Empty_path] not possible since Unchanged pattern is only empty path
498+
*)
428499
match m with
429500
| Added -> Diff_tree (res)
430501
| Subtracted ->
431502
(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))
503+
| [_] ->
504+
Diff_tree {res with left = (Vytree.delete[@alert "-exn"]) res.left path}
505+
| _ ->
506+
if not ((Vytree.is_terminal_path[@alert "-exn"]) res.right (list_but_last path)) then
507+
Diff_tree {res with left = (Vytree.delete[@alert "-exn"]) res.left path}
508+
else Diff_tree (res))
436509
| Unchanged -> Diff_tree (res)
437510
| Updated _ -> Diff_tree (res)
438511

439512
(* call recursive diff with mask_func; mask applied on right *)
440513
let mask_tree left right =
514+
(* raises:
515+
[Empty_comparison] from diff
516+
[Incommensurable]
517+
*)
518+
if (name_of left) <> (name_of right) then
519+
raise Incommensurable
520+
else
441521
let trees = make_diff_trees left right in
442522
let d = diff [] mask_func trees (Option.some left, Option.some right)
443523
in
@@ -450,19 +530,33 @@ let union_of_values (n : Config_tree.t) (m : Config_tree.t) =
450530
ValueS.elements (ValueS.union set_n set_m)
451531

452532
let tree_union s t =
533+
(* raises:
534+
[Tree_alg.Incompatible_union]
535+
[Tree_alg.Nonexistent_child] should not be reachable
536+
alert exn Tree_alg.ConfigAlg.tree_union:
537+
[Tree_alg.Incompatible_union] allow raise
538+
[Tree_alg.Nonexistent_child] allow raise; should not be reachable
539+
*)
453540
let f u v =
454541
let values = union_of_values u v in
455542
let data = {(data_of v) with Config_tree.values = values} in
456543
Vytree.make_full data (name_of v) (children_of v)
457544
in
458-
Tree_alg.ConfigAlg.tree_union s t f
545+
(Tree_alg.ConfigAlg.tree_union[@alert "-exn"]) s t f
459546

460547
let tree_merge ?(destructive=false) s t =
548+
(* raises:
549+
[Tree_alg.Incompatible_union]
550+
[Tree_alg.Nonexistent_child] should not be reachable
551+
alert exn Tree_alg.ConfigAlg.tree_union:
552+
[Tree_alg.Incompatible_union] allow raise
553+
[Tree_alg.Nonexistent_child] allow raise; should not be reachable
554+
*)
461555
let f u v =
462556
let data =
463557
match destructive with
464558
| false -> data_of u
465559
| true -> data_of v
466560
in Vytree.make_full data (name_of v) (children_of v)
467561
in
468-
Tree_alg.ConfigAlg.tree_union s t f
562+
(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)