Skip to content

Commit bb82646

Browse files
Forestrykspoechsel
andauthored
flambda-backend: Refactor load_path.ml (#2420)
* Refactor load_path.ml * Typo --------- Co-authored-by: Pierre Oechsel <[email protected]>
1 parent e539d07 commit bb82646

File tree

2 files changed

+95
-71
lines changed

2 files changed

+95
-71
lines changed

utils/load_path.ml

Lines changed: 95 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,18 @@
1414

1515
open Local_store
1616

17-
module STbl = Misc.Stdlib.String.Tbl
17+
module Dir : sig
18+
type t
1819

19-
(* Mapping from basenames to full filenames *)
20-
type registry = string STbl.t
20+
val path : t -> string
21+
val files : t -> string list
22+
val hidden : t -> bool
2123

22-
let visible_files : registry ref = s_table STbl.create 42
23-
let visible_files_uncap : registry ref = s_table STbl.create 42
24+
val create : hidden:bool -> string -> t
2425

25-
let hidden_files : registry ref = s_table STbl.create 42
26-
let hidden_files_uncap : registry ref = s_table STbl.create 42
27-
28-
module Dir = struct
26+
val find : t -> string -> string option
27+
val find_uncap : t -> string -> string option
28+
end = struct
2929
type t = {
3030
path : string;
3131
files : string list;
@@ -65,6 +65,81 @@ module Dir = struct
6565
{ path; files = Array.to_list (readdir_compat path); hidden }
6666
end
6767

68+
type visibility = Visible | Hidden
69+
70+
(** Stores cached paths to files *)
71+
module Path_cache : sig
72+
(* Clear cache *)
73+
val reset : unit -> unit
74+
75+
(* Same as [add] below, but will replace existing entries.
76+
77+
[prepend_add] is faster than [add] and intended for use in [init] and [remove_dir]:
78+
since we are starting from an empty cache, we can avoid checking whether a unit name
79+
already exists in the cache simply by adding entries in reverse order. *)
80+
val prepend_add : Dir.t -> unit
81+
82+
(* Add path to cache. If path with same basename is already in cache, skip adding. *)
83+
val add : Dir.t -> unit
84+
85+
(* Search for a basename in cache. Ignore case if [uncap] is true *)
86+
val find : uncap:bool -> string -> string * visibility
87+
end = struct
88+
module STbl = Misc.Stdlib.String.Tbl
89+
90+
(* Mapping from basenames to full filenames *)
91+
type registry = string STbl.t
92+
93+
let visible_files : registry ref = s_table STbl.create 42
94+
let visible_files_uncap : registry ref = s_table STbl.create 42
95+
96+
let hidden_files : registry ref = s_table STbl.create 42
97+
let hidden_files_uncap : registry ref = s_table STbl.create 42
98+
99+
let reset () =
100+
STbl.clear !hidden_files;
101+
STbl.clear !hidden_files_uncap;
102+
STbl.clear !visible_files;
103+
STbl.clear !visible_files_uncap
104+
105+
let prepend_add dir =
106+
List.iter (fun base ->
107+
let fn = Filename.concat (Dir.path dir) base in
108+
if Dir.hidden dir then begin
109+
STbl.replace !hidden_files base fn;
110+
STbl.replace !hidden_files_uncap (String.uncapitalize_ascii base) fn
111+
end else begin
112+
STbl.replace !visible_files base fn;
113+
STbl.replace !visible_files_uncap (String.uncapitalize_ascii base) fn
114+
end
115+
) (Dir.files dir)
116+
117+
let add dir =
118+
let update base fn visible_files hidden_files =
119+
if (Dir.hidden dir) && not (STbl.mem !hidden_files base) then
120+
STbl.replace !hidden_files base fn
121+
else if not (STbl.mem !visible_files base) then
122+
STbl.replace !visible_files base fn
123+
in
124+
List.iter
125+
(fun base ->
126+
let fn = Filename.concat (Dir.path dir) base in
127+
update base fn visible_files hidden_files;
128+
let ubase = String.uncapitalize_ascii base in
129+
update ubase fn visible_files_uncap hidden_files_uncap)
130+
(Dir.files dir)
131+
132+
let find fn visible_files hidden_files =
133+
try (STbl.find !visible_files fn, Visible) with
134+
| Not_found -> (STbl.find !hidden_files fn, Hidden)
135+
136+
let find ~uncap fn =
137+
if uncap then
138+
find (String.uncapitalize_ascii fn) visible_files_uncap hidden_files_uncap
139+
else
140+
find fn visible_files hidden_files
141+
end
142+
68143
type auto_include_callback =
69144
(Dir.t -> string -> string option) -> string -> string
70145

@@ -75,10 +150,7 @@ let auto_include_callback = ref no_auto_include
75150

76151
let reset () =
77152
assert (not Config.merlin || Local_store.is_bound ());
78-
STbl.clear !hidden_files;
79-
STbl.clear !hidden_files_uncap;
80-
STbl.clear !visible_files;
81-
STbl.clear !visible_files_uncap;
153+
Path_cache.reset ();
82154
hidden_dirs := [];
83155
visible_dirs := [];
84156
auto_include_callback := no_auto_include
@@ -99,28 +171,12 @@ let get_paths () =
99171
let get_visible_path_list () = List.rev_map Dir.path !visible_dirs
100172
let get_hidden_path_list () = List.rev_map Dir.path !hidden_dirs
101173

102-
(* Optimized version of [add] below, for use in [init] and [remove_dir]: since
103-
we are starting from an empty cache, we can avoid checking whether a unit
104-
name already exists in the cache simply by adding entries in reverse
105-
order. *)
106-
let prepend_add dir =
107-
List.iter (fun base ->
108-
let fn = Filename.concat dir.Dir.path base in
109-
if dir.Dir.hidden then begin
110-
STbl.replace !hidden_files base fn;
111-
STbl.replace !hidden_files_uncap (String.uncapitalize_ascii base) fn
112-
end else begin
113-
STbl.replace !visible_files base fn;
114-
STbl.replace !visible_files_uncap (String.uncapitalize_ascii base) fn
115-
end
116-
) dir.Dir.files
117-
118174
let init ~auto_include ~visible ~hidden =
119175
reset ();
120176
visible_dirs := List.rev_map (Dir.create ~hidden:false) visible;
121177
hidden_dirs := List.rev_map (Dir.create ~hidden:true) hidden;
122-
List.iter prepend_add !hidden_dirs;
123-
List.iter prepend_add !visible_dirs;
178+
List.iter Path_cache.prepend_add !hidden_dirs;
179+
List.iter Path_cache.prepend_add !visible_dirs;
124180
auto_include_callback := auto_include
125181

126182
let remove_dir dir =
@@ -132,29 +188,17 @@ let remove_dir dir =
132188
reset ();
133189
visible_dirs := visible;
134190
hidden_dirs := hidden;
135-
List.iter prepend_add hidden;
136-
List.iter prepend_add visible
191+
List.iter Path_cache.prepend_add hidden;
192+
List.iter Path_cache.prepend_add visible
137193
end
138194

139195
(* General purpose version of function to add a new entry to load path: We only
140196
add a basename to the cache if it is not already present, in order to enforce
141197
left-to-right precedence. *)
142198
let add (dir : Dir.t) =
143199
assert (not Config.merlin || Local_store.is_bound ());
144-
let update base fn visible_files hidden_files =
145-
if dir.hidden && not (STbl.mem !hidden_files base) then
146-
STbl.replace !hidden_files base fn
147-
else if not (STbl.mem !visible_files base) then
148-
STbl.replace !visible_files base fn
149-
in
150-
List.iter
151-
(fun base ->
152-
let fn = Filename.concat dir.Dir.path base in
153-
update base fn visible_files hidden_files;
154-
let ubase = String.uncapitalize_ascii base in
155-
update ubase fn visible_files_uncap hidden_files_uncap)
156-
dir.files;
157-
if dir.hidden then
200+
Path_cache.add dir;
201+
if (Dir.hidden dir) then
158202
hidden_dirs := dir :: !hidden_dirs
159203
else
160204
visible_dirs := dir :: !visible_dirs
@@ -167,8 +211,8 @@ let add_dir ~hidden dir = add (Dir.create ~hidden dir)
167211
unconditionally added. *)
168212
let prepend_dir (dir : Dir.t) =
169213
assert (not Config.merlin || Local_store.is_bound ());
170-
prepend_add dir;
171-
if dir.hidden then
214+
Path_cache.prepend_add dir;
215+
if (Dir.hidden dir) then
172216
hidden_dirs := !hidden_dirs @ [dir]
173217
else
174218
visible_dirs := !visible_dirs @ [dir]
@@ -197,17 +241,11 @@ let auto_include_otherlibs =
197241
List.map (fun lib -> (lib, read_lib lib)) ["dynlink"; "str"; "unix"] in
198242
auto_include_libs otherlibs
199243

200-
type visibility = Visible | Hidden
201-
202-
let find_file_in_cache fn visible_files hidden_files =
203-
try (STbl.find !visible_files fn, Visible) with
204-
| Not_found -> (STbl.find !hidden_files fn, Hidden)
205-
206244
let find fn =
207245
assert (not Config.merlin || Local_store.is_bound ());
208246
try
209247
if is_basename fn && not !Sys.interactive then
210-
fst (find_file_in_cache fn visible_files hidden_files)
248+
fst (Path_cache.find ~uncap:false fn)
211249
else
212250
Misc.find_in_path (get_path_list ()) fn
213251
with Not_found ->
@@ -217,8 +255,7 @@ let find_uncap_with_visibility fn =
217255
assert (not Config.merlin || Local_store.is_bound ());
218256
try
219257
if is_basename fn && not !Sys.interactive then
220-
find_file_in_cache (String.uncapitalize_ascii fn)
221-
visible_files_uncap hidden_files_uncap
258+
Path_cache.find ~uncap:true fn
222259
else
223260
try
224261
(Misc.find_in_path_uncap (get_visible_path_list ()) fn, Visible)

utils/load_path.mli

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -37,22 +37,9 @@ module Dir : sig
3737

3838
val create : hidden:bool -> string -> t
3939

40-
val path : t -> string
41-
4240
val files : t -> string list
4341
(** All the files in that directory. This doesn't include files in
4442
sub-directories of this directory. *)
45-
46-
val hidden : t -> bool
47-
(** If the modules in this directory should not be bound in the initial
48-
scope *)
49-
50-
val find : t -> string -> string option
51-
(** [find dir fn] returns the full path to [fn] in [dir]. *)
52-
53-
val find_uncap : t -> string -> string option
54-
(** As {!find}, but search also for uncapitalized name, i.e. if name is
55-
Foo.ml, either /path/Foo.ml or /path/foo.ml may be returned. *)
5643
end
5744

5845
type auto_include_callback =

0 commit comments

Comments
 (0)