@@ -4,10 +4,19 @@ let ( let> ) x f =
44let mod_name file =
55 String. capitalize_ascii Filename. (remove_extension (basename file))
66
7+ let load_cmi file_path =
8+ try
9+ let cmi_infos = Cmi_format. read_cmi file_path in
10+ Ok (cmi_infos.cmi_sign, cmi_infos.cmi_name)
11+ with e ->
12+ Error
13+ (Printf. sprintf " Error parsing %s: %s" file_path (Printexc. to_string e))
14+
715let lazy_sig path =
16+ let open CCResult.Infix in
817 Lazy. from_fun (fun () ->
9- let cmi_infos = Cmi_format. read_cmi path in
10- cmi_infos. cmi_sign)
18+ let + cmi_sign, _ = load_cmi path in
19+ cmi_sign)
1120
1221let collect_modules dir =
1322 try
@@ -26,13 +35,12 @@ let collect_modules dir =
2635 Error (Printf. sprintf " Error reading directory %s: %s" dir e)
2736
2837let get_sig modname map =
29- Option. map Lazy. force (String_map. find_opt modname map)
30-
31- let load_cmi file_path =
32- try
33- let cmi_infos = Cmi_format. read_cmi file_path in
34- Ok (cmi_infos.cmi_sign, cmi_infos.cmi_name)
35- with e -> Error (Printexc. to_string e)
38+ let open CCResult.Infix in
39+ match String_map. find_opt modname map with
40+ | None -> Ok None
41+ | Some lazy_sig ->
42+ let * sig_ = Lazy. force lazy_sig in
43+ Ok (Some sig_)
3644
3745type 'a named = { name : string ; value : 'a }
3846(* * Attach a module name to its various representations, e.g. a [signature] or a
@@ -86,7 +94,7 @@ let find_module_item modname sig_ =
8694 | Some mty -> Ok mty
8795 | None -> lookup_error ~path: modname ~module_name: sig_.name
8896
89- let find_module_type modname sig_ =
97+ let find_module_type_in_sig modname sig_ =
9098 let open Types in
9199 let mty_opt =
92100 List. find_map
@@ -101,21 +109,32 @@ let find_module_type modname sig_ =
101109 | Some mty -> Ok mty
102110 | None -> lookup_error ~path: modname ~module_name: sig_.name
103111
112+ let populate_env typing_env sig_ =
113+ List. fold_left
114+ (fun env sigi ->
115+ match sigi with
116+ | Types. Sig_modtype (id , modtype , Exported) ->
117+ Env. add_modtype id modtype env
118+ | _ -> env)
119+ typing_env sig_
120+
104121let rec find_module_in_sig ~library_modules path sig_ =
105122 let open CCResult.Infix in
123+ let typing_env = populate_env Env. empty sig_.value in
106124 match (path : Flat_path.t ) with
107125 | [ last ] ->
108126 let modname = Flat_path. modname_from_component last in
109127 find_module_item modname sig_
110128 | hd :: tl ->
111129 let modname = Flat_path. modname_from_component hd in
112130 let * mty = find_module_item modname sig_ in
113- find_module_in_md_type ~library_modules tl { name = modname; value = mty }
131+ find_module_in_md_type ~typing_env ~library_modules tl
132+ { name = modname; value = mty }
114133 | [] -> assert false
115134
116- and find_module_in_md_type ~library_modules path mty =
135+ and find_module_in_md_type ~typing_env ~ library_modules path mty =
117136 let open CCResult.Infix in
118- let * sig_ = sig_of_module_type ~library_modules mty.value in
137+ let * sig_ = sig_of_module_type ~typing_env ~ library_modules mty.value in
119138 match sig_ with
120139 | None ->
121140 let res =
@@ -137,48 +156,75 @@ and find_module_in_lib ~library_modules path :
137156 match path with
138157 | [ comp ] ->
139158 let modname = Flat_path. modname_from_component comp in
140- let > sig_ = Ok ( get_sig modname library_modules) in
159+ let > sig_ = get_sig modname library_modules in
141160 Ok (Some (Mty_signature sig_))
142- | comp :: inner_path -> (
161+ | comp :: inner_path ->
143162 let modname = Flat_path. modname_from_component comp in
144- match get_sig modname library_modules with
145- | None -> Ok None
146- | Some parent_sig ->
147- let + mty =
148- find_module_in_sig ~library_modules inner_path
149- { name = modname; value = parent_sig }
150- in
151- Some mty)
163+ let > parent_sig = get_sig modname library_modules in
164+ let + mty =
165+ find_module_in_sig ~library_modules inner_path
166+ { name = modname; value = parent_sig }
167+ in
168+ Some mty
152169 | _ -> Ok None
153170
154- and find_module_type_in_lib ~library_modules path :
155- (Types. module_type option , string ) result =
171+ and find_local_module_type ~typing_env path =
172+ try Some (`Local , Env. find_modtype_expansion path typing_env)
173+ with Not_found -> None
174+
175+ and find_global_module_type ~library_modules path =
176+ let typing_env = Env. empty in
156177 match path with
157178 | Path. Pdot (parent_mod_path , mty_name ) ->
158179 let > parent_mod = find_module_in_lib ~library_modules parent_mod_path in
159- let > sig_ = sig_of_module_type ~library_modules parent_mod in
160- find_module_type mty_name { name = mty_name; value = sig_ }
180+ let > sig_ = sig_of_module_type ~typing_env ~library_modules parent_mod in
181+ let > mty =
182+ find_module_type_in_sig mty_name { name = mty_name; value = sig_ }
183+ in
184+ Ok (Some (`Global , mty))
161185 | _ -> assert false (* Path to module type cannot be root modules/functors *)
162186
163- and sig_of_module_type ~library_modules module_type =
187+ and find_module_type ~typing_env ~library_modules path =
188+ match find_local_module_type ~typing_env path with
189+ | Some modtype -> Ok (Some modtype)
190+ | None -> find_global_module_type ~library_modules path
191+
192+ (* and find_module_type_in_lib ~library_modules ~typing_env path :
193+ (Types.module_type option, string) result =
194+ match (find_local_module_type ~typing_env path) with
195+ | Some x ->
196+ Ok (Some x)
197+ | None ->
198+ find_global_module_type ~library_modules
199+ *)
200+ and typing_env_for ~typing_env = function
201+ | `Local -> typing_env
202+ | `Global -> Env. empty
203+
204+ and sig_of_module_type ~library_modules ~typing_env module_type =
164205 match module_type with
165206 | Types. Mty_alias path ->
207+ (* find_module_in_lib only looks up globally, we shoud proabably fix it. *)
166208 let > mty = find_module_in_lib ~library_modules path in
167- sig_of_module_type ~library_modules mty
209+ sig_of_module_type ~typing_env: Env. empty ~ library_modules mty
168210 | Mty_ident path ->
169- let > mty = find_module_type_in_lib ~library_modules path in
170- sig_of_module_type ~library_modules mty
211+ let > where, mty = find_module_type ~typing_env ~library_modules path in
212+ let typing_env = typing_env_for ~typing_env where in
213+ sig_of_module_type ~typing_env ~library_modules mty
171214 | Mty_signature sig_ -> Ok (Some sig_)
172215 | Mty_functor _ -> Ok None
173216
174- let rec expand_sig ~library_modules sig_ =
217+ let rec expand_sig ~typing_env ~ library_modules sig_ =
175218 let open Types in
176219 let open CCResult.Infix in
220+ let typing_env = populate_env typing_env sig_ in
177221 CCResult. map_l
178222 (fun item ->
179223 match item with
180224 | Sig_module (id , presence , ({ md_type; _ } as mod_decl ), rs , vis ) ->
181- let * md_type = expand_module_type ~library_modules md_type in
225+ let * md_type =
226+ expand_module_type ~typing_env ~library_modules md_type
227+ in
182228 let presence =
183229 match md_type with
184230 | Mty_alias _ -> presence
@@ -189,11 +235,11 @@ let rec expand_sig ~library_modules sig_ =
189235 | _ -> Ok item)
190236 sig_
191237
192- and expand_module_type ~library_modules module_type =
238+ and expand_module_type ~typing_env ~ library_modules module_type =
193239 let open CCResult.Infix in
194240 let + res =
195- let > sig_ = sig_of_module_type ~library_modules module_type in
196- let + expanded = expand_sig ~library_modules sig_ in
241+ let > sig_ = sig_of_module_type ~typing_env ~ library_modules module_type in
242+ let + expanded = expand_sig ~typing_env ~ library_modules sig_ in
197243 Some (Types. Mty_signature expanded)
198244 in
199245 Option. value ~default: module_type res
@@ -203,24 +249,30 @@ type t = Types.signature String_map.t
203249let load_unwrapped project_path : (t, string) result =
204250 let open CCResult.Infix in
205251 let * library_modules = collect_modules project_path in
206- let module_map =
252+ let module_res_map =
207253 String_map. map (fun sig_ -> Lazy. force sig_) library_modules
208254 in
209- Ok module_map
255+ String_map. fold
256+ (fun key value acc ->
257+ let * acc = acc in
258+ let * value = value in
259+ Ok (String_map. add key value acc))
260+ module_res_map (Ok String_map. empty)
210261
211262let load ~main_module project_path : (t, string) result =
212263 let open CCResult.Infix in
213264 let * library_modules = collect_modules project_path in
214265 let * main_sig =
215- match get_sig main_module library_modules with
266+ let * x = get_sig main_module library_modules in
267+ match x with
216268 | Some s -> Ok s
217269 | None ->
218270 Error
219271 (Printf. sprintf " Could not find main module %s in %s" main_module
220272 project_path)
221273 in
222274 let expanded_main_sig =
223- match expand_sig ~library_modules main_sig with
275+ match expand_sig ~typing_env: Env. empty ~ library_modules main_sig with
224276 | Ok expanded_sig -> expanded_sig
225277 | Error e -> failwith e
226278 in
0 commit comments