Skip to content

Commit 4a97c4c

Browse files
leosterahuwaireb
andauthored
feat: make it work on ocaml 5.2 (#470)
Co-authored-by: Rashid Al Muhairi <[email protected]>
1 parent 232a8ff commit 4a97c4c

6 files changed

+126
-28
lines changed

CHANGES.md

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
unreleased
2+
----------
3+
4+
* Add support for OCaml 5.2 (#470, fixes #466, @leostera, @ManasJayanth,
5+
@huwaireb)
6+
17
2.13.1 (2023-07-07)
28
-------------------
39

dune-workspace.dev

+1
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
(context (opam (switch utop-414)))
66
(context (opam (switch utop-500)))
77
(context (opam (switch utop-510)))
8+
(context (opam (switch utop-520)))

src/lib/uTop.ml

+9-8
Original file line numberDiff line numberDiff line change
@@ -288,9 +288,8 @@ let parse_default parse str eos_is_error =
288288
| Syntaxerr.Ill_formed_ast (loc, s) ->
289289
Error ([mkloc loc],
290290
Printf.sprintf "Error: broken invariant in parsetree: %s" s)
291-
| Syntaxerr.Invalid_package_type (loc, s) ->
292-
Error ([mkloc loc],
293-
Printf.sprintf "Invalid package type: %s" s)
291+
| Syntaxerr.Invalid_package_type (loc, err) ->
292+
Error ([mkloc loc], UTop_compat.invalid_package_error_to_string err)
294293
#if OCAML_VERSION >= (5, 0, 0)
295294
| Syntaxerr.Removed_string_set loc ->
296295
Error ([mkloc loc],
@@ -358,11 +357,12 @@ let check_phrase phrase =
358357
let open Ast_helper in
359358
with_default_loc loc
360359
(fun () ->
361-
Str.eval
362-
(Exp.fun_ Nolabel None (Pat.construct unit None)
363-
(Exp.letmodule (with_loc loc (Some "_"))
360+
let punit = (Pat.construct unit None) in
361+
let body = (Exp.letmodule ~loc:loc
362+
(with_loc loc (Some "_"))
364363
(Mod.structure (item :: items))
365-
(Exp.construct unit None))))
364+
(Exp.construct unit None)) in
365+
Str.eval (UTop_compat.Exp.fun_ ~loc punit body))
366366
in
367367
let check_phrase = Ptop_def [top_def] in
368368
try
@@ -828,7 +828,8 @@ let () =
828828
| Compiler-libs re-exports |
829829
+-----------------------------------------------------------------+ *)
830830

831-
let get_load_path () = Load_path.get_paths ()
831+
let get_load_path = UTop_compat.get_load_path
832+
832833
let set_load_path = UTop_compat.set_load_path
833834

834835
module Private = struct

src/lib/uTop_compat.ml

+91-4
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,21 @@ let toploop_all_directive_names () =
1919
Hashtbl.fold (fun dir _ acc -> dir::acc) Toploop.directive_table []
2020
#endif
2121

22-
let set_load_path path =
23-
#if OCAML_VERSION >= (5, 0, 0)
24-
Load_path.init path ~auto_include:Load_path.no_auto_include
22+
let get_load_path () =
23+
#if OCAML_VERSION >= (5, 2, 0)
24+
let {Load_path.visible; hidden} = Load_path.get_paths () in
25+
visible @ hidden
26+
#else
27+
Load_path.get_paths ()
28+
#endif
29+
30+
let set_load_path visible =
31+
#if OCAML_VERSION >= (5, 2, 0)
32+
Load_path.init ~auto_include:Load_path.no_auto_include ~visible ~hidden:[]
33+
#elif OCAML_VERSION >= (5, 0, 0)
34+
Load_path.init ~auto_include:Load_path.no_auto_include visible
2535
#else
26-
Load_path.init path
36+
Load_path.init visible
2737
#endif
2838

2939
let toploop_use_silently fmt name =
@@ -55,3 +65,80 @@ let rec is_persistent_path = function
5565
#if OCAML_VERSION >= (5, 1, 0)
5666
| Path.Pextra_ty (p, _) -> is_persistent_path p
5767
#endif
68+
69+
let invalid_package_error_to_string err =
70+
#if OCAML_VERSION >= (5, 2, 0)
71+
(* NOTE: from https://github.com/ocaml/ocaml/blob/9b059b1e7a66e9d2f04d892a4de34c418cd96f69/parsing/parse.ml#L149 *)
72+
let invalid ppf ipt = match ipt with
73+
| Syntaxerr.Parameterized_types ->
74+
Format.fprintf ppf "parametrized types are not supported"
75+
| Constrained_types ->
76+
Format.fprintf ppf "constrained types are not supported"
77+
| Private_types ->
78+
Format.fprintf ppf "private types are not supported"
79+
| Not_with_type ->
80+
Format.fprintf ppf "only %a constraints are supported"
81+
Misc.Style.inline_code "with type t ="
82+
| Neither_identifier_nor_with_type ->
83+
Format.fprintf ppf
84+
"only module type identifier and %a constraints are supported"
85+
Misc.Style.inline_code "with type"
86+
in
87+
let buf = Buffer.create 128 in
88+
let fmt = Format.formatter_of_buffer buf in
89+
Format.fprintf fmt "Invalid package type: %a%!" invalid err;
90+
Buffer.contents buf
91+
#else
92+
err
93+
#endif
94+
95+
module Exp = struct
96+
open Ast_helper
97+
#if OCAML_VERSION >= (5, 2, 0)
98+
open Parsetree
99+
let fun_ ~loc p e =
100+
let args = [{
101+
pparam_loc=loc;
102+
pparam_desc=Pparam_val (Nolabel, None, p);
103+
}] in
104+
(Exp.function_ args None (Pfunction_body e))
105+
#else
106+
let fun_ ~loc p e = Exp.fun_ ~loc Nolabel None p e
107+
#endif
108+
end
109+
110+
let abstract_type_kind =
111+
#if OCAML_VERSION >= (5, 2, 0)
112+
Types.(Type_abstract Definition)
113+
#else
114+
Types.Type_abstract
115+
#endif
116+
117+
let find_in_path_normalized =
118+
#if OCAML_VERSION >= (5, 2, 0)
119+
Misc.find_in_path_normalized
120+
#else
121+
Misc.find_in_path_uncap
122+
#endif
123+
124+
let visible_paths_for_cmt_infos (cmt_infos: Cmt_format.cmt_infos) =
125+
#if OCAML_VERSION >= (5, 2, 0)
126+
cmt_infos.cmt_loadpath.visible
127+
#else
128+
cmt_infos.cmt_loadpath
129+
#endif
130+
131+
let add_cmi_hook f =
132+
let default_load = !Persistent_env.Persistent_signature.load in
133+
#if OCAML_VERSION >= (5, 2, 0)
134+
let load ~allow_hidden ~unit_name =
135+
let res = default_load ~unit_name ~allow_hidden in
136+
#else
137+
let load ~unit_name =
138+
let res = default_load ~unit_name in
139+
#endif
140+
(match res with None -> () | Some x -> f x.cmi);
141+
res
142+
in
143+
Persistent_env.Persistent_signature.load := load
144+

src/lib/uTop_complete.ml

+11-3
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ let visible_modules () =
394394
(Sys.readdir (if dir = "" then Filename.current_dir_name else dir))
395395
with Sys_error _ ->
396396
acc)
397-
String_set.empty @@ Load_path.get_paths ()
397+
String_set.empty @@ UTop_compat.get_load_path ()
398398
)
399399

400400
let field_name { ld_id = id } = Ident.name id
@@ -406,7 +406,11 @@ let add_fields_of_type decl acc =
406406
acc
407407
| Type_record (fields, _) ->
408408
List.fold_left (fun acc field -> add (field_name field) acc) acc fields
409+
#if OCAML_VERSION >= (5, 2, 0)
410+
| Type_abstract _ ->
411+
#else
409412
| Type_abstract ->
413+
#endif
410414
acc
411415
| Type_open ->
412416
acc
@@ -421,7 +425,11 @@ let add_names_of_type decl acc =
421425
List.fold_left (fun acc cstr -> add (constructor_name cstr) acc) acc constructors
422426
| Type_record (fields, _) ->
423427
List.fold_left (fun acc field -> add (field_name field) acc) acc fields
428+
#if OCAML_VERSION >= (5, 2, 0)
429+
| Type_abstract _ ->
430+
#else
424431
| Type_abstract ->
432+
#endif
425433
acc
426434
| Type_open ->
427435
acc
@@ -839,7 +847,7 @@ let complete ~phrase_terminator ~input =
839847
(fun acc d -> add_files filter acc (Filename.concat d dir))
840848
String_map.empty
841849
(Filename.current_dir_name ::
842-
(Load_path.get_paths ())
850+
(UTop_compat.get_load_path ())
843851
)
844852

845853
else
@@ -899,7 +907,7 @@ let complete ~phrase_terminator ~input =
899907
(fun acc d -> add_files filter acc (Filename.concat d dir))
900908
String_map.empty
901909
(Filename.current_dir_name ::
902-
(Load_path.get_paths ())
910+
(UTop_compat.get_load_path ())
903911
)
904912
else
905913
add_files filter String_map.empty (Filename.dirname file)

src/lib/uTop_main.ml

+8-13
Original file line numberDiff line numberDiff line change
@@ -335,14 +335,7 @@ end = struct
335335

336336
let scan_cmis =
337337
let new_cmis = ref [] in
338-
let default_load = !Persistent_env.Persistent_signature.load in
339-
let load ~unit_name =
340-
let res = default_load ~unit_name in
341-
(match res with None -> () | Some x -> new_cmis := x.cmi :: !new_cmis);
342-
res
343-
in
344-
Persistent_env.Persistent_signature.load := load;
345-
338+
UTop_compat.add_cmi_hook (fun cmi -> new_cmis := cmi :: !new_cmis );
346339
fun pp ->
347340
List.iter (fun (cmi : Cmi_format.cmi_infos) ->
348341
walk_sig pp ~path:(Longident.Lident cmi.cmi_name) cmi.cmi_sign
@@ -567,7 +560,7 @@ let rewrite_rules = [
567560
with_default_loc loc (fun () ->
568561
Exp.apply
569562
(Exp.ident (with_loc loc longident_async_thread_safe_block_on_async_exn))
570-
[(Nolabel, Exp.fun_ Nolabel None punit e)]
563+
[(Nolabel, UTop_compat.Exp.fun_ ~loc punit e)]
571564
)
572565
);
573566
enabled = UTop.auto_run_async;
@@ -582,10 +575,10 @@ let rule_path rule =
582575
let env = !Toploop.toplevel_env in
583576
let path =
584577
match Env.find_type_by_name rule.type_to_rewrite env with
585-
| path, { Types.type_kind = Types.Type_abstract
578+
| path, { Types.type_kind = type_kind
586579
; Types.type_private = Asttypes.Public
587580
; Types.type_manifest = Some ty
588-
} -> begin
581+
} when type_kind = UTop_compat.abstract_type_kind -> begin
589582
match get_desc (Ctype.expand_head env ty) with
590583
| Types.Tconstr (path, _, _) -> path
591584
| _ -> path
@@ -1545,7 +1538,8 @@ let interact ?(search_path=[]) ?(build_dir="_build") ~unit ~loc:(fname, lnum, cn
15451538
let search_path = walk build_dir ~init:search_path ~f:(fun dir acc -> dir :: acc) in
15461539
let cmt_fname =
15471540
try
1548-
Misc.find_in_path_uncap search_path (unit ^ ".cmt")
1541+
UTop_compat.find_in_path_normalized
1542+
search_path (unit ^ ".cmt")
15491543
with Not_found ->
15501544
Printf.ksprintf failwith "%s.cmt not found in search path!" unit
15511545
in
@@ -1577,7 +1571,8 @@ let interact ?(search_path=[]) ?(build_dir="_build") ~unit ~loc:(fname, lnum, cn
15771571
failwith "Couldn't find location in cmt file"
15781572
with Found env ->
15791573
try
1580-
List.iter Topdirs.dir_directory (search_path @ cmt_infos.cmt_loadpath);
1574+
let visible_paths = UTop_compat.visible_paths_for_cmt_infos cmt_infos in
1575+
List.iter Topdirs.dir_directory (search_path @ visible_paths);
15811576
let env = Envaux.env_of_only_summary env in
15821577
List.iter (fun (V (name, v)) -> Toploop.setvalue name (Obj.repr v)) values;
15831578
main_internal ~initial_env:(Some env)

0 commit comments

Comments
 (0)