···9393 done
94949595let handle_findlib_error = function
9696- | Failure msg ->
9797- Printf.fprintf stderr "%s" msg
9898- | Fl_package_base.No_such_package(pkg, reason) ->
9999- Printf.fprintf stderr "No such package: %s%s\n" pkg (if reason <> "" then " - " ^ reason else "")
9696+ | Failure msg -> Printf.fprintf stderr "%s" msg
9797+ | Fl_package_base.No_such_package (pkg, reason) ->
9898+ Printf.fprintf stderr "No such package: %s%s\n" pkg
9999+ (if reason <> "" then " - " ^ reason else "")
100100 | Fl_package_base.Package_loop pkg ->
101101 Printf.fprintf stderr "Package requires itself: %s\n" pkg
102102- | exn ->
103103- raise exn
102102+ | exn -> raise exn
104103105104module Server = Js_top_worker_rpc.Toplevel_api_gen.Make (Impl.IdlM.GenServer ())
106105···111110 let sync_get _ = None
112111 let create_file ~name:_ ~content:_ = failwith "Not implemented"
113112114114- let import_scripts urls = if List.length urls > 0 then failwith "Not implemented" else ()
113113+ let import_scripts urls =
114114+ if List.length urls > 0 then failwith "Not implemented" else ()
115115116116 let init_function _ () = failwith "Not implemented"
117117-118117 let findlib_init _ = ()
119119-120120- let get_stdlib_dcs _uri =
121121- []
118118+ let get_stdlib_dcs _uri = []
122119123120 let require () packages =
124121 try
125125- let eff_packages = Findlib.package_deep_ancestors !Topfind.predicates packages in
126126- Topfind.load eff_packages; []
122122+ let eff_packages =
123123+ Findlib.package_deep_ancestors !Topfind.predicates packages
124124+ in
125125+ Topfind.load eff_packages;
126126+ []
127127 with exn ->
128128- handle_findlib_error exn; []
128128+ handle_findlib_error exn;
129129+ []
129130end
130131131132module U = Impl.Make (S)
···150151 rpc_fn (Jsonrpc.call_of_string (Bytes.unsafe_to_string x))
151152 >>= fun response -> Jsonrpc.string_of_response response |> return
152153 in
153153- serve_requests process
154154- (Js_top_worker_rpc.Toplevel_api_gen.sockpath)
154154+ serve_requests process Js_top_worker_rpc.Toplevel_api_gen.sockpath
155155156156let _ = start_server ()
+5-1
idl/js_top_worker_client.ml
···8989 string ->
9090 (Toplevel_api_gen.exec_result, Toplevel_api_gen.err) result Lwt.t
91919292- val compile_js : rpc -> string option -> string -> (string, Toplevel_api_gen.err) result Lwt.t
9292+ val compile_js :
9393+ rpc ->
9494+ string option ->
9595+ string ->
9696+ (string, Toplevel_api_gen.err) result Lwt.t
9397end = struct
9498 type init_libs = Toplevel_api_gen.init_libs
9599 type err = Toplevel_api_gen.err
+14-16
idl/js_top_worker_client.mli
···99 this exception. *)
10101111type rpc = Rpc.call -> Rpc.response Lwt.t
1212-(** RPC function for communicating with the worker. This is used by each
1313- RPC function declared in {!W} *)
1212+(** RPC function for communicating with the worker. This is used by each RPC
1313+ function declared in {!W} *)
14141515val start : string -> int -> (unit -> unit) -> rpc
1616(** [start url timeout timeout_fn] initialises a web worker from [url] and
1717 starts communications with it. [timeout] is the number of seconds to wait
1818- for a response from any RPC before raising an error, and [timeout_fn] is
1919- called when a timeout occurs. Returns the {!type-rpc} function used
2020- in the RPC calls. *)
1818+ for a response from any RPC before raising an error, and [timeout_fn] is
1919+ called when a timeout occurs. Returns the {!type-rpc} function used in the
2020+ RPC calls. *)
21212222module W : sig
2323 (** {2 Type declarations}
2424-2525- The following types are redeclared here for convenience. *)
2424+2525+ The following types are redeclared here for convenience. *)
26262727 type init_libs = Toplevel_api_gen.init_libs
2828 type err = Toplevel_api_gen.err
2929 type exec_result = Toplevel_api_gen.exec_result
30303131 (** {2 RPC calls}
3232-3333- The first parameter of these calls is the rpc function returned by
3434- {!val-start}. If any of these calls fails to receive a response from
3535- the worker by the timeout set in the {!val-start} call, the {!Lwt}
3636- thread will be {{!Lwt.fail}failed}.
3737- *)
3232+3333+ The first parameter of these calls is the rpc function returned by
3434+ {!val-start}. If any of these calls fails to receive a response from the
3535+ worker by the timeout set in the {!val-start} call, the {!Lwt} thread will
3636+ be {{!Lwt.fail}failed}. *)
38373938 val init : rpc -> init_libs -> (unit, err) result Lwt.t
4039 (** Initialise the toplevel. This must be called before any other API. *)
41404241 val setup : rpc -> unit -> (exec_result, err) result Lwt.t
4343- (** Start the toplevel. Return value is the initial blurb
4444- printed when starting a toplevel. Note that the toplevel
4545- must be initialised first. *)
4242+ (** Start the toplevel. Return value is the initial blurb printed when
4343+ starting a toplevel. Note that the toplevel must be initialised first. *)
46444745 val typecheck : rpc -> string -> (exec_result, err) result Lwt.t
4846 (** Typecheck a phrase using the toplevel. The toplevel must have been
+1-1
idl/js_top_worker_client_fut.ml
···8181 let compile_js rpc id s = Wraw.compile_js rpc id s |> Rpc_fut.T.get
8282 let query_errors rpc doc = Wraw.query_errors rpc doc |> Rpc_fut.T.get
8383 let exec_toplevel rpc doc = Wraw.exec_toplevel rpc doc |> Rpc_fut.T.get
8484-8484+8585 let complete_prefix rpc doc pos =
8686 Wraw.complete_prefix rpc doc pos |> Rpc_fut.T.get
8787
···11(* Kinda findlib, sorta *)
2233-43type library = {
54 name : string;
65 meta_uri : Uri.t;
76 archive_name : string option;
87 dir : string option;
98 deps : string list;
99+ children : library list;
1010 mutable loaded : bool;
1111}
12121313-let read_libraries_from_pkg_defs ~library_name meta_uri pkg_defs =
1313+let rec flatten_libs libs =
1414+ let handle_lib l =
1515+ let children = flatten_libs l.children in
1616+ l :: children
1717+ in
1818+ List.map handle_lib libs |> List.flatten
1919+2020+let preloaded =
2121+ [
2222+ "logs";
2323+ "js_top_worker-rpc";
2424+ "js_of_ocaml-compiler";
2525+ "js_of_ocaml-ppx";
2626+ "astring";
2727+ "mime_printer";
2828+ "compiler-libs.common";
2929+ "compiler-libs.toplevel";
3030+ "merlin-lib.kernel";
3131+ "merlin-lib.utils";
3232+ "merlin-lib.query_protocol";
3333+ "merlin-lib.query_commands";
3434+ "merlin-lib.ocaml_parsing";
3535+ "findlib";
3636+ "findlib.top";
3737+ "js_top_worker";
3838+ "js_of_ocaml-ppx";
3939+ "js_of_ocaml-toplevel";
4040+ "logs.browser";
4141+ "uri";
4242+ "angstrom";
4343+ "findlib";
4444+ "fpath";
4545+ ]
4646+4747+let rec read_libraries_from_pkg_defs ~library_name ~dir meta_uri pkg_expr =
1448 try
4949+ let pkg_defs = pkg_expr.Fl_metascanner.pkg_defs in
1550 let archive_filename =
1651 try Some (Fl_metascanner.lookup "archive" [ "byte" ] pkg_defs)
1752 with _ -> (
···21562257 let deps_str = Fl_metascanner.lookup "requires" [] pkg_defs in
2358 let deps = Astring.String.fields ~empty:false deps_str in
2424- let dir =
5959+ let subdir =
2560 List.find_opt (fun d -> d.Fl_metascanner.def_var = "directory") pkg_defs
6161+ |> Option.map (fun d -> d.Fl_metascanner.def_value)
2662 in
2727- let dir = Option.map (fun d -> d.Fl_metascanner.def_value) dir in
6363+ let dir =
6464+ match (dir, subdir) with
6565+ | None, None -> None
6666+ | Some d, None -> Some d
6767+ | None, Some d -> Some d
6868+ | Some d1, Some d2 -> Some (Filename.concat d1 d2)
6969+ in
2870 let archive_name =
2971 Option.bind archive_filename (fun a ->
3072 let file_name_len = String.length a in
3173 if file_name_len > 0 then Some (Filename.chop_extension a) else None)
3274 in
3333- [ { name = library_name; archive_name; dir; deps; meta_uri; loaded=false } ]
3434- with Not_found -> []
3535-7575+ let children =
7676+ List.filter_map
7777+ (fun (n, expr) ->
7878+ let library_name = library_name ^ "." ^ n in
7979+ match
8080+ read_libraries_from_pkg_defs ~library_name ~dir meta_uri expr
8181+ with
8282+ | Ok l -> Some l
8383+ | Error (`Msg m) ->
8484+ Jslib.log "Error reading sub-library: %s" m;
8585+ None)
8686+ pkg_expr.pkg_children
8787+ in
8888+ Ok
8989+ {
9090+ name = library_name;
9191+ archive_name;
9292+ dir;
9393+ deps;
9494+ meta_uri;
9595+ loaded = false;
9696+ children;
9797+ }
9898+ with Not_found -> Error (`Msg "Failed to read libraries from pkg_defs")
369937100type t = library list
38101···41104let fetch_dynamic_cmis url =
42105 match Jslib.sync_get url with
43106 | None -> Error (`Msg "Failed to fetch dynamic cmis")
4444- | Some json ->
4545- let rpc = Jsonrpc.of_string json in
4646- Rpcmarshal.unmarshal Js_top_worker_rpc.Toplevel_api_gen.typ_of_dynamic_cmis rpc
107107+ | Some json ->
108108+ let rpc = Jsonrpc.of_string json in
109109+ Rpcmarshal.unmarshal
110110+ Js_top_worker_rpc.Toplevel_api_gen.typ_of_dynamic_cmis rpc
4711148112let init findlib_index : t =
4949- let findlib_metas =
113113+ let findlib_metas =
50114 match Jslib.sync_get findlib_index with
51115 | None -> []
5252- | Some txt ->
5353- Astring.String.fields ~empty:false txt
116116+ | Some txt -> Astring.String.fields ~empty:false txt
54117 in
5555- let metas = List.filter_map (fun x ->
5656- match Jslib.sync_get x with
5757- | Some meta -> Some (x, meta)
5858- | None -> None) findlib_metas in
5959- List.flatten @@ List.filter_map (fun (x, meta) ->
6060- match Angstrom.parse_string ~consume:All Uri.Parser.uri_reference x with
6161- | Ok uri -> (
6262- Jslib.log "Parsed uri: %s" (Uri.path uri);
6363- let path = Uri.path uri in
6464- let file = Fpath.v path in
6565- let base_library_name =
6666- if Fpath.basename file = "META" then Fpath.parent file |> Fpath.basename
6767- else Fpath.get_ext file
6868- in
118118+ let metas =
119119+ List.filter_map
120120+ (fun x ->
121121+ match Jslib.sync_get x with Some meta -> Some (x, meta) | None -> None)
122122+ findlib_metas
123123+ in
124124+ List.filter_map
125125+ (fun (x, meta) ->
126126+ match Angstrom.parse_string ~consume:All Uri.Parser.uri_reference x with
127127+ | Ok uri -> (
128128+ Jslib.log "Parsed uri: %s" (Uri.path uri);
129129+ let path = Uri.path uri in
130130+ let file = Fpath.v path in
131131+ let base_library_name =
132132+ if Fpath.basename file = "META" then
133133+ Fpath.parent file |> Fpath.basename
134134+ else Fpath.get_ext file
135135+ in
691367070- let lexing = Lexing.from_string meta in
7171- try
7272- let meta = Fl_metascanner.parse_lexing lexing in
7373- let rec extract_name_and_archive ~prefix
7474- ((name, pkg_expr) : string * Fl_metascanner.pkg_expr) =
7575- let library_name = prefix ^ "." ^ name in
7676- let libraries =
7777- read_libraries_from_pkg_defs ~library_name uri pkg_expr.pkg_defs
7878- in
7979- let child_libraries =
8080- pkg_expr.pkg_children
8181- |> List.map (extract_name_and_archive ~prefix:library_name)
8282- |> List.flatten
8383- in
8484- libraries @ child_libraries
8585- in
8686- let libraries =
8787- read_libraries_from_pkg_defs ~library_name:base_library_name uri meta.pkg_defs
8888- in
8989- let libraries =
9090- libraries
9191- @ (meta.pkg_children
9292- |> List.map (extract_name_and_archive ~prefix:base_library_name)
9393- |> List.flatten) in
9494- Some libraries
9595- with _ ->
9696- Jslib.log "Failed to parse meta: %s" (Uri.path uri);
9797- None)
9898- | Error m ->
9999- Jslib.log "Failed to parse uri: %s" m; None) metas
100100-137137+ let lexing = Lexing.from_string meta in
138138+ try
139139+ let meta = Fl_metascanner.parse_lexing lexing in
140140+ let libraries =
141141+ read_libraries_from_pkg_defs ~library_name:base_library_name
142142+ ~dir:None uri meta
143143+ in
144144+ Result.to_option libraries
145145+ with _ ->
146146+ Jslib.log "Failed to parse meta: %s" (Uri.path uri);
147147+ None)
148148+ | Error m ->
149149+ Jslib.log "Failed to parse uri: %s" m;
150150+ None)
151151+ metas |> flatten_libs
101152102153let require v packages =
103103- let rec require dcss package : Js_top_worker_rpc.Toplevel_api_gen.dynamic_cmis list =
154154+ let rec require dcss package :
155155+ Js_top_worker_rpc.Toplevel_api_gen.dynamic_cmis list =
104156 match List.find (fun lib -> lib.name = package) v with
105157 | exception Not_found ->
106106- Jslib.log "Package %s not found" package;
107107- dcss
158158+ Jslib.log "Package %s not found" package;
159159+ dcss
108160 | lib ->
109109- if lib.loaded
110110- then dcss
111111- else begin
112112- let dep_dcs = List.fold_left require dcss lib.deps in
113113- let path = Uri.path lib.meta_uri in
114114- let dir = Fpath.v path |> Fpath.parent in
115115- let dcs = Fpath.(dir / dcs_filename |> to_string) in
116116- let uri = Uri.with_path lib.meta_uri dcs in
117117- match fetch_dynamic_cmis (Uri.to_string uri) with
118118- | Ok dcs ->
119119- let () = match lib.archive_name with
120120- | None -> ()
121121- | Some archive ->
122122- let dir = match lib.dir with None -> dir | Some d -> Fpath.append dir (Fpath.v d) in
123123- let archive_js = Fpath.(dir / (archive ^ ".cma.js") |> to_string) in
124124- Js_of_ocaml.Worker.import_scripts [(Uri.with_path uri archive_js |> Uri.to_string)];
125125- lib.loaded <- true
161161+ if lib.loaded then dcss
162162+ else (
163163+ Jslib.log "Loading package %s" lib.name;
164164+ Jslib.log "lib.dir: %s" (Option.value ~default:"None" lib.dir);
165165+ let dep_dcs = List.fold_left require dcss lib.deps in
166166+ let path = Fpath.(v (Uri.path lib.meta_uri) |> parent) in
167167+ let dir =
168168+ match lib.dir with None -> path | Some d -> Fpath.(path // v d)
126169 in
127127- dcs :: dep_dcs
128128- | Error (`Msg m) ->
129129- Jslib.log "Failed to unmarshal dynamic_cms from url %s: %s" (Uri.to_string uri) m;
130130- dcss
131131- end
170170+ let dcs = Fpath.(dir / dcs_filename |> to_string) in
171171+ let uri = Uri.with_path lib.meta_uri dcs in
172172+ Jslib.log "uri: %s" (Uri.to_string uri);
173173+ match fetch_dynamic_cmis (Uri.to_string uri) with
174174+ | Ok dcs ->
175175+ let () =
176176+ match lib.archive_name with
177177+ | None -> ()
178178+ | Some archive ->
179179+ let archive_js =
180180+ Fpath.(dir / (archive ^ ".cma.js") |> to_string)
181181+ in
182182+ if List.mem lib.name preloaded then ()
183183+ else
184184+ Js_of_ocaml.Worker.import_scripts
185185+ [ Uri.with_path uri archive_js |> Uri.to_string ];
186186+ lib.loaded <- true
187187+ in
188188+ Jslib.log "Finished loading package %s" lib.name;
189189+ dcs :: dep_dcs
190190+ | Error (`Msg m) ->
191191+ Jslib.log "Failed to unmarshal dynamic_cms from url %s: %s"
192192+ (Uri.to_string uri) m;
193193+ dcss)
132194 in
133195 List.fold_left require [] packages
+154-122
lib/impl.ml
···5566type captured = { stdout : string; stderr : string }
7788-98module JsooTopPpx = struct
109 open Js_of_ocaml_compiler.Stdlib
11101212- let ppx_rewriters = ref [fun _ -> Ppx_js.mapper]
1111+ let ppx_rewriters = ref [ (fun _ -> Ppx_js.mapper) ]
13121414- let () = Ast_mapper.register_function := fun _ f -> ppx_rewriters := f :: !ppx_rewriters
1313+ let () =
1414+ Ast_mapper.register_function :=
1515+ fun _ f -> ppx_rewriters := f :: !ppx_rewriters
15161617 let preprocess_structure str =
1718 let open Ast_mapper in
1818- Printf.eprintf "Rewriting...\n%!";
1919+ Printf.eprintf "Rewriting...\n%!";
1920 List.fold_right !ppx_rewriters ~init:str ~f:(fun ppx_rewriter str ->
2021 let mapper = ppx_rewriter [] in
2122 mapper.structure mapper str)
···3132 match phrase with
3233 | Ptop_def str -> Ptop_def (preprocess_structure str)
3334 | Ptop_dir _ as x -> x
3434-3535end
3636+3637module type S = sig
3738 type findlib_t
3939+3840 val capture : (unit -> 'a) -> unit -> captured * 'a
3941 val create_file : name:string -> content:string -> unit
4042 val sync_get : string -> string option
4141-4243 val import_scripts : string list -> unit
4343- val init_function : string -> (unit -> unit )
4444-4444+ val init_function : string -> unit -> unit
4545 val get_stdlib_dcs : string -> Toplevel_api_gen.dynamic_cmis list
4646-4746 val findlib_init : string -> findlib_t
4848-4947 val require : findlib_t -> string list -> Toplevel_api_gen.dynamic_cmis list
5048end
5149···148146 let execute printval ?pp_code ?highlight_location pp_answer s =
149147 let s =
150148 let l = String.length s in
151151- if String.sub s (l-2) 2 = ";;" then s else s ^ ";;" in
149149+ if String.sub s (l - 2) 2 = ";;" then s else s ^ ";;"
150150+ in
152151 let lb = Lexing.from_function (refill_lexbuf s (ref 0) pp_code) in
153152 (try
154153 while true do
···219218 let dirs = get_paths () in
220219 reset ();
221220 List.iter (fun p -> prepend_dir (Dir.create p)) dirs
222222-221221+223222 let add_dynamic_cmis dcs =
224223 let fetch filename =
225224 let url = Filename.concat dcs.Toplevel_api_gen.dcs_url filename in
···233232 (fun name ->
234233 let filename = filename_of_module name in
235234 match fetch (filename_of_module name) with
236236- | Some content ->
235235+ | Some content -> (
237236 let name = Filename.(concat path filename) in
238238- (try S.create_file ~name ~content with _ -> ())
237237+ try S.create_file ~name ~content with _ -> ())
239238 | None -> ())
240239 dcs.dcs_toplevel_modules;
241240···247246 (* Check if it's already been downloaded. This will be the
248247 case for all toplevel cmis. Also check whether we're supposed
249248 to handle this cmi *)
250250- (if Sys.file_exists fs_name then
251251- Logs.info (fun m -> m "Found: %s" fs_name));
252252- (if
253253- (not (Sys.file_exists fs_name))
254254- && List.exists
255255- (fun prefix -> String.starts_with ~prefix filename)
256256- dcs.dcs_file_prefixes
257257- then (
258258- Logs.info (fun m -> m "Fetching %s\n%!" filename);
259259- match fetch filename with
260260- | Some x ->
261261- S.create_file ~name:fs_name ~content:x;
262262- (* At this point we need to tell merlin that the dir contents
249249+ if Sys.file_exists fs_name then Logs.info (fun m -> m "Found: %s" fs_name);
250250+ if
251251+ (not (Sys.file_exists fs_name))
252252+ && List.exists
253253+ (fun prefix -> String.starts_with ~prefix filename)
254254+ dcs.dcs_file_prefixes
255255+ then (
256256+ Logs.info (fun m -> m "Fetching %s\n%!" filename);
257257+ match fetch filename with
258258+ | Some x ->
259259+ S.create_file ~name:fs_name ~content:x;
260260+ (* At this point we need to tell merlin that the dir contents
263261 have changed *)
264264- if s = "merl" then reset_dirs () else reset_dirs_comp ()
265265- | None ->
266266- Printf.eprintf "Warning: Expected to find cmi at: %s\n%!"
267267- (Filename.concat dcs.Toplevel_api_gen.dcs_url filename)));
262262+ if s = "merl" then reset_dirs () else reset_dirs_comp ()
263263+ | None ->
264264+ Printf.eprintf "Warning: Expected to find cmi at: %s\n%!"
265265+ (Filename.concat dcs.Toplevel_api_gen.dcs_url filename));
268266 old_loader ~unit_name
269267 in
270268 let furl = "file://" in
271269 let l = String.length furl in
272272- if String.length dcs.dcs_url > l && String.sub dcs.dcs_url 0 l = furl then begin
270270+ if String.length dcs.dcs_url > l && String.sub dcs.dcs_url 0 l = furl then
273271 let path = String.sub dcs.dcs_url l (String.length dcs.dcs_url - l) in
274272 Topdirs.dir_directory path
275275- end else begin
273273+ else
276274 let open Persistent_env.Persistent_signature in
277275 let old_loader = !load in
278278- load := (new_load ~s:"comp" ~old_loader);
276276+ load := new_load ~s:"comp" ~old_loader;
279277280278 let open Ocaml_typing.Persistent_env.Persistent_signature in
281279 let old_loader = !load in
282282- load := (new_load ~s:"merl" ~old_loader)
283283- end
280280+ load := new_load ~s:"merl" ~old_loader
284281285282 let init (init_libs : Toplevel_api_gen.init_libs) =
286283 try
···290287 findlib_v := Some (S.findlib_init init_libs.findlib_index);
291288292289 (match S.get_stdlib_dcs init_libs.stdlib_dcs with
293293- |[dcs] -> add_dynamic_cmis dcs
290290+ | [ dcs ] -> add_dynamic_cmis dcs
294291 | _ -> ());
295292 Clflags.no_check_prims := true;
296293 List.iter
···304301 List.iter add_dynamic_cmis init_libs.cmis.dynamic_cmis;
305302306303 S.import_scripts
307307- (List.map (fun cma -> cma.Toplevel_api_gen.url) init_libs.cmas);
304304+ (List.map (fun cma -> cma.Toplevel_api_gen.url) init_libs.cmas);
308305309306 requires := init_libs.findlib_requires;
310307 functions :=
311308 Some
312309 (List.map
313313- (fun func_name ->
314314- Logs.info (fun m -> m "Function: %s" func_name);
315315- S.init_function func_name)
316316- (List.map (fun cma -> cma.Toplevel_api_gen.fn) init_libs.cmas));
317317-(*
318318- *)
310310+ (fun func_name ->
311311+ Logs.info (fun m -> m "Function: %s" func_name);
312312+ S.init_function func_name)
313313+ (List.map (fun cma -> cma.Toplevel_api_gen.fn) init_libs.cmas));
314314+ (* *)
319315 functions := Some [];
320316 Logs.info (fun m -> m "init() finished");
321317···329325 Logs.info (fun m -> m "setup() ...");
330326331327 let o =
332332-333333- (try
328328+ try
334329 match !functions with
335330 | Some l -> setup l ()
336331 | None -> failwith "Error: toplevel has not been initialised"
337337- with
338338- | Persistent_env.Error e ->
339339- Persistent_env.report_error Format.err_formatter e;
340340- let err = Format.asprintf "%a" Persistent_env.report_error e in
341341- failwith ("Error: " ^ err)
342342- | Env.Error e ->
343343- Env.report_error Format.err_formatter e;
344344- let err = Format.asprintf "%a" Env.report_error e in
345345- failwith ("Error: " ^ err))
346346- in
347347-348348- let dcs = (match !findlib_v with
349349- | Some v ->
350350- S.require v !requires
351351- | None -> []) in
332332+ with
333333+ | Persistent_env.Error e ->
334334+ Persistent_env.report_error Format.err_formatter e;
335335+ let err = Format.asprintf "%a" Persistent_env.report_error e in
336336+ failwith ("Error: " ^ err)
337337+ | Env.Error e ->
338338+ Env.report_error Format.err_formatter e;
339339+ let err = Format.asprintf "%a" Env.report_error e in
340340+ failwith ("Error: " ^ err)
341341+ in
342342+343343+ let dcs =
344344+ match !findlib_v with Some v -> S.require v !requires | None -> []
345345+ in
352346 List.iter add_dynamic_cmis dcs;
353347354348 Logs.info (fun m -> m "setup() finished");
···439433440434 let compile_js (id : string option) prog =
441435 try
442442-443436 let l = Lexing.from_string prog in
444437 let phr = Parse.toplevel_phrase l in
445438 Typecore.reset_delayed_checks ();
···490483 cu_debugsize = 0;
491484 }
492485 in
493493-486486+494487 let fmt = Js_of_ocaml_compiler.Pretty_print.to_buffer b in
495488 (* Symtable.patch_object code reloc;
496489 Symtable.check_global_initialized reloc;
···505498 let ic = open_in "/tmp/test.cmo" in
506499 let p = Js_of_ocaml_compiler.Parse_bytecode.from_cmo cmo ic in
507500 let wrap_with_fun =
508508- match id with
509509- | Some id -> `Named id
510510- | None -> `Iife
501501+ match id with Some id -> `Named id | None -> `Iife
511502 in
512512- Js_of_ocaml_compiler.Driver.f' ~standalone:false ~wrap_with_fun ~link:`No
513513- fmt p.debug p.code;
503503+ Js_of_ocaml_compiler.Driver.f' ~standalone:false ~wrap_with_fun
504504+ ~link:`No fmt p.debug p.code;
514505 Format.(pp_print_flush std_formatter ());
515506 Format.(pp_print_flush err_formatter ());
516507 flush stdout;
···521512 with e -> IdlM.ErrM.return ("Exception: %s" ^ Printexc.to_string e)
522513523514 let handle_toplevel stripped =
524524- if String.length stripped < 2 || stripped.[0] <> '#' || stripped.[1] <> ' ' then begin
525525- Printf.eprintf "Warning, ignoring toplevel block without a leading '# '.\n";
526526- IdlM.ErrM.return { Toplevel_api_gen.script=stripped; mime_vals=[] }
527527- end else begin
515515+ if String.length stripped < 2 || stripped.[0] <> '#' || stripped.[1] <> ' '
516516+ then (
517517+ Printf.eprintf
518518+ "Warning, ignoring toplevel block without a leading '# '.\n";
519519+ IdlM.ErrM.return { Toplevel_api_gen.script = stripped; mime_vals = [] })
520520+ else
528521 let s = String.sub stripped 2 (String.length stripped - 2) in
529522 let list = Ocamltop.parse_toplevel s in
530523 let buf = Buffer.create 1024 in
531531- let mime_vals = List.fold_left (fun acc (phr, _output) ->
532532- let new_output = execute phr |> IdlM.T.get |> M.run |> Result.get_ok in
533533- Printf.bprintf buf "# %s\n" phr;
534534- let r = (Option.to_list new_output.stdout) @ (Option.to_list new_output.stderr) @ (Option.to_list new_output.caml_ppf) in
535535- let r = List.concat_map (fun l -> Astring.String.cuts ~sep:"\n" l) r in
536536- List.iter (fun x -> Printf.bprintf buf " %s\n" x) r;
537537- let mime_vals = new_output.mime_vals in
538538- acc @ mime_vals
539539- ) [] list in
524524+ let mime_vals =
525525+ List.fold_left
526526+ (fun acc (phr, _output) ->
527527+ let new_output =
528528+ execute phr |> IdlM.T.get |> M.run |> Result.get_ok
529529+ in
530530+ Printf.bprintf buf "# %s\n" phr;
531531+ let r =
532532+ Option.to_list new_output.stdout
533533+ @ Option.to_list new_output.stderr
534534+ @ Option.to_list new_output.caml_ppf
535535+ in
536536+ let r =
537537+ List.concat_map (fun l -> Astring.String.cuts ~sep:"\n" l) r
538538+ in
539539+ List.iter (fun x -> Printf.bprintf buf " %s\n" x) r;
540540+ let mime_vals = new_output.mime_vals in
541541+ acc @ mime_vals)
542542+ [] list
543543+ in
540544 let content_txt = Buffer.contents buf in
541541- let content_txt = String.sub content_txt 0 (String.length content_txt - 1) in
542542- let result = { Toplevel_api_gen.script=content_txt; mime_vals } in
545545+ let content_txt =
546546+ String.sub content_txt 0 (String.length content_txt - 1)
547547+ in
548548+ let result = { Toplevel_api_gen.script = content_txt; mime_vals } in
543549 IdlM.ErrM.return result
544544- end
545545-546546- let exec_toplevel (phrase : string) =
547547- handle_toplevel phrase
550550+551551+ let exec_toplevel (phrase : string) = handle_toplevel phrase
548552549553 let config () =
550554 let path =
···658662659663 let complete_prefix source position =
660664 let source = Merlin_kernel.Msource.make source in
661661- let map_kind : [`Value|`Constructor|`Variant|`Label|
662662- `Module|`Modtype|`Type|`MethodCall|`Keyword] -> Toplevel_api_gen.kind_ty = function
665665+ let map_kind :
666666+ [ `Value
667667+ | `Constructor
668668+ | `Variant
669669+ | `Label
670670+ | `Module
671671+ | `Modtype
672672+ | `Type
673673+ | `MethodCall
674674+ | `Keyword ] ->
675675+ Toplevel_api_gen.kind_ty = function
663676 | `Value -> Value
664677 | `Constructor -> Constructor
665678 | `Variant -> Variant
···668681 | `Modtype -> Modtype
669682 | `Type -> Type
670683 | `MethodCall -> MethodCall
671671- | `Keyword -> Keyword in
684684+ | `Keyword -> Keyword
685685+ in
672686 let position =
673687 match position with
674688 | Toplevel_api_gen.Start -> `Start
675689 | Offset x -> `Offset x
676690 | Logical (x, y) -> `Logical (x, y)
677677- | End -> `End in
691691+ | End -> `End
692692+ in
678693 match Completion.at_pos source position with
679694 | Some (from, to_, compl) ->
680695 let entries =
681681- List.map (fun (entry : Query_protocol.Compl.entry) ->
682682- {
683683- Toplevel_api_gen.name = entry.name;
684684- kind = map_kind entry.kind;
685685- desc = entry.desc;
686686- info = entry.info;
687687- deprecated = entry.deprecated;
688688- } ) compl.entries in
696696+ List.map
697697+ (fun (entry : Query_protocol.Compl.entry) ->
698698+ {
699699+ Toplevel_api_gen.name = entry.name;
700700+ kind = map_kind entry.kind;
701701+ desc = entry.desc;
702702+ info = entry.info;
703703+ deprecated = entry.deprecated;
704704+ })
705705+ compl.entries
706706+ in
689707 IdlM.ErrM.return { Toplevel_api_gen.from; to_; entries }
690708 | None ->
691709 IdlM.ErrM.return { Toplevel_api_gen.from = 0; to_ = 0; entries = [] }
···699717 let errors =
700718 wdispatch source query
701719 |> StdLabels.List.map
702702- ~f:(fun
703703- (Ocaml_parsing.Location.{ kind; main = _; sub; source } as error)
704704- ->
705705- let of_sub sub =
706706- Ocaml_parsing.Location.print_sub_msg Format.str_formatter sub;
707707- String.trim (Format.flush_str_formatter ())
708708- in
709709- let loc = Ocaml_parsing.Location.loc_of_report error in
710710- let main =
711711- Format.asprintf "@[%a@]" Ocaml_parsing.Location.print_main error
712712- |> String.trim
713713- in
714714- {
715715- Toplevel_api_gen.kind;
716716- loc;
717717- main;
718718- sub = StdLabels.List.map ~f:of_sub sub;
719719- source;
720720- })
720720+ ~f:(fun
721721+ (Ocaml_parsing.Location.{ kind; main = _; sub; source } as
722722+ error)
723723+ ->
724724+ let of_sub sub =
725725+ Ocaml_parsing.Location.print_sub_msg Format.str_formatter sub;
726726+ String.trim (Format.flush_str_formatter ())
727727+ in
728728+ let loc = Ocaml_parsing.Location.loc_of_report error in
729729+ let main =
730730+ Format.asprintf "@[%a@]" Ocaml_parsing.Location.print_main
731731+ error
732732+ |> String.trim
733733+ in
734734+ {
735735+ Toplevel_api_gen.kind;
736736+ loc;
737737+ main;
738738+ sub = StdLabels.List.map ~f:of_sub sub;
739739+ source;
740740+ })
721741 in
722742 IdlM.ErrM.return errors
723743 with e ->
···730750 | Toplevel_api_gen.Start -> `Start
731751 | Offset x -> `Offset x
732752 | Logical (x, y) -> `Logical (x, y)
733733- | End -> `End in
753753+ | End -> `End
754754+ in
734755 let source = Merlin_kernel.Msource.make source in
735756 let query = Query_protocol.Type_enclosing (None, position, None) in
736757 let enclosing = wdispatch source query in
737737- let map_index_or_string = function | `Index i -> Toplevel_api_gen.Index i | `String s -> String s in
738738- let map_tail_position = function | `No -> Toplevel_api_gen.No | `Tail_position -> Tail_position | `Tail_call -> Tail_call in
739739- let enclosing = List.map (fun (x,y,z) -> (x,map_index_or_string y,map_tail_position z)) enclosing in
758758+ let map_index_or_string = function
759759+ | `Index i -> Toplevel_api_gen.Index i
760760+ | `String s -> String s
761761+ in
762762+ let map_tail_position = function
763763+ | `No -> Toplevel_api_gen.No
764764+ | `Tail_position -> Tail_position
765765+ | `Tail_call -> Tail_call
766766+ in
767767+ let enclosing =
768768+ List.map
769769+ (fun (x, y, z) -> (x, map_index_or_string y, map_tail_position z))
770770+ enclosing
771771+ in
740772 IdlM.ErrM.return enclosing
741773end
-1
lib/jslib.ml
···1818 None)
1919 (fun b -> Some (Typed_array.String.of_arrayBuffer b))
2020 | _ -> None
2121-
+7-6
lib/ocamltop.ml
···22 if !p = String.length s then 0
33 else
44 let len' =
55- try (String.index_from s !p '\n' - !p + 1)
66- with _ -> (String.length s - !p)
55+ try String.index_from s !p '\n' - !p + 1 with _ -> String.length s - !p
76 in
87 let len'' = min len len' in
98 String.blit s !p buffer 0 len'';
···1110 len''
12111312let parse_toplevel s =
1414- let s = s in
1313+ Logs.warn (fun m -> m "Parsing toplevel phrases");
1514 let lexbuf = Lexing.from_string s in
1615 let rec loop pos =
1716 let _phr = !Toploop.parse_toplevel_phrase lexbuf in
1817 let new_pos = Lexing.lexeme_end lexbuf in
1918 let phr = String.sub s pos (new_pos - pos) in
2020- let (cont, output) = Toplexer.entry lexbuf in
1919+ let cont, is_legacy, output = Toplexer.entry lexbuf in
2020+ if is_legacy then
2121+ Logs.warn (fun m -> m "Warning: Legacy toplevel output detected");
2122 let new_pos = Lexing.lexeme_end lexbuf in
2222- if cont then (phr, output) :: loop new_pos else [(phr, output)]
2323+ if cont then (phr, output) :: loop new_pos else [ (phr, output) ]
2324 in
2424- loop 02525+ loop 0
···2121(** {6 Parsing} *)
22222323type location = int * int
2424-(** Type of a string-location. It is composed of a start and stop
2525- offsets (in bytes). *)
2424+(** Type of a string-location. It is composed of a start and stop offsets (in
2525+ bytes). *)
26262727type lines = { start : int; stop : int }
2828(** Type for a range of lines in a buffer from start to stop. *)
···57575858val parse_toplevel_phrase_default :
5959 string -> bool -> Parsetree.toplevel_phrase result
6060-(** The default parser for toplevel phrases. It uses the standard ocaml parser. *)
6060+(** The default parser for toplevel phrases. It uses the standard ocaml parser.
6161+*)
61626263val parse_default : (Lexing.lexbuf -> 'a) -> string -> bool -> 'a result
6364(** The default parser. It uses the standard ocaml parser. *)
···6768 toplevel. *)
68696970val lexbuf_of_string : bool ref -> string -> Lexing.lexbuf
7070-(** [lexbuf_of_string eof str] is the same as [Lexing.from_string
7171- str]
7272- except that if the lexer reach the end of [str] then [eof] is set to [true]. *)
7171+(** [lexbuf_of_string eof str] is the same as [Lexing.from_string str] except
7272+ that if the lexer reach the end of [str] then [eof] is set to [true]. *)
73737474(** {6 Helpers} *)
7575···7878 prints as a string. *)
79798080val get_ocaml_error_message : exn -> location * string * lines option
8181-(** [get_ocaml_error_message exn] returns the location and error
8282- message for the exception [exn] which must be an exception from
8383- the compiler. *)
8181+(** [get_ocaml_error_message exn] returns the location and error message for the
8282+ exception [exn] which must be an exception from the compiler. *)
84838584val check_phrase :
8685 Parsetree.toplevel_phrase ->
8786 (location list * string * lines option list) option
8888-(** [check_phrase phrase] checks that [phrase] can be executed
8989- without typing or compilation errors. It returns [None] if
9090- [phrase] is OK and an error message otherwise.
9191- If the result is [None] it is guaranteed that
9292- [Toploop.execute_phrase] won't raise any exception. *)
8787+(** [check_phrase phrase] checks that [phrase] can be executed without typing or
8888+ compilation errors. It returns [None] if [phrase] is OK and an error message
8989+ otherwise. If the result is [None] it is guaranteed that
9090+ [Toploop.execute_phrase] won't raise any exception. *)
93919492val collect_formatters : Buffer.t -> Format.formatter list -> (unit -> 'a) -> 'a
9593(** [collect_formatters buf pps f] executes [f] and redirect everything it
+2-8
lib/worker.ml
···11open Js_top_worker_rpc
22open Js_top_worker
33-43module Server = Toplevel_api_gen.Make (Impl.IdlM.GenServer ())
5465(* OCamlorg toplevel in a web worker
···54535554 let sync_get = Jslib.sync_get
5655 let create_file = Js_of_ocaml.Sys_js.create_file
5757-5858- let get_stdlib_dcs uri =
5959- Findlibish.fetch_dynamic_cmis uri |> Result.to_list
6060-5656+ let get_stdlib_dcs uri = Findlibish.fetch_dynamic_cmis uri |> Result.to_list
6157 let import_scripts = Js_of_ocaml.Worker.import_scripts
6262-6358 let findlib_init = Findlibish.init
64596560 let require v = function
···6964 let init_function func_name =
7065 let open Js_of_ocaml in
7166 let func = Js.Unsafe.js_expr func_name in
7272- fun () ->
7373- Js.Unsafe.fun_call func [| Js.Unsafe.inject Dom_html.window |]
6767+ fun () -> Js.Unsafe.fun_call func [| Js.Unsafe.inject Dom_html.window |]
7468end
75697670module M = Impl.Make (S)