Skip to content

Commit

Permalink
env refactoring: use a custom ADT for missing pers_struct entries
Browse files Browse the repository at this point in the history
The hope is that a tailor-made algebraic datatype is more readable /
less confusing than using ('a option) directly -- one may confuse
getting None when looking in a table with the Not_found case.

(Suggested by Jérémie Dimino)
  • Loading branch information
gasche committed Feb 1, 2019
1 parent 8674451 commit 6fa23da
Showing 1 changed file with 17 additions and 11 deletions.
28 changes: 17 additions & 11 deletions typing/persistent_env.ml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,14 @@ type pers_struct = {

module String = Misc.Stdlib.String

(* If a .cmi file is missing (or invalid), we
store it as Missing in the cache. *)
type 'a pers_struct_info =
| Missing
| Found of pers_struct * 'a

type 'a t = {
persistent_structures : (string, (pers_struct * 'a) option) Hashtbl.t;
persistent_structures : (string, 'a pers_struct_info) Hashtbl.t;
imported_units: String.Set.t ref;
imported_opaque_units: String.Set.t ref;
crc_units: Consistbl.t;
Expand Down Expand Up @@ -72,7 +78,7 @@ let clear penv =
let clear_missing {persistent_structures; _} =
let missing_entries =
Hashtbl.fold
(fun name r acc -> if r = None then name :: acc else acc)
(fun name r acc -> if r = Missing then name :: acc else acc)
persistent_structures []
in
List.iter (Hashtbl.remove persistent_structures) missing_entries
Expand All @@ -85,8 +91,8 @@ let add_imported_opaque {imported_opaque_units; _} s =

let find_in_cache {persistent_structures; _} s =
match Hashtbl.find persistent_structures s with
| exception Not_found | None -> None
| Some (_ps, pm) -> Some pm
| exception Not_found | Missing -> None
| Found (_ps, pm) -> Some pm

let import_crcs penv ~source crcs =
let {crc_units; _} = penv in
Expand Down Expand Up @@ -120,16 +126,16 @@ let without_cmis penv f x =

let fold {persistent_structures; _} f x =
Hashtbl.fold (fun modname pso x -> match pso with
| None -> x
| Some (_, pm) -> f modname pm x)
| Missing -> x
| Found (_, pm) -> f modname pm x)
persistent_structures x

(* Reading persistent structures from .cmi files *)

let save_pers_struct penv crc ps pm =
let {persistent_structures; crc_units; _} = penv in
let modname = ps.ps_name in
Hashtbl.add persistent_structures modname (Some (ps, pm));
Hashtbl.add persistent_structures modname (Found (ps, pm));
List.iter
(function
| Rectypes -> ()
Expand Down Expand Up @@ -165,7 +171,7 @@ let acknowledge_pers_struct penv check modname pers_sig pm =
ps.ps_flags;
if check then check_consistency penv ps;
let {persistent_structures; _} = penv in
Hashtbl.add persistent_structures modname (Some (ps, pm));
Hashtbl.add persistent_structures modname (Found (ps, pm));
ps

let read_pers_struct penv val_of_pers_sig check modname filename =
Expand All @@ -180,8 +186,8 @@ let find_pers_struct penv val_of_pers_sig check name =
let {persistent_structures; _} = penv in
if name = "*predef*" then raise Not_found;
match Hashtbl.find persistent_structures name with
| Some ps -> ps
| None -> raise Not_found
| Found (ps, pm) -> (ps, pm)
| Missing -> raise Not_found
| exception Not_found ->
match can_load_cmis penv with
| Cannot_load_cmis _ -> raise Not_found
Expand All @@ -190,7 +196,7 @@ let find_pers_struct penv val_of_pers_sig check name =
match !Persistent_signature.load ~unit_name:name with
| Some psig -> psig
| None ->
Hashtbl.add persistent_structures name None;
Hashtbl.add persistent_structures name Missing;
raise Not_found
in
add_import penv name;
Expand Down

0 comments on commit 6fa23da

Please sign in to comment.