···8989 string ->
9090 (Toplevel_api_gen.exec_result, Toplevel_api_gen.err) result Lwt.t
91919292- val compile_js : rpc -> string -> string -> (string, Toplevel_api_gen.err) result Lwt.t
9292+ val compile_js : rpc -> string option -> string -> (string, Toplevel_api_gen.err) result Lwt.t
9393end = struct
9494 type init_libs = Toplevel_api_gen.init_libs
9595 type err = Toplevel_api_gen.err
+1-1
idl/js_top_worker_client.mli
···5252 (** Execute a phrase using the toplevel. The toplevel must have been
5353 initialised first. *)
54545555- val compile_js : rpc -> string -> string -> (string, err) result Lwt.t
5555+ val compile_js : rpc -> string option -> string -> (string, err) result Lwt.t
5656end
···5566type captured = { stdout : string; stderr : string }
7788+99+module JsooTopPpx = struct
1010+ open Js_of_ocaml_compiler.Stdlib
1111+1212+ let ppx_rewriters = ref [fun _ -> Logs.info (fun m -> m "Rewriting..."); Ppx_js.mapper]
1313+1414+ let () = Ast_mapper.register_function := fun _ f -> ppx_rewriters := f :: !ppx_rewriters
1515+1616+ let preprocess_structure str =
1717+ let open Ast_mapper in
1818+ List.fold_right !ppx_rewriters ~init:str ~f:(fun ppx_rewriter str ->
1919+ let mapper = ppx_rewriter [] in
2020+ mapper.structure mapper str)
2121+2222+ let preprocess_signature str =
2323+ let open Ast_mapper in
2424+ List.fold_right !ppx_rewriters ~init:str ~f:(fun ppx_rewriter str ->
2525+ let mapper = ppx_rewriter [] in
2626+ mapper.signature mapper str)
2727+2828+ let preprocess_phrase phrase =
2929+ let open Parsetree in
3030+ match phrase with
3131+ | Ptop_def str -> Ptop_def (preprocess_structure str)
3232+ | Ptop_dir _ as x -> x
3333+3434+end
835module type S = sig
936 val capture : (unit -> 'a) -> unit -> captured * 'a
1037 val create_file : name:string -> content:string -> unit
···5986 let o, () = exec' s in
6087 combine o
6188 in
6262- Logs.info (fun m -> m "Setting up toplevel");
6389 Sys.interactive := false;
6464- Logs.info (fun m -> m "Finished this bit 1");
65906691 Toploop.input_name := "//toplevel//";
6767- Logs.info (fun m -> m "Finished this bit 2");
6892 let path =
6993 match !path with Some p -> p | None -> failwith "Path not set"
7094 in
71957296 Topdirs.dir_directory path;
73977474- List.iter Topdirs.dir_directory [
7575- "/Users/jonathanludlam/devel/learno/_opam/lib/note";
7676- "/Users/jonathanludlam/devel/learno/_opam/lib/js_of_ocaml-compiler/runtime";
7777-"/Users/jonathanludlam/devel/learno/_opam/lib/brr";
7878-"/Users/jonathanludlam/devel/learno/_opam/lib/note/brr";
7979-"/Users/jonathanludlam/devel/learno/codemirror3/odoc_notebook/_build/default/mime_printer/.mime_printer.objs/byte"
8080- ];
8181-8282- Logs.info (fun m -> m "Finished this bit 3");
8398 Toploop.initialize_toplevel_env ();
8484- Logs.info (fun m -> m "Finished this bit 4");
859986100 List.iter (fun f -> f ()) functions;
87101 exec' "open Stdlib";
···184198 reset ();
185199 List.iter (fun p -> prepend_dir (Dir.create p)) dirs
186200201201+ let reset_dirs_comp () =
202202+ let open Load_path in
203203+ let dirs = get_paths () in
204204+ reset ();
205205+ List.iter (fun p -> prepend_dir (Dir.create p)) dirs
206206+187207 let add_dynamic_cmis dcs =
188188- let open Ocaml_typing.Persistent_env.Persistent_signature in
189189- let old_loader = !load in
190190-191208 let fetch filename =
192209 let url = Filename.concat dcs.Toplevel_api_gen.dcs_url filename in
193210 S.sync_get url
···206223 | None -> ())
207224 dcs.dcs_toplevel_modules;
208225209209- let new_load ~unit_name =
226226+ let new_load ~s ~old_loader ~unit_name =
227227+ Logs.info (fun m -> m "%s Loading: %s" s unit_name);
210228 let filename = filename_of_module unit_name in
211229212230 let fs_name = Filename.(concat path filename) in
213231 (* Check if it's already been downloaded. This will be the
214232 case for all toplevel cmis. Also check whether we're supposed
215233 to handle this cmi *)
234234+ (if Sys.file_exists fs_name then
235235+ Logs.info (fun m -> m "Found: %s" fs_name));
216236 (if
217237 (not (Sys.file_exists fs_name))
218238 && List.exists
219239 (fun prefix -> String.starts_with ~prefix filename)
220240 dcs.dcs_file_prefixes
221221- then
241241+ then (
242242+ Logs.info (fun m -> m "Fetching %s\n%!" filename);
222243 match fetch filename with
223244 | Some x ->
224245 S.create_file ~name:fs_name ~content:x;
225246 (* At this point we need to tell merlin that the dir contents
226247 have changed *)
227227- reset_dirs ()
248248+ if s = "merl" then reset_dirs () else reset_dirs_comp ()
228249 | None ->
229250 Printf.eprintf "Warning: Expected to find cmi at: %s\n%!"
230230- (Filename.concat dcs.Toplevel_api_gen.dcs_url filename));
251251+ (Filename.concat dcs.Toplevel_api_gen.dcs_url filename)));
231252 old_loader ~unit_name
232253 in
233233- load := new_load
254254+ let furl = "file://" in
255255+ let l = String.length furl in
256256+ if String.length dcs.dcs_url > l && String.sub dcs.dcs_url 0 l = furl then begin
257257+ let path = String.sub dcs.dcs_url l (String.length dcs.dcs_url - l) in
258258+ Topdirs.dir_directory path
259259+ end else begin
260260+ let open Persistent_env.Persistent_signature in
261261+ let old_loader = !load in
262262+ load := (new_load ~s:"comp" ~old_loader);
263263+264264+ let open Ocaml_typing.Persistent_env.Persistent_signature in
265265+ let old_loader = !load in
266266+ load := (new_load ~s:"merl" ~old_loader)
267267+ end
234268235269 let init (init_libs : Toplevel_api_gen.init_libs) =
236270 try
···246280 let name = Filename.(concat init_libs.path filename) in
247281 S.create_file ~name ~content:sc_content)
248282 init_libs.cmis.static_cmis;
249249- Option.iter add_dynamic_cmis init_libs.cmis.dynamic_cmis;
283283+ List.iter add_dynamic_cmis init_libs.cmis.dynamic_cmis;
250284251285 (*import_scripts
252286 (List.map (fun cma -> cma.Toplevel_api_gen.url) init_libs.cmas);
···360394 in
361395 Array.of_list (split 0 0)
362396363363- let compile_js id prog =
364364- let open Js_of_ocaml_compiler in
365365- let open Js_of_ocaml_compiler.Stdlib in
397397+ let compile_js (id : string option) prog =
366398 try
367367- let str = Printf.sprintf "let _ = Mime_printer.id := \"%s\"\n%s" id prog in
368368- let l = Lexing.from_string str in
399399+400400+ let l = Lexing.from_string prog in
369401 let phr = Parse.toplevel_phrase l in
370402 Typecore.reset_delayed_checks ();
371403 Env.reset_cache_toplevel ();
372404 let oldenv = !Toploop.toplevel_env in
373405 (* let oldenv = Compmisc.initial_env() in *)
406406+ let phr = JsooTopPpx.preprocess_phrase phr in
374407 match phr with
375408 | Ptop_def sstr ->
409409+ Logs.info (fun m -> m "Typing...");
376410 let str, sg, sn, _shape, newenv =
377411 try Typemod.type_toplevel_phrase oldenv sstr
378412 with Env.Error e ->
379413 Env.report_error Format.err_formatter e;
380380- exit 1
414414+ (* exit 1 *)
415415+ let err = Format.asprintf "%a" Env.report_error e in
416416+ failwith ("Error: " ^ err)
381417 in
418418+ Logs.info (fun m -> m "simplify...");
382419 let sg' = Typemod.Signature_names.simplify newenv sn sg in
383420 ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg');
384421 Typecore.force_delayed_checks ();
422422+ Logs.info (fun m -> m "Translmod...");
385423 let lam = Translmod.transl_toplevel_definition str in
424424+ Logs.info (fun m -> m "Simplif...");
386425 let slam = Simplif.simplify_lambda lam in
426426+ Logs.info (fun m -> m "Bytegen...");
387427 let init_code, fun_code = Bytegen.compile_phrase slam in
428428+ Logs.info (fun m -> m "Emitcode...");
388429 let code, reloc, _events = Emitcode.to_memory init_code fun_code in
389430 Toploop.toplevel_env := newenv;
390431 (* let prims = split_primitives (Symtable.data_primitive_names ()) in *)
···404445 cu_debugsize = 0;
405446 }
406447 in
407407- let fmt = Pretty_print.to_buffer b in
448448+449449+ let fmt = Js_of_ocaml_compiler.Pretty_print.to_buffer b in
408450 (* Symtable.patch_object code reloc;
409451 Symtable.check_global_initialized reloc;
410452 Symtable.update_global_table(); *)
···413455414456 (* let code = String.init (Misc.LongString.length code) ~f:(fun i -> Misc.LongString.get code i) in *)
415457 close_out oc;
416416- Driver.configure fmt;
458458+ (* Js_of_ocaml_compiler.Config.Flag.enable "pretty"; *)
459459+ Js_of_ocaml_compiler.Driver.configure fmt;
417460 let ic = open_in "/tmp/test.cmo" in
418418- let p = Parse_bytecode.from_cmo cmo ic in
419419- Driver.f' ~standalone:false ~wrap_with_fun:(`Named id) ~linkall:false
461461+ let p = Js_of_ocaml_compiler.Parse_bytecode.from_cmo cmo ic in
462462+ let wrap_with_fun =
463463+ match id with
464464+ | Some id -> `Named id
465465+ | None -> `Iife
466466+ in
467467+ Js_of_ocaml_compiler.Driver.f' ~standalone:false ~wrap_with_fun ~linkall:false
420468 fmt p.debug p.code;
421469 Format.(pp_print_flush std_formatter ());
422470 Format.(pp_print_flush err_formatter ());
···539587540588 let complete_prefix source position =
541589 let source = Merlin_kernel.Msource.make source in
590590+ let map_kind : [`Value|`Constructor|`Variant|`Label|
591591+ `Module|`Modtype|`Type|`MethodCall|`Keyword] -> Toplevel_api_gen.kind_ty = function
592592+ | `Value -> Value
593593+ | `Constructor -> Constructor
594594+ | `Variant -> Variant
595595+ | `Label -> Label
596596+ | `Module -> Module
597597+ | `Modtype -> Modtype
598598+ | `Type -> Type
599599+ | `MethodCall -> MethodCall
600600+ | `Keyword -> Keyword in
601601+ let position =
602602+ match position with
603603+ | Toplevel_api_gen.Start -> `Start
604604+ | Offset x -> `Offset x
605605+ | Logical (x, y) -> `Logical (x, y)
606606+ | End -> `End in
542607 match Completion.at_pos source position with
543608 | Some (from, to_, compl) ->
544544- let entries = compl.entries in
609609+ let entries =
610610+ List.map (fun (entry : Query_protocol.Compl.entry) ->
611611+ {
612612+ Toplevel_api_gen.name = entry.name;
613613+ kind = map_kind entry.kind;
614614+ desc = entry.desc;
615615+ info = entry.info;
616616+ deprecated = entry.deprecated;
617617+ } ) compl.entries in
545618 IdlM.ErrM.return { Toplevel_api_gen.from; to_; entries }
546619 | None ->
547620 IdlM.ErrM.return { Toplevel_api_gen.from = 0; to_ = 0; entries = [] }
···577650 IdlM.ErrM.return errors
578651579652 let type_enclosing source position =
653653+ let position =
654654+ match position with
655655+ | Toplevel_api_gen.Start -> `Start
656656+ | Offset x -> `Offset x
657657+ | Logical (x, y) -> `Logical (x, y)
658658+ | End -> `End in
580659 let source = Merlin_kernel.Msource.make source in
581660 let query = Query_protocol.Type_enclosing (None, position, None) in
582661 let enclosing = wdispatch source query in
662662+ let map_index_or_string = function | `Index i -> Toplevel_api_gen.Index i | `String s -> String s in
663663+ let map_tail_position = function | `No -> Toplevel_api_gen.No | `Tail_position -> Tail_position | `Tail_call -> Tail_call in
664664+ let enclosing = List.map (fun (x,y,z) -> (x,map_index_or_string y,map_tail_position z)) enclosing in
583665 IdlM.ErrM.return enclosing
584666end