···11+open Js_top_worker_rpc
22+module M = Idl.IdM (* Server is synchronous *)
33+module IdlM = Idl.Make (M)
44+module Client = Toplevel_api_gen.Make (IdlM.GenClient ())
55+module Cmds = Toplevel_api_gen.Make (Cmdlinergen.Gen ())
66+77+(* Use a binary 16-byte length to frame RPC messages *)
88+let binary_rpc path (call : Rpc.call) : Rpc.response =
99+ let sockaddr = Unix.ADDR_UNIX path in
1010+ let s = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in
1111+ Unix.connect s sockaddr;
1212+ let ic = Unix.in_channel_of_descr s in
1313+ let oc = Unix.out_channel_of_descr s in
1414+ let msg_buf = Jsonrpc.string_of_call call in
1515+ let len = Printf.sprintf "%016d" (String.length msg_buf) in
1616+ output_string oc len;
1717+ output_string oc msg_buf;
1818+ flush oc;
1919+ let len_buf = Bytes.make 16 '\000' in
2020+ really_input ic len_buf 0 16;
2121+ let len = int_of_string (Bytes.unsafe_to_string len_buf) in
2222+ let msg_buf = Bytes.make len '\000' in
2323+ really_input ic msg_buf 0 len;
2424+ let (response : Rpc.response) =
2525+ Jsonrpc.response_of_string (Bytes.unsafe_to_string msg_buf)
2626+ in
2727+ response
2828+(*
2929+ let server_cmd =
3030+ let doc = "Start the server" in
3131+ Cmdliner.(Cmd.v
3232+ (Cmd.info "server" ~doc )
3333+ (Term.(const Example2_server.start_server $ const ())))
3434+*)
3535+3636+let cli () =
3737+ let default =
3838+ Cmdliner.Term.(ret (const (fun _ -> `Help (`Pager, None)) $ const ()))
3939+ in
4040+ let info = Cmdliner.Cmd.info "cli" ~version:"1.6.1" ~doc:"a cli for an API" in
4141+ let rpc = binary_rpc Toplevel_api_gen.sockpath in
4242+ let cmds =
4343+ (* server_cmd :: *)
4444+ List.map
4545+ (fun t ->
4646+ let term, info = t rpc in
4747+ Cmdliner.(Cmd.v info Term.(term $ const ())))
4848+ (Cmds.implementation ())
4949+ in
5050+ let cmd = Cmdliner.Cmd.group ~default info cmds in
5151+ exit (Cmdliner.Cmd.eval cmd)
5252+5353+let () = cli ()
+127
example/unix_worker.ml
···11+(* Unix worker *)
22+open Js_top_worker
33+open Impl
44+55+let capture f () =
66+ let stdout_backup = Unix.dup ~cloexec:true Unix.stdout in
77+ let stderr_backup = Unix.dup ~cloexec:true Unix.stderr in
88+ let filename_out = Filename.temp_file "ocaml-mdx-" ".stdout" in
99+ let filename_err = Filename.temp_file "ocaml-mdx-" ".stderr" in
1010+ let fd_out =
1111+ Unix.openfile filename_out
1212+ Unix.[ O_WRONLY; O_CREAT; O_TRUNC; O_CLOEXEC ]
1313+ 0o600
1414+ in
1515+ let fd_err =
1616+ Unix.openfile filename_err
1717+ Unix.[ O_WRONLY; O_CREAT; O_TRUNC; O_CLOEXEC ]
1818+ 0o600
1919+ in
2020+ Unix.dup2 ~cloexec:false fd_out Unix.stdout;
2121+ Unix.dup2 ~cloexec:false fd_err Unix.stderr;
2222+ let ic_out = open_in filename_out in
2323+ let ic_err = open_in filename_err in
2424+ let capture oc ic fd buf =
2525+ flush oc;
2626+ let len = Unix.lseek fd 0 Unix.SEEK_CUR in
2727+ Buffer.add_channel buf ic len
2828+ in
2929+ Fun.protect
3030+ (fun () ->
3131+ let x = f () in
3232+ let buf_out = Buffer.create 1024 in
3333+ let buf_err = Buffer.create 1024 in
3434+ capture stdout ic_out fd_out buf_out;
3535+ capture stderr ic_err fd_err buf_err;
3636+ ( {
3737+ Impl.stdout = Buffer.contents buf_out;
3838+ stderr = Buffer.contents buf_err;
3939+ },
4040+ x ))
4141+ ~finally:(fun () ->
4242+ close_in_noerr ic_out;
4343+ close_in_noerr ic_out;
4444+ Unix.close fd_out;
4545+ Unix.close fd_err;
4646+ Unix.dup2 ~cloexec:false stdout_backup Unix.stdout;
4747+ Unix.dup2 ~cloexec:false stderr_backup Unix.stderr;
4848+ Unix.close stdout_backup;
4949+ Unix.close stderr_backup;
5050+ Sys.remove filename_out;
5151+ Sys.remove filename_err)
5252+5353+let binary_handler process s =
5454+ let ic = Unix.in_channel_of_descr s in
5555+ let oc = Unix.out_channel_of_descr s in
5656+ (* Read a 16 byte length encoded as a string *)
5757+ let len_buf = Bytes.make 16 '\000' in
5858+ really_input ic len_buf 0 (Bytes.length len_buf);
5959+ let len = int_of_string (Bytes.unsafe_to_string len_buf) in
6060+ let msg_buf = Bytes.make len '\000' in
6161+ really_input ic msg_buf 0 (Bytes.length msg_buf);
6262+ let ( >>= ) = M.bind in
6363+ process msg_buf >>= fun result ->
6464+ let len_buf = Printf.sprintf "%016d" (String.length result) in
6565+ output_string oc len_buf;
6666+ output_string oc result;
6767+ flush oc;
6868+ M.return ()
6969+7070+let mkdir_rec dir perm =
7171+ let rec p_mkdir dir =
7272+ let p_name = Filename.dirname dir in
7373+ if p_name <> "/" && p_name <> "." then p_mkdir p_name;
7474+ try Unix.mkdir dir perm with Unix.Unix_error (Unix.EEXIST, _, _) -> ()
7575+ in
7676+ p_mkdir dir
7777+7878+let serve_requests rpcfn path =
7979+ (try Unix.unlink path with Unix.Unix_error (Unix.ENOENT, _, _) -> ());
8080+ mkdir_rec (Filename.dirname path) 0o0755;
8181+ let sock = Unix.socket Unix.PF_UNIX Unix.SOCK_STREAM 0 in
8282+ Unix.bind sock (Unix.ADDR_UNIX path);
8383+ Unix.listen sock 5;
8484+ while true do
8585+ let this_connection, _ = Unix.accept sock in
8686+ Fun.protect
8787+ ~finally:(fun () -> Unix.close this_connection)
8888+ (fun () ->
8989+ (* Here I am calling M.run to make sure that I am running the process,
9090+ this is not much of a problem with IdM or ExnM, but in general you
9191+ should ensure that the computation is started by a runner. *)
9292+ binary_handler rpcfn this_connection |> M.run)
9393+ done
9494+9595+module Server = Js_top_worker_rpc.Toplevel_api_gen.Make (Impl.IdlM.GenServer ())
9696+9797+module S : Impl.S = struct
9898+ let capture = capture
9999+ let sync_get _ = None
100100+ let create_file ~name:_ ~content:_ = failwith "Not implemented"
101101+end
102102+103103+module U = Impl.Make (S)
104104+105105+let start_server () =
106106+ let open U in
107107+ Logs.set_reporter (Logs_fmt.reporter ());
108108+ Logs.set_level (Some Logs.Info);
109109+ let pid = Unix.getpid () in
110110+ Server.exec execute;
111111+ Server.setup setup;
112112+ Server.init init;
113113+ Server.typecheck typecheck_phrase;
114114+ Server.complete_prefix complete_prefix;
115115+ Server.query_errors query_errors;
116116+ Server.type_enclosing type_enclosing;
117117+ Server.compile_js compile_js;
118118+ let rpc_fn = IdlM.server Server.implementation in
119119+ let process x =
120120+ let open M in
121121+ rpc_fn (Jsonrpc.call_of_string (Bytes.unsafe_to_string x))
122122+ >>= fun response -> Jsonrpc.string_of_response response |> return
123123+ in
124124+ serve_requests process
125125+ (Js_top_worker_rpc.Toplevel_api_gen.sockpath ^ string_of_int pid)
126126+127127+let _ = start_server ()
···11+(*
22+ * Copyright (c) 2006-2009 Citrix Systems Inc.
33+ * Copyright (c) 2006-2014 Thomas Gazagnaire <thomas@gazagnaire.org>
44+ *
55+ * Permission to use, copy, modify, and distribute this software for any
66+ * purpose with or without fee is hereby granted, provided that the above
77+ * copyright notice and this permission notice appear in all copies.
88+ *
99+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1010+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1111+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1212+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1313+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1414+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1515+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1616+ *)
1717+1818+open Rpc
1919+2020+module Yojson_private = struct
2121+ include Yojson.Safe
2222+2323+ let from_string ?(strict = true) ?buf ?fname ?lnum s =
2424+ let open Yojson in
2525+ try
2626+ let lexbuf = Lexing.from_string s in
2727+ let v = init_lexer ?buf ?fname ?lnum () in
2828+ if strict then from_lexbuf v lexbuf else from_lexbuf v ~stream:true lexbuf
2929+ with End_of_input -> json_error "Blank input data"
3030+end
3131+3232+module Y = Yojson_private
3333+module U = Yojson.Basic.Util
3434+3535+type version = V1 | V2
3636+3737+let rec rpc_to_json t =
3838+ match t with
3939+ | Int i -> `Intlit (Int64.to_string i)
4040+ | Int32 i -> `Int (Int32.to_int i)
4141+ | Bool b -> `Bool b
4242+ | Float r -> `Float r
4343+ | String s -> `String s
4444+ | DateTime d -> `String d
4545+ | Base64 b -> `String b
4646+ | Null -> `Null
4747+ | Enum a -> `List (Rpcmarshal.tailrec_map rpc_to_json a)
4848+ | Dict a ->
4949+ `Assoc (Rpcmarshal.tailrec_map (fun (k, v) -> (k, rpc_to_json v)) a)
5050+5151+exception JsonToRpcError of Y.t
5252+5353+let rec json_to_rpc t =
5454+ match t with
5555+ | `Intlit i -> Int (Int64.of_string i)
5656+ | `Int i -> Int (Int64.of_int i)
5757+ | `Bool b -> Bool b
5858+ | `Float r -> Float r
5959+ | `String s -> (* TODO: check if it is a DateTime *) String s
6060+ (* | DateTime d -> `String d *)
6161+ (* | Base64 b -> `String b *)
6262+ | `Null -> Null
6363+ | `List a -> Enum (Rpcmarshal.tailrec_map json_to_rpc a)
6464+ | `Assoc a ->
6565+ Dict (Rpcmarshal.tailrec_map (fun (k, v) -> (k, json_to_rpc v)) a)
6666+ | unsupported -> raise (JsonToRpcError unsupported)
6767+6868+let to_fct t f = rpc_to_json t |> Y.to_string |> f
6969+let to_buffer t buf = to_fct t (fun s -> Buffer.add_string buf s)
7070+let to_string t = rpc_to_json t |> Y.to_string
7171+7272+let to_a ~empty ~append t =
7373+ let buf = empty () in
7474+ to_fct t (fun s -> append buf s);
7575+ buf
7676+7777+let new_id =
7878+ let count = ref 0L in
7979+ fun () ->
8080+ count := Int64.add 1L !count;
8181+ !count
8282+8383+let string_of_call ?(version = V1) call =
8484+ let json =
8585+ match version with
8686+ | V1 -> [ ("method", String call.name); ("params", Enum call.params) ]
8787+ | V2 ->
8888+ let params =
8989+ match call.params with [ Dict x ] -> Dict x | _ -> Enum call.params
9090+ in
9191+ [
9292+ ("jsonrpc", String "2.0");
9393+ ("method", String call.name);
9494+ ("params", params);
9595+ ]
9696+ in
9797+ let json =
9898+ if not call.is_notification then json @ [ ("id", Int (new_id ())) ]
9999+ else json
100100+ in
101101+ to_string (Dict json)
102102+103103+let json_of_response ?(id = Int 0L) version response =
104104+ if response.Rpc.success then
105105+ match version with
106106+ | V1 ->
107107+ Dict [ ("result", response.Rpc.contents); ("error", Null); ("id", id) ]
108108+ | V2 ->
109109+ Dict
110110+ [
111111+ ("jsonrpc", String "2.0");
112112+ ("result", response.Rpc.contents);
113113+ ("id", id);
114114+ ]
115115+ else
116116+ match version with
117117+ | V1 ->
118118+ Dict [ ("result", Null); ("error", response.Rpc.contents); ("id", id) ]
119119+ | V2 ->
120120+ Dict
121121+ [
122122+ ("jsonrpc", String "2.0");
123123+ ("error", response.Rpc.contents);
124124+ ("id", id);
125125+ ]
126126+127127+let json_of_error_object ?(data = None) code message =
128128+ let data_json = match data with Some d -> [ ("data", d) ] | None -> [] in
129129+ Dict ([ ("code", Int code); ("message", String message) ] @ data_json)
130130+131131+let string_of_response ?(id = Int 0L) ?(version = V1) response =
132132+ let json = json_of_response ~id version response in
133133+ to_string json
134134+135135+let a_of_response ?(id = Int 0L) ?(version = V1) ~empty ~append response =
136136+ let json = json_of_response ~id version response in
137137+ to_a ~empty ~append json
138138+139139+let of_string ?(strict = true) s = s |> Y.from_string ~strict |> json_to_rpc
140140+141141+let of_a ~next_char b =
142142+ let buf = Buffer.create 2048 in
143143+ let rec acc () =
144144+ match next_char b with
145145+ | Some c ->
146146+ Buffer.add_char buf c;
147147+ acc ()
148148+ | None -> ()
149149+ in
150150+ acc ();
151151+ Buffer.contents buf |> of_string
152152+153153+let get' name dict = try Some (List.assoc name dict) with Not_found -> None
154154+155155+exception Malformed_method_request of string
156156+exception Malformed_method_response of string
157157+exception Missing_field of string
158158+159159+let get name dict =
160160+ match get' name dict with
161161+ | None ->
162162+ if Rpc.get_debug () then
163163+ Printf.eprintf "%s was not found in the dictionary\n" name;
164164+ raise (Missing_field name)
165165+ | Some v -> v
166166+167167+let version_id_and_call_of_string_option str =
168168+ try
169169+ match of_string str with
170170+ | Dict d ->
171171+ let name =
172172+ match get "method" d with
173173+ | String s -> s
174174+ | _ ->
175175+ raise
176176+ (Malformed_method_request
177177+ "Invalid field 'method' in request body")
178178+ in
179179+ let version =
180180+ match get' "jsonrpc" d with
181181+ | None -> V1
182182+ | Some (String "2.0") -> V2
183183+ | _ ->
184184+ raise
185185+ (Malformed_method_request
186186+ "Invalid field 'jsonrpc' in request body")
187187+ in
188188+ let params =
189189+ match version with
190190+ | V1 -> (
191191+ match get "params" d with
192192+ | Enum l -> l
193193+ | _ ->
194194+ raise
195195+ (Malformed_method_request
196196+ "Invalid field 'params' in request body"))
197197+ | V2 -> (
198198+ match get' "params" d with
199199+ | None | Some Null -> []
200200+ | Some (Enum l) -> l
201201+ | Some (Dict l) -> [ Dict l ]
202202+ | _ ->
203203+ raise
204204+ (Malformed_method_request
205205+ "Invalid field 'params' in request body"))
206206+ in
207207+ let id =
208208+ match get' "id" d with
209209+ | None | Some Null -> None (* is a notification *)
210210+ | Some (Int a) -> Some (Int a)
211211+ | Some (String a) -> Some (String a)
212212+ | Some _ ->
213213+ raise
214214+ (Malformed_method_request "Invalid field 'id' in request body")
215215+ in
216216+ let c = call name params in
217217+ (version, id, { c with is_notification = id == None })
218218+ | _ -> raise (Malformed_method_request "Invalid request body")
219219+ with
220220+ | Missing_field field ->
221221+ raise
222222+ (Malformed_method_request
223223+ (Printf.sprintf "Required field %s is missing" field))
224224+ | JsonToRpcError json ->
225225+ raise
226226+ (Malformed_method_request
227227+ (Printf.sprintf "Unable to parse %s" (Y.to_string json)))
228228+229229+let version_id_and_call_of_string s =
230230+ let version, id_, call = version_id_and_call_of_string_option s in
231231+ match id_ with
232232+ | Some id -> (version, id, call)
233233+ | None ->
234234+ raise (Malformed_method_request "Invalid field 'id' in request body")
235235+236236+let call_of_string str =
237237+ let _, _, call = version_id_and_call_of_string str in
238238+ call
239239+240240+(* This functions parses the json and tries to extract a valid jsonrpc response
241241+ * (See http://www.jsonrpc.org/ for the exact specs). *)
242242+let get_response extractor str =
243243+ try
244244+ match extractor str with
245245+ | Dict d -> (
246246+ let _ =
247247+ match get "id" d with
248248+ | Int _ as x -> x
249249+ | String _ as y -> y
250250+ | _ -> raise (Malformed_method_response "id")
251251+ in
252252+ match get' "jsonrpc" d with
253253+ | None -> (
254254+ let result = get "result" d in
255255+ let error = get "error" d in
256256+ match (result, error) with
257257+ | v, Null -> success v
258258+ | Null, v -> failure v
259259+ | x, y ->
260260+ raise
261261+ (Malformed_method_response
262262+ (Printf.sprintf "<result=%s><error=%s>" (Rpc.to_string x)
263263+ (Rpc.to_string y))))
264264+ | Some (String "2.0") -> (
265265+ let result = get' "result" d in
266266+ let error = get' "error" d in
267267+ match (result, error) with
268268+ | Some v, None -> success v
269269+ | None, Some v -> (
270270+ match v with
271271+ | Dict err ->
272272+ let (_ : int64) =
273273+ match get "code" err with
274274+ | Int i -> i
275275+ | _ -> raise (Malformed_method_response "Error code")
276276+ in
277277+ let _ =
278278+ match get "message" err with
279279+ | String s -> s
280280+ | _ -> raise (Malformed_method_response "Error message")
281281+ in
282282+ failure v
283283+ | _ -> raise (Malformed_method_response "Error object"))
284284+ | Some x, Some y ->
285285+ raise
286286+ (Malformed_method_response
287287+ (Printf.sprintf "<result=%s><error=%s>" (Rpc.to_string x)
288288+ (Rpc.to_string y)))
289289+ | None, None ->
290290+ raise
291291+ (Malformed_method_response
292292+ (Printf.sprintf "neither <result> nor <error> was found")))
293293+ | _ -> raise (Malformed_method_response "jsonrpc"))
294294+ | rpc ->
295295+ raise
296296+ (Malformed_method_response
297297+ (Printf.sprintf "<response_of_stream(%s)>" (to_string rpc)))
298298+ with
299299+ | Missing_field field ->
300300+ raise
301301+ (Malformed_method_response (Printf.sprintf "<%s was not found>" field))
302302+ | JsonToRpcError json ->
303303+ raise
304304+ (Malformed_method_response
305305+ (Printf.sprintf "<unable to parse %s>" (Y.to_string json)))
306306+307307+let response_of_string ?(strict = true) str =
308308+ get_response (of_string ~strict) str
309309+310310+let response_of_in_channel channel =
311311+ let of_channel s = s |> Y.from_channel |> json_to_rpc in
312312+ get_response of_channel channel
···20202121exception Timeout
22222323-let log s = Js_of_ocaml.Firebug.console##log (Js_of_ocaml.Js.string s)
2323+(* let log s = Js_of_ocaml.Firebug.console##log (Js_of_ocaml.Js.string s) *)
24242525let demux context msg =
2626 Lwt.async (fun () ->
···2929 | Some (mv, outstanding_execution) ->
3030 Brr.G.stop_timer outstanding_execution;
3131 let msg : string = Message.Ev.data (Brr.Ev.as_type msg) in
3232- log (Printf.sprintf "Client received: %s" msg);
3232+ (* log (Printf.sprintf "Client received: %s" msg); *)
3333 Lwt_mvar.put mv (Ok (Jsonrpc.response_of_string msg)))
34343535let rpc : context -> Rpc.call -> Rpc.response Lwt.t =
3636 fun context call ->
3737 let open Lwt in
3838 let jv = Jsonrpc.string_of_call call in
3939- log (Printf.sprintf "Client sending: %s" jv);
3939+ (* log (Printf.sprintf "Client sending: %s" jv); *)
4040 let mv = Lwt_mvar.create_empty () in
4141 let outstanding_execution =
4242 Brr.G.set_timeout ~ms:context.timeout (fun () ->
···6868 type init_libs = Toplevel_api_gen.init_libs
6969 type err = Toplevel_api_gen.err
7070 type exec_result = Toplevel_api_gen.exec_result
7171- type completion_result = Toplevel_api_gen.completion_result
72717372 val init :
7473 rpc ->
···9089 string ->
9190 (Toplevel_api_gen.exec_result, Toplevel_api_gen.err) result Lwt.t
92919393- val complete :
9494- rpc ->
9595- string ->
9696- (Toplevel_api_gen.completion_result, Toplevel_api_gen.err) result Lwt.t
9292+ val compile_js : rpc -> string -> string -> (string, Toplevel_api_gen.err) result Lwt.t
9793end = struct
9894 type init_libs = Toplevel_api_gen.init_libs
9995 type err = Toplevel_api_gen.err
10096 type exec_result = Toplevel_api_gen.exec_result
101101- type completion_result = Toplevel_api_gen.completion_result
1029710398 let init rpc a = Wraw.init rpc a |> Rpc_lwt.T.get
10499 let setup rpc a = Wraw.setup rpc a |> Rpc_lwt.T.get
105100 let typecheck rpc a = Wraw.typecheck rpc a |> Rpc_lwt.T.get
106101 let exec rpc a = Wraw.exec rpc a |> Rpc_lwt.T.get
107107- let complete rpc a = Wraw.complete rpc a |> Rpc_lwt.T.get
102102+ let compile_js rpc id s = Wraw.compile_js rpc id s |> Rpc_lwt.T.get
108103end
+1-6
idl/js_top_worker_client.mli
···2727 type init_libs = Toplevel_api_gen.init_libs
2828 type err = Toplevel_api_gen.err
2929 type exec_result = Toplevel_api_gen.exec_result
3030- type completion_result = Toplevel_api_gen.completion_result
31303231 (** {2 RPC calls}
3332···5352 (** Execute a phrase using the toplevel. The toplevel must have been
5453 initialised first. *)
55545656- val complete : rpc -> string -> (completion_result, err) result Lwt.t
5757- (** Find completions of the incomplete phrase. Completion occurs at the
5858- end of the phrase passed in. If completion is required at a point
5959- other than the end of a string, then take the substring before calling
6060- this API. *)
5555+ val compile_js : rpc -> string -> string -> (string, err) result Lwt.t
6156end
+89
idl/js_top_worker_client_fut.ml
···11+(** Worker rpc *)
22+33+(** Functions to facilitate RPC calls to web workers. *)
44+55+module Worker = Brr_webworkers.Worker
66+open Brr_io
77+open Js_top_worker_rpc
88+99+(** The assumption made in this module is that RPCs are answered in the order
1010+ they are made. *)
1111+1212+type context = {
1313+ worker : Worker.t;
1414+ timeout : int;
1515+ timeout_fn : unit -> unit;
1616+ waiting : (((Rpc.response, exn) Result.t -> unit) * int) Queue.t;
1717+}
1818+1919+type rpc = Rpc.call -> Rpc.response Fut.t
2020+2121+exception Timeout
2222+2323+(* let log s = Js_of_ocaml.Firebug.console##log (Js_of_ocaml.Js.string s) *)
2424+2525+let demux context msg =
2626+ match Queue.take_opt context.waiting with
2727+ | None -> ()
2828+ | Some (mv, outstanding_execution) ->
2929+ Brr.G.stop_timer outstanding_execution;
3030+ let msg : string = Message.Ev.data (Brr.Ev.as_type msg) in
3131+ (* log (Printf.sprintf "Client received: %s" msg); *)
3232+ mv (Ok (Jsonrpc.response_of_string msg))
3333+3434+let rpc : context -> Rpc.call -> Rpc.response Fut.t =
3535+ fun context call ->
3636+ let open Fut.Syntax in
3737+ let jv = Jsonrpc.string_of_call call in
3838+ (* log (Printf.sprintf "Client sending: %s" jv); *)
3939+ let v, mv = Fut.create () in
4040+ let outstanding_execution =
4141+ Brr.G.set_timeout ~ms:context.timeout (fun () ->
4242+ mv (Error Timeout);
4343+ Worker.terminate context.worker;
4444+ context.timeout_fn ())
4545+ in
4646+ Queue.push (mv, outstanding_execution) context.waiting;
4747+ Worker.post context.worker jv;
4848+ let* r = v in
4949+ match r with
5050+ | Ok jv ->
5151+ let response = jv in
5252+ Fut.return response
5353+ | Error exn -> raise exn
5454+5555+let start url timeout timeout_fn : rpc =
5656+ let worker = Worker.create (Jstr.v url) in
5757+ let context = { worker; timeout; timeout_fn; waiting = Queue.create () } in
5858+ let _listener =
5959+ Brr.Ev.listen Message.Ev.message (demux context) (Worker.as_target worker)
6060+ in
6161+ rpc context
6262+6363+module M = struct
6464+ include Fut
6565+6666+ let fail e = raise e
6767+end
6868+6969+module Rpc_fut = Idl.Make (M)
7070+module Wraw = Toplevel_api_gen.Make (Rpc_fut.GenClient ())
7171+7272+module W = struct
7373+ type init_libs = Toplevel_api_gen.init_libs
7474+ type err = Toplevel_api_gen.err
7575+ type exec_result = Toplevel_api_gen.exec_result
7676+7777+ let init rpc a = Wraw.init rpc a |> Rpc_fut.T.get
7878+ let setup rpc a = Wraw.setup rpc a |> Rpc_fut.T.get
7979+ let typecheck rpc a = Wraw.typecheck rpc a |> Rpc_fut.T.get
8080+ let exec rpc a = Wraw.exec rpc a |> Rpc_fut.T.get
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+8484+ let complete_prefix rpc doc pos =
8585+ Wraw.complete_prefix rpc doc pos |> Rpc_fut.T.get
8686+8787+ let type_enclosing rpc doc pos =
8888+ Wraw.type_enclosing rpc doc pos |> Rpc_fut.T.get
8989+end
-302
idl/jsonrpc.ml
···11-(*
22- * Copyright (c) 2006-2009 Citrix Systems Inc.
33- * Copyright (c) 2006-2014 Thomas Gazagnaire <thomas@gazagnaire.org>
44- *
55- * Permission to use, copy, modify, and distribute this software for any
66- * purpose with or without fee is hereby granted, provided that the above
77- * copyright notice and this permission notice appear in all copies.
88- *
99- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
1010- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1111- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
1212- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
1313- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
1414- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
1515- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1616- *)
1717-1818-open Rpc
1919-2020-module Yojson_private = struct
2121- include Yojson.Safe
2222-2323- let from_string ?(strict = true) ?buf ?fname ?lnum s =
2424- let open Yojson in
2525- try
2626- let lexbuf = Lexing.from_string s in
2727- let v = init_lexer ?buf ?fname ?lnum () in
2828- if strict then from_lexbuf v lexbuf else from_lexbuf v ~stream:true lexbuf
2929- with
3030- | End_of_input -> json_error "Blank input data"
3131-end
3232-3333-module Y = Yojson_private
3434-module U = Yojson.Basic.Util
3535-3636-type version =
3737- | V1
3838- | V2
3939-4040-let rec rpc_to_json t =
4141- match t with
4242- | Int i -> `Intlit (Int64.to_string i)
4343- | Int32 i -> `Int (Int32.to_int i)
4444- | Bool b -> `Bool b
4545- | Float r -> `Float r
4646- | String s -> `String s
4747- | DateTime d -> `String d
4848- | Base64 b -> `String b
4949- | Null -> `Null
5050- | Enum a -> `List (Rpcmarshal.tailrec_map rpc_to_json a)
5151- | Dict a -> `Assoc (Rpcmarshal.tailrec_map (fun (k, v) -> k, rpc_to_json v) a)
5252-5353-5454-exception JsonToRpcError of Y.t
5555-5656-let rec json_to_rpc t =
5757- match t with
5858- | `Intlit i -> Int (Int64.of_string i)
5959- | `Int i -> Int (Int64.of_int i)
6060- | `Bool b -> Bool b
6161- | `Float r -> Float r
6262- | `String s -> (* TODO: check if it is a DateTime *) String s
6363- (* | DateTime d -> `String d *)
6464- (* | Base64 b -> `String b *)
6565- | `Null -> Null
6666- | `List a -> Enum (Rpcmarshal.tailrec_map json_to_rpc a)
6767- | `Assoc a -> Dict (Rpcmarshal.tailrec_map (fun (k, v) -> k, json_to_rpc v) a)
6868- | unsupported -> raise (JsonToRpcError unsupported)
6969-7070-7171-let to_fct t f = rpc_to_json t |> Y.to_string |> f
7272-let to_buffer t buf = to_fct t (fun s -> Buffer.add_string buf s)
7373-let to_string t = rpc_to_json t |> Y.to_string
7474-7575-let to_a ~empty ~append t =
7676- let buf = empty () in
7777- to_fct t (fun s -> append buf s);
7878- buf
7979-8080-8181-let new_id =
8282- let count = ref 0L in
8383- fun () ->
8484- count := Int64.add 1L !count;
8585- !count
8686-8787-8888-let string_of_call ?(version = V1) call =
8989- let json =
9090- match version with
9191- | V1 -> [ "method", String call.name; "params", Enum call.params ]
9292- | V2 ->
9393- let params =
9494- match call.params with
9595- | [ Dict x ] -> Dict x
9696- | _ -> Enum call.params
9797- in
9898- [ "jsonrpc", String "2.0"; "method", String call.name; "params", params ]
9999- in
100100- let json =
101101- if not call.is_notification then json @ [ "id", Int (new_id ()) ] else json
102102- in
103103- to_string (Dict json)
104104-105105-106106-let json_of_response ?(id = Int 0L) version response =
107107- if response.Rpc.success
108108- then (
109109- match version with
110110- | V1 -> Dict [ "result", response.Rpc.contents; "error", Null; "id", id ]
111111- | V2 -> Dict [ "jsonrpc", String "2.0"; "result", response.Rpc.contents; "id", id ])
112112- else (
113113- match version with
114114- | V1 -> Dict [ "result", Null; "error", response.Rpc.contents; "id", id ]
115115- | V2 -> Dict [ "jsonrpc", String "2.0"; "error", response.Rpc.contents; "id", id ])
116116-117117-118118-let json_of_error_object ?(data = None) code message =
119119- let data_json =
120120- match data with
121121- | Some d -> [ "data", d ]
122122- | None -> []
123123- in
124124- Dict ([ "code", Int code; "message", String message ] @ data_json)
125125-126126-127127-let string_of_response ?(id = Int 0L) ?(version = V1) response =
128128- let json = json_of_response ~id version response in
129129- to_string json
130130-131131-132132-let a_of_response ?(id = Int 0L) ?(version = V1) ~empty ~append response =
133133- let json = json_of_response ~id version response in
134134- to_a ~empty ~append json
135135-136136-137137-let of_string ?(strict = true) s = s |> Y.from_string ~strict |> json_to_rpc
138138-139139-let of_a ~next_char b =
140140- let buf = Buffer.create 2048 in
141141- let rec acc () =
142142- match next_char b with
143143- | Some c ->
144144- Buffer.add_char buf c;
145145- acc ()
146146- | None -> ()
147147- in
148148- acc ();
149149- Buffer.contents buf |> of_string
150150-151151-152152-let get' name dict =
153153- try Some (List.assoc name dict) with
154154- | Not_found -> None
155155-156156-157157-exception Malformed_method_request of string
158158-exception Malformed_method_response of string
159159-exception Missing_field of string
160160-161161-let get name dict =
162162- match get' name dict with
163163- | None ->
164164- if Rpc.get_debug () then Printf.eprintf "%s was not found in the dictionary\n" name;
165165- raise (Missing_field name)
166166- | Some v -> v
167167-168168-169169-let version_id_and_call_of_string_option str =
170170- try
171171- match of_string str with
172172- | Dict d ->
173173- let name =
174174- match get "method" d with
175175- | String s -> s
176176- | _ -> raise (Malformed_method_request "Invalid field 'method' in request body")
177177- in
178178- let version =
179179- match get' "jsonrpc" d with
180180- | None -> V1
181181- | Some (String "2.0") -> V2
182182- | _ -> raise (Malformed_method_request "Invalid field 'jsonrpc' in request body")
183183- in
184184- let params =
185185- match version with
186186- | V1 ->
187187- (match get "params" d with
188188- | Enum l -> l
189189- | _ -> raise (Malformed_method_request "Invalid field 'params' in request body"))
190190- | V2 ->
191191- (match get' "params" d with
192192- | None | Some Null -> []
193193- | Some (Enum l) -> l
194194- | Some (Dict l) -> [ Dict l ]
195195- | _ -> raise (Malformed_method_request "Invalid field 'params' in request body"))
196196- in
197197- let id =
198198- match get' "id" d with
199199- | None | Some Null -> None (* is a notification *)
200200- | Some (Int a) -> Some (Int a)
201201- | Some (String a) -> Some (String a)
202202- | Some _ -> raise (Malformed_method_request "Invalid field 'id' in request body")
203203- in
204204- let c = call name params in
205205- version, id, { c with is_notification = id == None }
206206- | _ -> raise (Malformed_method_request "Invalid request body")
207207- with
208208- | Missing_field field ->
209209- raise (Malformed_method_request (Printf.sprintf "Required field %s is missing" field))
210210- | JsonToRpcError json ->
211211- raise
212212- (Malformed_method_request (Printf.sprintf "Unable to parse %s" (Y.to_string json)))
213213-214214-215215-let version_id_and_call_of_string s =
216216- let version, id_, call = version_id_and_call_of_string_option s in
217217- match id_ with
218218- | Some id -> version, id, call
219219- | None -> raise (Malformed_method_request "Invalid field 'id' in request body")
220220-221221-222222-let call_of_string str =
223223- let _, _, call = version_id_and_call_of_string str in
224224- call
225225-226226-227227-(* This functions parses the json and tries to extract a valid jsonrpc response
228228- * (See http://www.jsonrpc.org/ for the exact specs). *)
229229-let get_response extractor str =
230230- try
231231- match extractor str with
232232- | Dict d ->
233233- let _ =
234234- match get "id" d with
235235- | Int _ as x -> x
236236- | String _ as y -> y
237237- | _ -> raise (Malformed_method_response "id")
238238- in
239239- (match get' "jsonrpc" d with
240240- | None ->
241241- let result = get "result" d in
242242- let error = get "error" d in
243243- (match result, error with
244244- | v, Null -> success v
245245- | Null, v -> failure v
246246- | x, y ->
247247- raise
248248- (Malformed_method_response
249249- (Printf.sprintf
250250- "<result=%s><error=%s>"
251251- (Rpc.to_string x)
252252- (Rpc.to_string y))))
253253- | Some (String "2.0") ->
254254- let result = get' "result" d in
255255- let error = get' "error" d in
256256- (match result, error with
257257- | Some v, None -> success v
258258- | None, Some v ->
259259- (match v with
260260- | Dict err ->
261261- let (_ : int64) =
262262- match get "code" err with
263263- | Int i -> i
264264- | _ -> raise (Malformed_method_response "Error code")
265265- in
266266- let _ =
267267- match get "message" err with
268268- | String s -> s
269269- | _ -> raise (Malformed_method_response "Error message")
270270- in
271271- failure v
272272- | _ -> raise (Malformed_method_response "Error object"))
273273- | Some x, Some y ->
274274- raise
275275- (Malformed_method_response
276276- (Printf.sprintf
277277- "<result=%s><error=%s>"
278278- (Rpc.to_string x)
279279- (Rpc.to_string y)))
280280- | None, None ->
281281- raise
282282- (Malformed_method_response
283283- (Printf.sprintf "neither <result> nor <error> was found")))
284284- | _ -> raise (Malformed_method_response "jsonrpc"))
285285- | rpc ->
286286- raise
287287- (Malformed_method_response
288288- (Printf.sprintf "<response_of_stream(%s)>" (to_string rpc)))
289289- with
290290- | Missing_field field ->
291291- raise (Malformed_method_response (Printf.sprintf "<%s was not found>" field))
292292- | JsonToRpcError json ->
293293- raise
294294- (Malformed_method_response
295295- (Printf.sprintf "<unable to parse %s>" (Y.to_string json)))
296296-297297-298298-let response_of_string ?(strict = true) str = get_response (of_string ~strict) str
299299-300300-let response_of_in_channel channel =
301301- let of_channel s = s |> Y.from_channel |> json_to_rpc in
302302- get_response of_channel channel
idl/rpc.ml
idl/_old/rpc.ml
idl/rpc.mli
idl/_old/rpc.mli
idl/rpcmarshal.ml
idl/_old/rpcmarshal.ml
+577-18
idl/toplevel_api.ml
···33open Rpc
44open Idl
5566+let sockpath = "/tmp/js_top_worker.sock"
77+88+open Merlin_kernel
99+module Location = Ocaml_parsing.Location
1010+1111+type lexing_position = Lexing.position = {
1212+ pos_fname: string;
1313+ pos_lnum: int;
1414+ pos_bol: int;
1515+ pos_cnum: int;
1616+} [@@deriving rpcty]
1717+1818+type location = Location.t = {
1919+ loc_start: lexing_position;
2020+ loc_end: lexing_position;
2121+ loc_ghost: bool;
2222+} [@@deriving rpcty]
2323+2424+type location_error_source = Location.error_source =
2525+ | Lexer
2626+ | Parser
2727+ | Typer
2828+ | Warning
2929+ | Unknown
3030+ | Env
3131+ | Config [@@deriving rpcty]
3232+3333+type location_report_kind = Location.report_kind =
3434+ | Report_error
3535+ | Report_warning of string
3636+ | Report_warning_as_error of string
3737+ | Report_alert of string
3838+ | Report_alert_as_error of string [@@deriving rpcty]
3939+4040+type source = string [@@deriving rpcty]
4141+4242+(** CMIs are provided either statically or as URLs to be downloaded on demand *)
4343+4444+(** Dynamic cmis are loaded from beneath the given url. In addition the
4545+ top-level modules are specified, and prefixes for other modules. For
4646+ example, for the OCaml standard library, a user might pass:
4747+4848+ {[
4949+ { dcs_url="/static/stdlib";
5050+ dcs_toplevel_modules=["Stdlib"];
5151+ dcs_file_prefixes=["stdlib__"]; }
5252+ ]}
5353+5454+ In which case, merlin will expect to be able to download a valid file
5555+ from the url ["/static/stdlib/stdlib.cmi"] corresponding to the
5656+ specified toplevel module, and it will also attempt to download any
5757+ module with the prefix ["Stdlib__"] from the same base url, so for
5858+ example if an attempt is made to look up the module ["Stdlib__Foo"]
5959+ then merlin-js will attempt to download a file from the url
6060+ ["/static/stdlib/stdlib__Foo.cmi"].
6161+ *)
6262+6363+type dynamic_cmis = {
6464+ dcs_url : string;
6565+ dcs_toplevel_modules : string list;
6666+ dcs_file_prefixes : string list;
6767+}
6868+6969+and static_cmi = {
7070+ sc_name : string; (* capitalised, e.g. 'Stdlib' *)
7171+ sc_content : string;
7272+}
7373+7474+and cmis = {
7575+ static_cmis : static_cmi list;
7676+ dynamic_cmis : dynamic_cmis option;
7777+} [@@deriving rpcty]
7878+7979+type action =
8080+ | Complete_prefix of source * Msource.position
8181+ | Type_enclosing of source * Msource.position
8282+ | All_errors of source
8383+ | Add_cmis of cmis
8484+8585+type error = {
8686+ kind : location_report_kind;
8787+ loc: location;
8888+ main : string;
8989+ sub : string list;
9090+ source : location_error_source;
9191+} [@@deriving rpcty]
9292+9393+type error_list = error list [@@deriving rpcty]
9494+9595+type kind_ty =
9696+ [ `Constructor
9797+ | `Keyword
9898+ | `Label
9999+ | `MethodCall
100100+ | `Modtype
101101+ | `Module
102102+ | `Type
103103+ | `Value
104104+ | `Variant ]
105105+106106+include
107107+ struct
108108+ open Rpc.Types
109109+ let _ = fun (_ : kind_ty) -> ()
110110+ let rec typ_of_kind_ty =
111111+ let mk tname tpreview treview =
112112+ BoxedTag
113113+ {
114114+ tname;
115115+ tcontents = Unit;
116116+ tversion = None;
117117+ tdescription = [];
118118+ tpreview;
119119+ treview;
120120+ }
121121+ in
122122+123123+ Variant
124124+ ({
125125+ vname = "kind";
126126+ variants =
127127+ [mk "Constructor" (function | `Constructor -> Some () | _ -> None) (function | () -> `Constructor);
128128+ mk "Keyword" (function | `Keyword -> Some () | _ -> None) (function | () -> `Keyword);
129129+ mk "Label" (function | `Label -> Some () | _ -> None) (function | () -> `Label);
130130+ mk "MethodCall" (function | `MethodCall -> Some () | _ -> None) (function | () -> `MethodCall);
131131+ mk "Modtype" (function | `Modtype -> Some () | _ -> None) (function | () -> `Modtype);
132132+ mk "Module" (function | `Module -> Some () | _ -> None) (function | () -> `Module);
133133+ mk "Type" (function | `Type -> Some () | _ -> None) (function | () -> `Type);
134134+ mk "Value" (function | `Value -> Some () | _ -> None) (function | () -> `Value);
135135+ mk "Variant" (function | `Variant -> Some () | _ -> None) (function | () -> `Variant)];
136136+ vdefault = None;
137137+ vversion = None;
138138+ vconstructor =
139139+ (fun s' ->
140140+ fun t ->
141141+ let s = String.lowercase_ascii s' in
142142+ match s with
143143+ | "constructor" ->
144144+ Rresult.R.bind (t.tget Unit)
145145+ (function | () -> Rresult.R.ok `Constructor)
146146+ | "keyword" ->
147147+ Rresult.R.bind (t.tget Unit)
148148+ (function | () -> Rresult.R.ok `Keyword)
149149+ | "label" ->
150150+ Rresult.R.bind (t.tget Unit)
151151+ (function | () -> Rresult.R.ok `Label)
152152+ | "methodcall" ->
153153+ Rresult.R.bind (t.tget Unit)
154154+ (function | () -> Rresult.R.ok `MethodCall)
155155+ | "modtype" ->
156156+ Rresult.R.bind (t.tget Unit)
157157+ (function | () -> Rresult.R.ok `Modtype)
158158+ | "module" ->
159159+ Rresult.R.bind (t.tget Unit)
160160+ (function | () -> Rresult.R.ok `Module)
161161+ | "type" ->
162162+ Rresult.R.bind (t.tget Unit)
163163+ (function | () -> Rresult.R.ok `Type)
164164+ | "value" ->
165165+ Rresult.R.bind (t.tget Unit)
166166+ (function | () -> Rresult.R.ok `Value)
167167+ | "variant" ->
168168+ Rresult.R.bind (t.tget Unit)
169169+ (function | () -> Rresult.R.ok `Variant)
170170+ | _ ->
171171+ Rresult.R.error_msg
172172+ (Printf.sprintf "Unknown tag '%s'" s))
173173+ } : kind_ty variant)
174174+ and kind_ty =
175175+ {
176176+ name = "kind_ty";
177177+ description = [];
178178+ ty = typ_of_kind_ty
179179+ }
180180+ let _ = typ_of_kind_ty
181181+ and _ = kind_ty
182182+end[@@ocaml.doc "@inline"][@@merlin.hide ]
183183+184184+185185+type query_protocol_compl_entry = Query_protocol.Compl.entry
186186+include
187187+ struct
188188+ open Rpc.Types
189189+ let _ = fun (_ : query_protocol_compl_entry) -> ()
190190+ let rec query_protocol_compl_entry_name :
191191+ (_, query_protocol_compl_entry) field =
192192+ {
193193+ fname = "name";
194194+ field = typ_of_source;
195195+ fdefault = None;
196196+ fdescription = [];
197197+ fversion = None;
198198+ fget = (fun _r -> _r.name);
199199+ fset = (fun v -> fun _s -> { _s with name = v })
200200+ }
201201+ and query_protocol_compl_entry_kind :
202202+ (_, query_protocol_compl_entry) field =
203203+ {
204204+ fname = "kind";
205205+ field = typ_of_kind_ty;
206206+ fdefault = None;
207207+ fdescription = [];
208208+ fversion = None;
209209+ fget = (fun _r -> _r.kind);
210210+ fset = (fun v -> fun _s -> { _s with kind = v })
211211+ }
212212+ and query_protocol_compl_entry_desc :
213213+ (_, query_protocol_compl_entry) field =
214214+ {
215215+ fname = "desc";
216216+ field = typ_of_source;
217217+ fdefault = None;
218218+ fdescription = [];
219219+ fversion = None;
220220+ fget = (fun _r -> _r.desc);
221221+ fset = (fun v -> fun _s -> { _s with desc = v })
222222+ }
223223+ and query_protocol_compl_entry_info :
224224+ (_, query_protocol_compl_entry) field =
225225+ {
226226+ fname = "info";
227227+ field = typ_of_source;
228228+ fdefault = None;
229229+ fdescription = [];
230230+ fversion = None;
231231+ fget = (fun _r -> _r.info);
232232+ fset = (fun v -> fun _s -> { _s with info = v })
233233+ }
234234+ and query_protocol_compl_entry_deprecated :
235235+ (_, query_protocol_compl_entry) field =
236236+ {
237237+ fname = "deprecated";
238238+ field = (let open Rpc.Types in Basic Bool);
239239+ fdefault = None;
240240+ fdescription = [];
241241+ fversion = None;
242242+ fget = (fun _r -> _r.deprecated);
243243+ fset = (fun v -> fun _s -> { _s with deprecated = v })
244244+ }
245245+ and typ_of_query_protocol_compl_entry =
246246+ Struct
247247+ ({
248248+ fields =
249249+ [BoxedField query_protocol_compl_entry_name;
250250+ BoxedField query_protocol_compl_entry_kind;
251251+ BoxedField query_protocol_compl_entry_desc;
252252+ BoxedField query_protocol_compl_entry_info;
253253+ BoxedField query_protocol_compl_entry_deprecated];
254254+ sname = "query_protocol_compl_entry";
255255+ version = None;
256256+ constructor =
257257+ (fun getter ->
258258+ let open Rresult.R in
259259+ (getter.field_get "deprecated"
260260+ (let open Rpc.Types in Basic Bool))
261261+ >>=
262262+ (fun query_protocol_compl_entry_deprecated ->
263263+ (getter.field_get "info" typ_of_source) >>=
264264+ (fun query_protocol_compl_entry_info ->
265265+ (getter.field_get "desc" typ_of_source)
266266+ >>=
267267+ (fun query_protocol_compl_entry_desc ->
268268+ (getter.field_get "kind"
269269+ typ_of_kind_ty)
270270+ >>=
271271+ (fun query_protocol_compl_entry_kind ->
272272+ (getter.field_get "name"
273273+ typ_of_source)
274274+ >>=
275275+ (fun query_protocol_compl_entry_name
276276+ ->
277277+ return
278278+ {
279279+ Query_protocol.Compl.name =
280280+ query_protocol_compl_entry_name;
281281+ kind =
282282+ query_protocol_compl_entry_kind;
283283+ desc =
284284+ query_protocol_compl_entry_desc;
285285+ info =
286286+ query_protocol_compl_entry_info;
287287+ deprecated =
288288+ query_protocol_compl_entry_deprecated
289289+ }))))))
290290+ } : query_protocol_compl_entry structure)
291291+ and query_protocol_compl_entry =
292292+ {
293293+ name = "query_protocol_compl_entry";
294294+ description = [];
295295+ ty = typ_of_query_protocol_compl_entry
296296+ }
297297+ let _ = query_protocol_compl_entry_name
298298+ and _ = query_protocol_compl_entry_kind
299299+ and _ = query_protocol_compl_entry_desc
300300+ and _ = query_protocol_compl_entry_info
301301+ and _ = query_protocol_compl_entry_deprecated
302302+ and _ = typ_of_query_protocol_compl_entry
303303+ and _ = query_protocol_compl_entry
304304+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
305305+306306+307307+include
308308+ struct
309309+ open Rpc.Types
310310+ let _ = fun (_ : Merlin_kernel.Msource.position) -> ()
311311+ let rec typ_of_msource_position =
312312+ Variant
313313+ ({
314314+ vname = "msource_position";
315315+ variants =
316316+ [BoxedTag
317317+ {
318318+ tname = "Start";
319319+ tcontents = Unit;
320320+ tversion = None;
321321+ tdescription = [];
322322+ tpreview =
323323+ ((function | `Start -> Some () | _ -> None));
324324+ treview = ((function | () -> `Start))
325325+ };
326326+ BoxedTag
327327+ {
328328+ tname = "Offset";
329329+ tcontents = ((let open Rpc.Types in Basic Int));
330330+ tversion = None;
331331+ tdescription = [];
332332+ tpreview =
333333+ ((function | `Offset a0 -> Some a0 | _ -> None));
334334+ treview = ((function | a0 -> `Offset a0))
335335+ };
336336+ BoxedTag
337337+ {
338338+ tname = "Logical";
339339+ tcontents =
340340+ (Tuple
341341+ (((let open Rpc.Types in Basic Int)),
342342+ ((let open Rpc.Types in Basic Int))));
343343+ tversion = None;
344344+ tdescription = [];
345345+ tpreview =
346346+ ((function | `Logical (a0, a1) -> Some (a0, a1) | _ -> None));
347347+ treview =
348348+ ((function | (a0, a1) -> `Logical (a0, a1)))
349349+ };
350350+ BoxedTag
351351+ {
352352+ tname = "End";
353353+ tcontents = Unit;
354354+ tversion = None;
355355+ tdescription = [];
356356+ tpreview =
357357+ ((function | `End -> Some () | _ -> None));
358358+ treview = ((function | () -> `End))
359359+ }];
360360+ vdefault = None;
361361+ vversion = None;
362362+ vconstructor =
363363+ (fun s' ->
364364+ fun t ->
365365+ let s = String.lowercase_ascii s' in
366366+ match s with
367367+ | "start" ->
368368+ Rresult.R.bind (t.tget Unit)
369369+ (function | () -> Rresult.R.ok `Start)
370370+ | "offset" ->
371371+ Rresult.R.bind
372372+ (t.tget (let open Rpc.Types in Basic Int))
373373+ (function | a0 -> Rresult.R.ok (`Offset a0))
374374+ | "logical" ->
375375+ Rresult.R.bind
376376+ (t.tget
377377+ (Tuple
378378+ ((let open Rpc.Types in Basic Int),
379379+ (let open Rpc.Types in Basic Int))))
380380+ (function
381381+ | (a0, a1) -> Rresult.R.ok (`Logical (a0, a1)))
382382+ | "end" ->
383383+ Rresult.R.bind (t.tget Unit)
384384+ (function | () -> Rresult.R.ok `End)
385385+ | _ ->
386386+ Rresult.R.error_msg
387387+ (Printf.sprintf "Unknown tag '%s'" s))
388388+ } : Merlin_kernel.Msource.position variant)
389389+ and msource_position =
390390+ {
391391+ name = "msource_position";
392392+ description = [];
393393+ ty = typ_of_msource_position
394394+ }
395395+ let _ = typ_of_msource_position
396396+ and _ = msource_position
397397+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
398398+399399+type completions = {
400400+ from: int;
401401+ to_: int;
402402+ entries : query_protocol_compl_entry list
403403+} [@@deriving rpcty]
404404+405405+type is_tail_position =
406406+ [ `No | `Tail_position | `Tail_call ]
407407+ include
408408+ struct
409409+ open Rpc.Types
410410+ let _ = fun (_ : is_tail_position) -> ()
411411+ let rec typ_of_is_tail_position =
412412+ Variant
413413+ ({
414414+ vname = "is_tail_position";
415415+ variants =
416416+ [BoxedTag
417417+ {
418418+ tname = "No";
419419+ tcontents = Unit;
420420+ tversion = None;
421421+ tdescription = [];
422422+ tpreview =
423423+ ((function | `No -> Some () | _ -> None));
424424+ treview = ((function | () -> `No))
425425+ };
426426+ BoxedTag
427427+ {
428428+ tname = "Tail_position";
429429+ tcontents = Unit;
430430+ tversion = None;
431431+ tdescription = [];
432432+ tpreview =
433433+ ((function | `Tail_position -> Some () | _ -> None));
434434+ treview = ((function | () -> `Tail_position))
435435+ };
436436+ BoxedTag
437437+ {
438438+ tname = "Tail_call";
439439+ tcontents = Unit;
440440+ tversion = None;
441441+ tdescription = [];
442442+ tpreview =
443443+ ((function | `Tail_call -> Some () | _ -> None));
444444+ treview = ((function | () -> `Tail_call))
445445+ }];
446446+ vdefault = None;
447447+ vversion = None;
448448+ vconstructor =
449449+ (fun s' ->
450450+ fun t ->
451451+ let s = String.lowercase_ascii s' in
452452+ match s with
453453+ | "no" ->
454454+ Rresult.R.bind (t.tget Unit)
455455+ (function | () -> Rresult.R.ok `No)
456456+ | "tail_position" ->
457457+ Rresult.R.bind (t.tget Unit)
458458+ (function | () -> Rresult.R.ok `Tail_position)
459459+ | "tail_call" ->
460460+ Rresult.R.bind (t.tget Unit)
461461+ (function | () -> Rresult.R.ok `Tail_call)
462462+ | _ ->
463463+ Rresult.R.error_msg
464464+ (Printf.sprintf "Unknown tag '%s'" s))
465465+ } : is_tail_position variant)
466466+ and is_tail_position =
467467+ {
468468+ name = "is_tail_position";
469469+ description = [];
470470+ ty = typ_of_is_tail_position
471471+ }
472472+ let _ = typ_of_is_tail_position
473473+ and _ = is_tail_position
474474+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
475475+476476+type index_or_string =
477477+ [ `Index of int
478478+ | `String of string ]
479479+include
480480+ struct
481481+ open Rpc.Types
482482+ let _ = fun (_ : index_or_string) -> ()
483483+ let rec typ_of_index_or_string =
484484+ Variant
485485+ ({
486486+ vname = "index_or_string";
487487+ variants =
488488+ [BoxedTag
489489+ {
490490+ tname = "Index";
491491+ tcontents = ((let open Rpc.Types in Basic Int));
492492+ tversion = None;
493493+ tdescription = [];
494494+ tpreview =
495495+ ((function | `Index a0 -> Some a0 | _ -> None));
496496+ treview = ((function | a0 -> `Index a0))
497497+ };
498498+ BoxedTag
499499+ {
500500+ tname = "String";
501501+ tcontents = ((let open Rpc.Types in Basic String));
502502+ tversion = None;
503503+ tdescription = [];
504504+ tpreview =
505505+ ((function | `String a0 -> Some a0 | _ -> None));
506506+ treview = ((function | a0 -> `String a0))
507507+ }];
508508+ vdefault = None;
509509+ vversion = None;
510510+ vconstructor =
511511+ (fun s' ->
512512+ fun t ->
513513+ let s = String.lowercase_ascii s' in
514514+ match s with
515515+ | "index" ->
516516+ Rresult.R.bind
517517+ (t.tget (let open Rpc.Types in Basic Int))
518518+ (function | a0 -> Rresult.R.ok (`Index a0))
519519+ | "string" ->
520520+ Rresult.R.bind
521521+ (t.tget (let open Rpc.Types in Basic String))
522522+ (function | a0 -> Rresult.R.ok (`String a0))
523523+ | _ ->
524524+ Rresult.R.error_msg
525525+ (Printf.sprintf "Unknown tag '%s'" s))
526526+ } : index_or_string variant)
527527+ and index_or_string =
528528+ {
529529+ name = "index_or_string";
530530+ description = [];
531531+ ty = typ_of_index_or_string
532532+ }
533533+ let _ = typ_of_index_or_string
534534+ and _ = index_or_string
535535+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
536536+537537+type typed_enclosings = location * index_or_string * is_tail_position [@@deriving rpcty]
538538+type typed_enclosings_list = typed_enclosings list [@@deriving rpcty]
539539+let report_source_to_string = function
540540+ | Location.Lexer -> "lexer"
541541+ | Location.Parser -> "parser"
542542+ | Location.Typer -> "typer"
543543+ | Location.Warning -> "warning" (* todo incorrect ?*)
544544+ | Location.Unknown -> "unknown"
545545+ | Location.Env -> "env"
546546+ | Location.Config -> "config"
547547+6548type highlight = { line1 : int; line2 : int; col1 : int; col2 : int }
7549[@@deriving rpcty]
8550(** An area to be highlighted *)
···26568[@@deriving rpcty]
27569(** Represents the result of executing a toplevel phrase *)
285702929-type completion_result = {
3030- n : int;
3131- (** The position in the input string from where the completions may be
3232- inserted *)
3333- completions : string list; (** The list of possible completions *)
3434-}
3535-[@@deriving rpcty]
3636-(** The result returned by a 'complete' call. *)
3737-38571type cma = {
39572 url : string; (** URL where the cma is available *)
40573 fn : string; (** Name of the 'wrapping' function *)
41574}
42575[@@deriving rpcty]
435764444-type init_libs = { cmi_urls : string list; cmas : cma list } [@@deriving rpcty]
577577+type init_libs = { path : string; cmis : cmis; cmas : cma list } [@@deriving rpcty]
45578type err = InternalError of string [@@deriving rpcty]
4657947580module E = Idl.Error.Make (struct
···69602 let implementation = implement description
70603 let unit_p = Param.mk Types.unit
71604 let phrase_p = Param.mk Types.string
605605+ let id_p = Param.mk Types.string
72606 let typecheck_result_p = Param.mk exec_result
73607 let exec_result_p = Param.mk exec_result
7474- let completion_p = Param.mk completion_result
608608+609609+ let source_p = Param.mk source
610610+ let position_p = Param.mk msource_position
611611+612612+ let completions_p = Param.mk completions
613613+ let error_list_p = Param.mk error_list
614614+ let typed_enclosings_p = Param.mk typed_enclosings_list
7561576616 let init_libs =
77617 Param.mk ~name:"init_libs"
···110650 ]
111651 (phrase_p @-> returning exec_result_p err)
112652113113- let complete =
114114- declare "complete"
653653+ let compile_js =
654654+ declare "compile_js"
655655+ [
656656+ "Compile a phrase to javascript. The toplevel must have been";
657657+ "Initialised first.";
658658+ ]
659659+ (id_p @-> phrase_p @-> returning phrase_p err)
660660+661661+ let complete_prefix =
662662+ declare "complete_prefix"
663663+ [
664664+ "Complete a prefix"
665665+ ]
666666+ (source_p @-> position_p @-> returning completions_p err)
667667+668668+ let query_errors =
669669+ declare "query_errors"
115670 [
116116- "Find completions of the incomplete phrase. Completion occurs at the";
117117- "end of the phrase passed in. If completion is required at a point";
118118- "other than the end of a string, then take the substring before calling";
119119- "this API.";
671671+ "Query the errors in the given source"
120672 ]
121121- (phrase_p @-> returning completion_p err)
673673+ (source_p @-> returning error_list_p err)
674674+675675+ let type_enclosing =
676676+ declare "type_enclosing"
677677+ [
678678+ "Get the type of the enclosing expression"
679679+ ]
680680+ (source_p @-> position_p @-> returning typed_enclosings_p err)
122681end
+1373-96
idl/toplevel_api_gen.ml
···1818[@@@ocaml.text " IDL for talking to the toplevel webworker "]
1919open Rpc
2020open Idl
2121+let sockpath = "/tmp/js_top_worker.sock"
2222+open Merlin_kernel
2323+module Location = Ocaml_parsing.Location
2424+type lexing_position = Lexing.position =
2525+ {
2626+ pos_fname: string ;
2727+ pos_lnum: int ;
2828+ pos_bol: int ;
2929+ pos_cnum: int }[@@deriving rpcty]
3030+include
3131+ struct
3232+ let _ = fun (_ : lexing_position) -> ()
3333+ let rec lexing_position_pos_fname : (_, lexing_position) Rpc.Types.field
3434+ =
3535+ {
3636+ Rpc.Types.fname = "pos_fname";
3737+ Rpc.Types.field = (let open Rpc.Types in Basic String);
3838+ Rpc.Types.fdefault = None;
3939+ Rpc.Types.fdescription = [];
4040+ Rpc.Types.fversion = None;
4141+ Rpc.Types.fget = (fun _r -> _r.pos_fname);
4242+ Rpc.Types.fset = (fun v -> fun _s -> { _s with pos_fname = v })
4343+ }
4444+ and lexing_position_pos_lnum : (_, lexing_position) Rpc.Types.field =
4545+ {
4646+ Rpc.Types.fname = "pos_lnum";
4747+ Rpc.Types.field = (let open Rpc.Types in Basic Int);
4848+ Rpc.Types.fdefault = None;
4949+ Rpc.Types.fdescription = [];
5050+ Rpc.Types.fversion = None;
5151+ Rpc.Types.fget = (fun _r -> _r.pos_lnum);
5252+ Rpc.Types.fset = (fun v -> fun _s -> { _s with pos_lnum = v })
5353+ }
5454+ and lexing_position_pos_bol : (_, lexing_position) Rpc.Types.field =
5555+ {
5656+ Rpc.Types.fname = "pos_bol";
5757+ Rpc.Types.field = (let open Rpc.Types in Basic Int);
5858+ Rpc.Types.fdefault = None;
5959+ Rpc.Types.fdescription = [];
6060+ Rpc.Types.fversion = None;
6161+ Rpc.Types.fget = (fun _r -> _r.pos_bol);
6262+ Rpc.Types.fset = (fun v -> fun _s -> { _s with pos_bol = v })
6363+ }
6464+ and lexing_position_pos_cnum : (_, lexing_position) Rpc.Types.field =
6565+ {
6666+ Rpc.Types.fname = "pos_cnum";
6767+ Rpc.Types.field = (let open Rpc.Types in Basic Int);
6868+ Rpc.Types.fdefault = None;
6969+ Rpc.Types.fdescription = [];
7070+ Rpc.Types.fversion = None;
7171+ Rpc.Types.fget = (fun _r -> _r.pos_cnum);
7272+ Rpc.Types.fset = (fun v -> fun _s -> { _s with pos_cnum = v })
7373+ }
7474+ and typ_of_lexing_position =
7575+ Rpc.Types.Struct
7676+ ({
7777+ Rpc.Types.fields =
7878+ [Rpc.Types.BoxedField lexing_position_pos_fname;
7979+ Rpc.Types.BoxedField lexing_position_pos_lnum;
8080+ Rpc.Types.BoxedField lexing_position_pos_bol;
8181+ Rpc.Types.BoxedField lexing_position_pos_cnum];
8282+ Rpc.Types.sname = "lexing_position";
8383+ Rpc.Types.version = None;
8484+ Rpc.Types.constructor =
8585+ (fun getter ->
8686+ let open Rresult.R in
8787+ (getter.Rpc.Types.field_get "pos_cnum"
8888+ (let open Rpc.Types in Basic Int))
8989+ >>=
9090+ (fun lexing_position_pos_cnum ->
9191+ (getter.Rpc.Types.field_get "pos_bol"
9292+ (let open Rpc.Types in Basic Int))
9393+ >>=
9494+ (fun lexing_position_pos_bol ->
9595+ (getter.Rpc.Types.field_get "pos_lnum"
9696+ (let open Rpc.Types in Basic Int))
9797+ >>=
9898+ (fun lexing_position_pos_lnum ->
9999+ (getter.Rpc.Types.field_get "pos_fname"
100100+ (let open Rpc.Types in Basic String))
101101+ >>=
102102+ (fun lexing_position_pos_fname ->
103103+ return
104104+ {
105105+ pos_fname =
106106+ lexing_position_pos_fname;
107107+ pos_lnum = lexing_position_pos_lnum;
108108+ pos_bol = lexing_position_pos_bol;
109109+ pos_cnum = lexing_position_pos_cnum
110110+ })))))
111111+ } : lexing_position Rpc.Types.structure)
112112+ and lexing_position =
113113+ {
114114+ Rpc.Types.name = "lexing_position";
115115+ Rpc.Types.description = [];
116116+ Rpc.Types.ty = typ_of_lexing_position
117117+ }
118118+ let _ = lexing_position_pos_fname
119119+ and _ = lexing_position_pos_lnum
120120+ and _ = lexing_position_pos_bol
121121+ and _ = lexing_position_pos_cnum
122122+ and _ = typ_of_lexing_position
123123+ and _ = lexing_position
124124+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
125125+type location = Location.t =
126126+ {
127127+ loc_start: lexing_position ;
128128+ loc_end: lexing_position ;
129129+ loc_ghost: bool }[@@deriving rpcty]
130130+include
131131+ struct
132132+ let _ = fun (_ : location) -> ()
133133+ let rec location_loc_start : (_, location) Rpc.Types.field =
134134+ {
135135+ Rpc.Types.fname = "loc_start";
136136+ Rpc.Types.field = typ_of_lexing_position;
137137+ Rpc.Types.fdefault = None;
138138+ Rpc.Types.fdescription = [];
139139+ Rpc.Types.fversion = None;
140140+ Rpc.Types.fget = (fun _r -> _r.loc_start);
141141+ Rpc.Types.fset = (fun v -> fun _s -> { _s with loc_start = v })
142142+ }
143143+ and location_loc_end : (_, location) Rpc.Types.field =
144144+ {
145145+ Rpc.Types.fname = "loc_end";
146146+ Rpc.Types.field = typ_of_lexing_position;
147147+ Rpc.Types.fdefault = None;
148148+ Rpc.Types.fdescription = [];
149149+ Rpc.Types.fversion = None;
150150+ Rpc.Types.fget = (fun _r -> _r.loc_end);
151151+ Rpc.Types.fset = (fun v -> fun _s -> { _s with loc_end = v })
152152+ }
153153+ and location_loc_ghost : (_, location) Rpc.Types.field =
154154+ {
155155+ Rpc.Types.fname = "loc_ghost";
156156+ Rpc.Types.field = (let open Rpc.Types in Basic Bool);
157157+ Rpc.Types.fdefault = None;
158158+ Rpc.Types.fdescription = [];
159159+ Rpc.Types.fversion = None;
160160+ Rpc.Types.fget = (fun _r -> _r.loc_ghost);
161161+ Rpc.Types.fset = (fun v -> fun _s -> { _s with loc_ghost = v })
162162+ }
163163+ and typ_of_location =
164164+ Rpc.Types.Struct
165165+ ({
166166+ Rpc.Types.fields =
167167+ [Rpc.Types.BoxedField location_loc_start;
168168+ Rpc.Types.BoxedField location_loc_end;
169169+ Rpc.Types.BoxedField location_loc_ghost];
170170+ Rpc.Types.sname = "location";
171171+ Rpc.Types.version = None;
172172+ Rpc.Types.constructor =
173173+ (fun getter ->
174174+ let open Rresult.R in
175175+ (getter.Rpc.Types.field_get "loc_ghost"
176176+ (let open Rpc.Types in Basic Bool))
177177+ >>=
178178+ (fun location_loc_ghost ->
179179+ (getter.Rpc.Types.field_get "loc_end"
180180+ typ_of_lexing_position)
181181+ >>=
182182+ (fun location_loc_end ->
183183+ (getter.Rpc.Types.field_get "loc_start"
184184+ typ_of_lexing_position)
185185+ >>=
186186+ (fun location_loc_start ->
187187+ return
188188+ {
189189+ loc_start = location_loc_start;
190190+ loc_end = location_loc_end;
191191+ loc_ghost = location_loc_ghost
192192+ }))))
193193+ } : location Rpc.Types.structure)
194194+ and location =
195195+ {
196196+ Rpc.Types.name = "location";
197197+ Rpc.Types.description = [];
198198+ Rpc.Types.ty = typ_of_location
199199+ }
200200+ let _ = location_loc_start
201201+ and _ = location_loc_end
202202+ and _ = location_loc_ghost
203203+ and _ = typ_of_location
204204+ and _ = location
205205+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
206206+type location_error_source = Location.error_source =
207207+ | Lexer
208208+ | Parser
209209+ | Typer
210210+ | Warning
211211+ | Unknown
212212+ | Env
213213+ | Config [@@deriving rpcty]
214214+include
215215+ struct
216216+ let _ = fun (_ : location_error_source) -> ()
217217+ let rec typ_of_location_error_source =
218218+ Rpc.Types.Variant
219219+ ({
220220+ Rpc.Types.vname = "location_error_source";
221221+ Rpc.Types.variants =
222222+ [BoxedTag
223223+ {
224224+ Rpc.Types.tname = "Lexer";
225225+ Rpc.Types.tcontents = Unit;
226226+ Rpc.Types.tversion = None;
227227+ Rpc.Types.tdescription = [];
228228+ Rpc.Types.tpreview =
229229+ ((function | Lexer -> Some () | _ -> None));
230230+ Rpc.Types.treview = ((function | () -> Lexer))
231231+ };
232232+ BoxedTag
233233+ {
234234+ Rpc.Types.tname = "Parser";
235235+ Rpc.Types.tcontents = Unit;
236236+ Rpc.Types.tversion = None;
237237+ Rpc.Types.tdescription = [];
238238+ Rpc.Types.tpreview =
239239+ ((function | Parser -> Some () | _ -> None));
240240+ Rpc.Types.treview = ((function | () -> Parser))
241241+ };
242242+ BoxedTag
243243+ {
244244+ Rpc.Types.tname = "Typer";
245245+ Rpc.Types.tcontents = Unit;
246246+ Rpc.Types.tversion = None;
247247+ Rpc.Types.tdescription = [];
248248+ Rpc.Types.tpreview =
249249+ ((function | Typer -> Some () | _ -> None));
250250+ Rpc.Types.treview = ((function | () -> Typer))
251251+ };
252252+ BoxedTag
253253+ {
254254+ Rpc.Types.tname = "Warning";
255255+ Rpc.Types.tcontents = Unit;
256256+ Rpc.Types.tversion = None;
257257+ Rpc.Types.tdescription = [];
258258+ Rpc.Types.tpreview =
259259+ ((function | Warning -> Some () | _ -> None));
260260+ Rpc.Types.treview = ((function | () -> Warning))
261261+ };
262262+ BoxedTag
263263+ {
264264+ Rpc.Types.tname = "Unknown";
265265+ Rpc.Types.tcontents = Unit;
266266+ Rpc.Types.tversion = None;
267267+ Rpc.Types.tdescription = [];
268268+ Rpc.Types.tpreview =
269269+ ((function | Unknown -> Some () | _ -> None));
270270+ Rpc.Types.treview = ((function | () -> Unknown))
271271+ };
272272+ BoxedTag
273273+ {
274274+ Rpc.Types.tname = "Env";
275275+ Rpc.Types.tcontents = Unit;
276276+ Rpc.Types.tversion = None;
277277+ Rpc.Types.tdescription = [];
278278+ Rpc.Types.tpreview =
279279+ ((function | Env -> Some () | _ -> None));
280280+ Rpc.Types.treview = ((function | () -> Env))
281281+ };
282282+ BoxedTag
283283+ {
284284+ Rpc.Types.tname = "Config";
285285+ Rpc.Types.tcontents = Unit;
286286+ Rpc.Types.tversion = None;
287287+ Rpc.Types.tdescription = [];
288288+ Rpc.Types.tpreview =
289289+ ((function | Config -> Some () | _ -> None));
290290+ Rpc.Types.treview = ((function | () -> Config))
291291+ }];
292292+ Rpc.Types.vdefault = None;
293293+ Rpc.Types.vversion = None;
294294+ Rpc.Types.vconstructor =
295295+ (fun s' ->
296296+ fun t ->
297297+ let s = String.lowercase_ascii s' in
298298+ match s with
299299+ | "lexer" ->
300300+ Rresult.R.bind (t.tget Unit)
301301+ (function | () -> Rresult.R.ok Lexer)
302302+ | "parser" ->
303303+ Rresult.R.bind (t.tget Unit)
304304+ (function | () -> Rresult.R.ok Parser)
305305+ | "typer" ->
306306+ Rresult.R.bind (t.tget Unit)
307307+ (function | () -> Rresult.R.ok Typer)
308308+ | "warning" ->
309309+ Rresult.R.bind (t.tget Unit)
310310+ (function | () -> Rresult.R.ok Warning)
311311+ | "unknown" ->
312312+ Rresult.R.bind (t.tget Unit)
313313+ (function | () -> Rresult.R.ok Unknown)
314314+ | "env" ->
315315+ Rresult.R.bind (t.tget Unit)
316316+ (function | () -> Rresult.R.ok Env)
317317+ | "config" ->
318318+ Rresult.R.bind (t.tget Unit)
319319+ (function | () -> Rresult.R.ok Config)
320320+ | _ ->
321321+ Rresult.R.error_msg
322322+ (Printf.sprintf "Unknown tag '%s'" s))
323323+ } : location_error_source Rpc.Types.variant)
324324+ and location_error_source =
325325+ {
326326+ Rpc.Types.name = "location_error_source";
327327+ Rpc.Types.description = [];
328328+ Rpc.Types.ty = typ_of_location_error_source
329329+ }
330330+ let _ = typ_of_location_error_source
331331+ and _ = location_error_source
332332+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
333333+type location_report_kind = Location.report_kind =
334334+ | Report_error
335335+ | Report_warning of string
336336+ | Report_warning_as_error of string
337337+ | Report_alert of string
338338+ | Report_alert_as_error of string [@@deriving rpcty]
339339+include
340340+ struct
341341+ let _ = fun (_ : location_report_kind) -> ()
342342+ let rec typ_of_location_report_kind =
343343+ Rpc.Types.Variant
344344+ ({
345345+ Rpc.Types.vname = "location_report_kind";
346346+ Rpc.Types.variants =
347347+ [BoxedTag
348348+ {
349349+ Rpc.Types.tname = "Report_error";
350350+ Rpc.Types.tcontents = Unit;
351351+ Rpc.Types.tversion = None;
352352+ Rpc.Types.tdescription = [];
353353+ Rpc.Types.tpreview =
354354+ ((function | Report_error -> Some () | _ -> None));
355355+ Rpc.Types.treview = ((function | () -> Report_error))
356356+ };
357357+ BoxedTag
358358+ {
359359+ Rpc.Types.tname = "Report_warning";
360360+ Rpc.Types.tcontents = ((let open Rpc.Types in Basic String));
361361+ Rpc.Types.tversion = None;
362362+ Rpc.Types.tdescription = [];
363363+ Rpc.Types.tpreview =
364364+ ((function | Report_warning a0 -> Some a0 | _ -> None));
365365+ Rpc.Types.treview = ((function | a0 -> Report_warning a0))
366366+ };
367367+ BoxedTag
368368+ {
369369+ Rpc.Types.tname = "Report_warning_as_error";
370370+ Rpc.Types.tcontents = ((let open Rpc.Types in Basic String));
371371+ Rpc.Types.tversion = None;
372372+ Rpc.Types.tdescription = [];
373373+ Rpc.Types.tpreview =
374374+ ((function
375375+ | Report_warning_as_error a0 -> Some a0
376376+ | _ -> None));
377377+ Rpc.Types.treview =
378378+ ((function | a0 -> Report_warning_as_error a0))
379379+ };
380380+ BoxedTag
381381+ {
382382+ Rpc.Types.tname = "Report_alert";
383383+ Rpc.Types.tcontents = ((let open Rpc.Types in Basic String));
384384+ Rpc.Types.tversion = None;
385385+ Rpc.Types.tdescription = [];
386386+ Rpc.Types.tpreview =
387387+ ((function | Report_alert a0 -> Some a0 | _ -> None));
388388+ Rpc.Types.treview = ((function | a0 -> Report_alert a0))
389389+ };
390390+ BoxedTag
391391+ {
392392+ Rpc.Types.tname = "Report_alert_as_error";
393393+ Rpc.Types.tcontents = ((let open Rpc.Types in Basic String));
394394+ Rpc.Types.tversion = None;
395395+ Rpc.Types.tdescription = [];
396396+ Rpc.Types.tpreview =
397397+ ((function
398398+ | Report_alert_as_error a0 -> Some a0
399399+ | _ -> None));
400400+ Rpc.Types.treview =
401401+ ((function | a0 -> Report_alert_as_error a0))
402402+ }];
403403+ Rpc.Types.vdefault = None;
404404+ Rpc.Types.vversion = None;
405405+ Rpc.Types.vconstructor =
406406+ (fun s' ->
407407+ fun t ->
408408+ let s = String.lowercase_ascii s' in
409409+ match s with
410410+ | "report_error" ->
411411+ Rresult.R.bind (t.tget Unit)
412412+ (function | () -> Rresult.R.ok Report_error)
413413+ | "report_warning" ->
414414+ Rresult.R.bind
415415+ (t.tget (let open Rpc.Types in Basic String))
416416+ (function | a0 -> Rresult.R.ok (Report_warning a0))
417417+ | "report_warning_as_error" ->
418418+ Rresult.R.bind
419419+ (t.tget (let open Rpc.Types in Basic String))
420420+ (function
421421+ | a0 -> Rresult.R.ok (Report_warning_as_error a0))
422422+ | "report_alert" ->
423423+ Rresult.R.bind
424424+ (t.tget (let open Rpc.Types in Basic String))
425425+ (function | a0 -> Rresult.R.ok (Report_alert a0))
426426+ | "report_alert_as_error" ->
427427+ Rresult.R.bind
428428+ (t.tget (let open Rpc.Types in Basic String))
429429+ (function
430430+ | a0 -> Rresult.R.ok (Report_alert_as_error a0))
431431+ | _ ->
432432+ Rresult.R.error_msg
433433+ (Printf.sprintf "Unknown tag '%s'" s))
434434+ } : location_report_kind Rpc.Types.variant)
435435+ and location_report_kind =
436436+ {
437437+ Rpc.Types.name = "location_report_kind";
438438+ Rpc.Types.description = [];
439439+ Rpc.Types.ty = typ_of_location_report_kind
440440+ }
441441+ let _ = typ_of_location_report_kind
442442+ and _ = location_report_kind
443443+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
444444+type source = string[@@deriving rpcty]
445445+include
446446+ struct
447447+ let _ = fun (_ : source) -> ()
448448+ let rec typ_of_source = let open Rpc.Types in Basic String
449449+ and source =
450450+ {
451451+ Rpc.Types.name = "source";
452452+ Rpc.Types.description = [];
453453+ Rpc.Types.ty = typ_of_source
454454+ }
455455+ let _ = typ_of_source
456456+ and _ = source
457457+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
458458+[@@@ocaml.text
459459+ " CMIs are provided either statically or as URLs to be downloaded on demand "]
460460+[@@@ocaml.text
461461+ " Dynamic cmis are loaded from beneath the given url. In addition the\n top-level modules are specified, and prefixes for other modules. For\n example, for the OCaml standard library, a user might pass:\n\n {[\n { dcs_url=\"/static/stdlib\";\n dcs_toplevel_modules=[\"Stdlib\"];\n dcs_file_prefixes=[\"stdlib__\"]; }\n ]}\n\n In which case, merlin will expect to be able to download a valid file\n from the url [\"/static/stdlib/stdlib.cmi\"] corresponding to the\n specified toplevel module, and it will also attempt to download any\n module with the prefix [\"Stdlib__\"] from the same base url, so for\n example if an attempt is made to look up the module [\"Stdlib__Foo\"]\n then merlin-js will attempt to download a file from the url\n [\"/static/stdlib/stdlib__Foo.cmi\"].\n "]
462462+type dynamic_cmis =
463463+ {
464464+ dcs_url: string ;
465465+ dcs_toplevel_modules: string list ;
466466+ dcs_file_prefixes: string list }
467467+and static_cmi = {
468468+ sc_name: string ;
469469+ sc_content: string }
470470+and cmis = {
471471+ static_cmis: static_cmi list ;
472472+ dynamic_cmis: dynamic_cmis option }[@@deriving rpcty]
473473+include
474474+ struct
475475+ let _ = fun (_ : dynamic_cmis) -> ()
476476+ let _ = fun (_ : static_cmi) -> ()
477477+ let _ = fun (_ : cmis) -> ()
478478+ let rec dynamic_cmis_dcs_url : (_, dynamic_cmis) Rpc.Types.field =
479479+ {
480480+ Rpc.Types.fname = "dcs_url";
481481+ Rpc.Types.field = (let open Rpc.Types in Basic String);
482482+ Rpc.Types.fdefault = None;
483483+ Rpc.Types.fdescription = [];
484484+ Rpc.Types.fversion = None;
485485+ Rpc.Types.fget = (fun _r -> _r.dcs_url);
486486+ Rpc.Types.fset = (fun v -> fun _s -> { _s with dcs_url = v })
487487+ }
488488+ and dynamic_cmis_dcs_toplevel_modules : (_, dynamic_cmis) Rpc.Types.field
489489+ =
490490+ {
491491+ Rpc.Types.fname = "dcs_toplevel_modules";
492492+ Rpc.Types.field =
493493+ (Rpc.Types.List (let open Rpc.Types in Basic String));
494494+ Rpc.Types.fdefault = None;
495495+ Rpc.Types.fdescription = [];
496496+ Rpc.Types.fversion = None;
497497+ Rpc.Types.fget = (fun _r -> _r.dcs_toplevel_modules);
498498+ Rpc.Types.fset =
499499+ (fun v -> fun _s -> { _s with dcs_toplevel_modules = v })
500500+ }
501501+ and dynamic_cmis_dcs_file_prefixes : (_, dynamic_cmis) Rpc.Types.field =
502502+ {
503503+ Rpc.Types.fname = "dcs_file_prefixes";
504504+ Rpc.Types.field =
505505+ (Rpc.Types.List (let open Rpc.Types in Basic String));
506506+ Rpc.Types.fdefault = None;
507507+ Rpc.Types.fdescription = [];
508508+ Rpc.Types.fversion = None;
509509+ Rpc.Types.fget = (fun _r -> _r.dcs_file_prefixes);
510510+ Rpc.Types.fset =
511511+ (fun v -> fun _s -> { _s with dcs_file_prefixes = v })
512512+ }
513513+ and typ_of_dynamic_cmis =
514514+ Rpc.Types.Struct
515515+ ({
516516+ Rpc.Types.fields =
517517+ [Rpc.Types.BoxedField dynamic_cmis_dcs_url;
518518+ Rpc.Types.BoxedField dynamic_cmis_dcs_toplevel_modules;
519519+ Rpc.Types.BoxedField dynamic_cmis_dcs_file_prefixes];
520520+ Rpc.Types.sname = "dynamic_cmis";
521521+ Rpc.Types.version = None;
522522+ Rpc.Types.constructor =
523523+ (fun getter ->
524524+ let open Rresult.R in
525525+ (getter.Rpc.Types.field_get "dcs_file_prefixes"
526526+ (Rpc.Types.List (let open Rpc.Types in Basic String)))
527527+ >>=
528528+ (fun dynamic_cmis_dcs_file_prefixes ->
529529+ (getter.Rpc.Types.field_get "dcs_toplevel_modules"
530530+ (Rpc.Types.List
531531+ (let open Rpc.Types in Basic String)))
532532+ >>=
533533+ (fun dynamic_cmis_dcs_toplevel_modules ->
534534+ (getter.Rpc.Types.field_get "dcs_url"
535535+ (let open Rpc.Types in Basic String))
536536+ >>=
537537+ (fun dynamic_cmis_dcs_url ->
538538+ return
539539+ {
540540+ dcs_url = dynamic_cmis_dcs_url;
541541+ dcs_toplevel_modules =
542542+ dynamic_cmis_dcs_toplevel_modules;
543543+ dcs_file_prefixes =
544544+ dynamic_cmis_dcs_file_prefixes
545545+ }))))
546546+ } : dynamic_cmis Rpc.Types.structure)
547547+ and dynamic_cmis =
548548+ {
549549+ Rpc.Types.name = "dynamic_cmis";
550550+ Rpc.Types.description = [];
551551+ Rpc.Types.ty = typ_of_dynamic_cmis
552552+ }
553553+ and static_cmi_sc_name : (_, static_cmi) Rpc.Types.field =
554554+ {
555555+ Rpc.Types.fname = "sc_name";
556556+ Rpc.Types.field = (let open Rpc.Types in Basic String);
557557+ Rpc.Types.fdefault = None;
558558+ Rpc.Types.fdescription = [];
559559+ Rpc.Types.fversion = None;
560560+ Rpc.Types.fget = (fun _r -> _r.sc_name);
561561+ Rpc.Types.fset = (fun v -> fun _s -> { _s with sc_name = v })
562562+ }
563563+ and static_cmi_sc_content : (_, static_cmi) Rpc.Types.field =
564564+ {
565565+ Rpc.Types.fname = "sc_content";
566566+ Rpc.Types.field = (let open Rpc.Types in Basic String);
567567+ Rpc.Types.fdefault = None;
568568+ Rpc.Types.fdescription = [];
569569+ Rpc.Types.fversion = None;
570570+ Rpc.Types.fget = (fun _r -> _r.sc_content);
571571+ Rpc.Types.fset = (fun v -> fun _s -> { _s with sc_content = v })
572572+ }
573573+ and typ_of_static_cmi =
574574+ Rpc.Types.Struct
575575+ ({
576576+ Rpc.Types.fields =
577577+ [Rpc.Types.BoxedField static_cmi_sc_name;
578578+ Rpc.Types.BoxedField static_cmi_sc_content];
579579+ Rpc.Types.sname = "static_cmi";
580580+ Rpc.Types.version = None;
581581+ Rpc.Types.constructor =
582582+ (fun getter ->
583583+ let open Rresult.R in
584584+ (getter.Rpc.Types.field_get "sc_content"
585585+ (let open Rpc.Types in Basic String))
586586+ >>=
587587+ (fun static_cmi_sc_content ->
588588+ (getter.Rpc.Types.field_get "sc_name"
589589+ (let open Rpc.Types in Basic String))
590590+ >>=
591591+ (fun static_cmi_sc_name ->
592592+ return
593593+ {
594594+ sc_name = static_cmi_sc_name;
595595+ sc_content = static_cmi_sc_content
596596+ })))
597597+ } : static_cmi Rpc.Types.structure)
598598+ and static_cmi =
599599+ {
600600+ Rpc.Types.name = "static_cmi";
601601+ Rpc.Types.description = [];
602602+ Rpc.Types.ty = typ_of_static_cmi
603603+ }
604604+ and cmis_static_cmis : (_, cmis) Rpc.Types.field =
605605+ {
606606+ Rpc.Types.fname = "static_cmis";
607607+ Rpc.Types.field = (Rpc.Types.List typ_of_static_cmi);
608608+ Rpc.Types.fdefault = None;
609609+ Rpc.Types.fdescription = [];
610610+ Rpc.Types.fversion = None;
611611+ Rpc.Types.fget = (fun _r -> _r.static_cmis);
612612+ Rpc.Types.fset = (fun v -> fun _s -> { _s with static_cmis = v })
613613+ }
614614+ and cmis_dynamic_cmis : (_, cmis) Rpc.Types.field =
615615+ {
616616+ Rpc.Types.fname = "dynamic_cmis";
617617+ Rpc.Types.field = (Rpc.Types.Option typ_of_dynamic_cmis);
618618+ Rpc.Types.fdefault = None;
619619+ Rpc.Types.fdescription = [];
620620+ Rpc.Types.fversion = None;
621621+ Rpc.Types.fget = (fun _r -> _r.dynamic_cmis);
622622+ Rpc.Types.fset = (fun v -> fun _s -> { _s with dynamic_cmis = v })
623623+ }
624624+ and typ_of_cmis =
625625+ Rpc.Types.Struct
626626+ ({
627627+ Rpc.Types.fields =
628628+ [Rpc.Types.BoxedField cmis_static_cmis;
629629+ Rpc.Types.BoxedField cmis_dynamic_cmis];
630630+ Rpc.Types.sname = "cmis";
631631+ Rpc.Types.version = None;
632632+ Rpc.Types.constructor =
633633+ (fun getter ->
634634+ let open Rresult.R in
635635+ (getter.Rpc.Types.field_get "dynamic_cmis"
636636+ (Rpc.Types.Option typ_of_dynamic_cmis))
637637+ >>=
638638+ (fun cmis_dynamic_cmis ->
639639+ (getter.Rpc.Types.field_get "static_cmis"
640640+ (Rpc.Types.List typ_of_static_cmi))
641641+ >>=
642642+ (fun cmis_static_cmis ->
643643+ return
644644+ {
645645+ static_cmis = cmis_static_cmis;
646646+ dynamic_cmis = cmis_dynamic_cmis
647647+ })))
648648+ } : cmis Rpc.Types.structure)
649649+ and cmis =
650650+ {
651651+ Rpc.Types.name = "cmis";
652652+ Rpc.Types.description = [];
653653+ Rpc.Types.ty = typ_of_cmis
654654+ }
655655+ let _ = dynamic_cmis_dcs_url
656656+ and _ = dynamic_cmis_dcs_toplevel_modules
657657+ and _ = dynamic_cmis_dcs_file_prefixes
658658+ and _ = typ_of_dynamic_cmis
659659+ and _ = dynamic_cmis
660660+ and _ = static_cmi_sc_name
661661+ and _ = static_cmi_sc_content
662662+ and _ = typ_of_static_cmi
663663+ and _ = static_cmi
664664+ and _ = cmis_static_cmis
665665+ and _ = cmis_dynamic_cmis
666666+ and _ = typ_of_cmis
667667+ and _ = cmis
668668+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
669669+type action =
670670+ | Complete_prefix of source * Msource.position
671671+ | Type_enclosing of source * Msource.position
672672+ | All_errors of source
673673+ | Add_cmis of cmis
674674+type error =
675675+ {
676676+ kind: location_report_kind ;
677677+ loc: location ;
678678+ main: string ;
679679+ sub: string list ;
680680+ source: location_error_source }[@@deriving rpcty]
681681+include
682682+ struct
683683+ let _ = fun (_ : error) -> ()
684684+ let rec error_kind : (_, error) Rpc.Types.field =
685685+ {
686686+ Rpc.Types.fname = "kind";
687687+ Rpc.Types.field = typ_of_location_report_kind;
688688+ Rpc.Types.fdefault = None;
689689+ Rpc.Types.fdescription = [];
690690+ Rpc.Types.fversion = None;
691691+ Rpc.Types.fget = (fun _r -> _r.kind);
692692+ Rpc.Types.fset = (fun v -> fun _s -> { _s with kind = v })
693693+ }
694694+ and error_loc : (_, error) Rpc.Types.field =
695695+ {
696696+ Rpc.Types.fname = "loc";
697697+ Rpc.Types.field = typ_of_location;
698698+ Rpc.Types.fdefault = None;
699699+ Rpc.Types.fdescription = [];
700700+ Rpc.Types.fversion = None;
701701+ Rpc.Types.fget = (fun _r -> _r.loc);
702702+ Rpc.Types.fset = (fun v -> fun _s -> { _s with loc = v })
703703+ }
704704+ and error_main : (_, error) Rpc.Types.field =
705705+ {
706706+ Rpc.Types.fname = "main";
707707+ Rpc.Types.field = (let open Rpc.Types in Basic String);
708708+ Rpc.Types.fdefault = None;
709709+ Rpc.Types.fdescription = [];
710710+ Rpc.Types.fversion = None;
711711+ Rpc.Types.fget = (fun _r -> _r.main);
712712+ Rpc.Types.fset = (fun v -> fun _s -> { _s with main = v })
713713+ }
714714+ and error_sub : (_, error) Rpc.Types.field =
715715+ {
716716+ Rpc.Types.fname = "sub";
717717+ Rpc.Types.field =
718718+ (Rpc.Types.List (let open Rpc.Types in Basic String));
719719+ Rpc.Types.fdefault = None;
720720+ Rpc.Types.fdescription = [];
721721+ Rpc.Types.fversion = None;
722722+ Rpc.Types.fget = (fun _r -> _r.sub);
723723+ Rpc.Types.fset = (fun v -> fun _s -> { _s with sub = v })
724724+ }
725725+ and error_source : (_, error) Rpc.Types.field =
726726+ {
727727+ Rpc.Types.fname = "source";
728728+ Rpc.Types.field = typ_of_location_error_source;
729729+ Rpc.Types.fdefault = None;
730730+ Rpc.Types.fdescription = [];
731731+ Rpc.Types.fversion = None;
732732+ Rpc.Types.fget = (fun _r -> _r.source);
733733+ Rpc.Types.fset = (fun v -> fun _s -> { _s with source = v })
734734+ }
735735+ and typ_of_error =
736736+ Rpc.Types.Struct
737737+ ({
738738+ Rpc.Types.fields =
739739+ [Rpc.Types.BoxedField error_kind;
740740+ Rpc.Types.BoxedField error_loc;
741741+ Rpc.Types.BoxedField error_main;
742742+ Rpc.Types.BoxedField error_sub;
743743+ Rpc.Types.BoxedField error_source];
744744+ Rpc.Types.sname = "error";
745745+ Rpc.Types.version = None;
746746+ Rpc.Types.constructor =
747747+ (fun getter ->
748748+ let open Rresult.R in
749749+ (getter.Rpc.Types.field_get "source"
750750+ typ_of_location_error_source)
751751+ >>=
752752+ (fun error_source ->
753753+ (getter.Rpc.Types.field_get "sub"
754754+ (Rpc.Types.List
755755+ (let open Rpc.Types in Basic String)))
756756+ >>=
757757+ (fun error_sub ->
758758+ (getter.Rpc.Types.field_get "main"
759759+ (let open Rpc.Types in Basic String))
760760+ >>=
761761+ (fun error_main ->
762762+ (getter.Rpc.Types.field_get "loc"
763763+ typ_of_location)
764764+ >>=
765765+ (fun error_loc ->
766766+ (getter.Rpc.Types.field_get "kind"
767767+ typ_of_location_report_kind)
768768+ >>=
769769+ (fun error_kind ->
770770+ return
771771+ {
772772+ kind = error_kind;
773773+ loc = error_loc;
774774+ main = error_main;
775775+ sub = error_sub;
776776+ source = error_source
777777+ }))))))
778778+ } : error Rpc.Types.structure)
779779+ and error =
780780+ {
781781+ Rpc.Types.name = "error";
782782+ Rpc.Types.description = [];
783783+ Rpc.Types.ty = typ_of_error
784784+ }
785785+ let _ = error_kind
786786+ and _ = error_loc
787787+ and _ = error_main
788788+ and _ = error_sub
789789+ and _ = error_source
790790+ and _ = typ_of_error
791791+ and _ = error
792792+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
793793+type error_list = error list[@@deriving rpcty]
794794+include
795795+ struct
796796+ let _ = fun (_ : error_list) -> ()
797797+ let rec typ_of_error_list = Rpc.Types.List typ_of_error
798798+ and error_list =
799799+ {
800800+ Rpc.Types.name = "error_list";
801801+ Rpc.Types.description = [];
802802+ Rpc.Types.ty = typ_of_error_list
803803+ }
804804+ let _ = typ_of_error_list
805805+ and _ = error_list
806806+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
807807+type kind_ty =
808808+ [ `Constructor | `Keyword | `Label | `MethodCall | `Modtype |
809809+ `Module
810810+ | `Type | `Value | `Variant ]
811811+include
812812+ struct
813813+ open Rpc.Types
814814+ let _ = fun (_ : kind_ty) -> ()
815815+ let rec typ_of_kind_ty =
816816+ let mk tname tpreview treview =
817817+ BoxedTag
818818+ {
819819+ tname;
820820+ tcontents = Unit;
821821+ tversion = None;
822822+ tdescription = [];
823823+ tpreview;
824824+ treview
825825+ } in
826826+ Variant
827827+ ({
828828+ vname = "kind";
829829+ variants =
830830+ [mk "Constructor"
831831+ (function | `Constructor -> Some () | _ -> None)
832832+ (function | () -> `Constructor);
833833+ mk "Keyword" (function | `Keyword -> Some () | _ -> None)
834834+ (function | () -> `Keyword);
835835+ mk "Label" (function | `Label -> Some () | _ -> None)
836836+ (function | () -> `Label);
837837+ mk "MethodCall" (function | `MethodCall -> Some () | _ -> None)
838838+ (function | () -> `MethodCall);
839839+ mk "Modtype" (function | `Modtype -> Some () | _ -> None)
840840+ (function | () -> `Modtype);
841841+ mk "Module" (function | `Module -> Some () | _ -> None)
842842+ (function | () -> `Module);
843843+ mk "Type" (function | `Type -> Some () | _ -> None)
844844+ (function | () -> `Type);
845845+ mk "Value" (function | `Value -> Some () | _ -> None)
846846+ (function | () -> `Value);
847847+ mk "Variant" (function | `Variant -> Some () | _ -> None)
848848+ (function | () -> `Variant)];
849849+ vdefault = None;
850850+ vversion = None;
851851+ vconstructor =
852852+ (fun s' ->
853853+ fun t ->
854854+ let s = String.lowercase_ascii s' in
855855+ match s with
856856+ | "constructor" ->
857857+ Rresult.R.bind (t.tget Unit)
858858+ (function | () -> Rresult.R.ok `Constructor)
859859+ | "keyword" ->
860860+ Rresult.R.bind (t.tget Unit)
861861+ (function | () -> Rresult.R.ok `Keyword)
862862+ | "label" ->
863863+ Rresult.R.bind (t.tget Unit)
864864+ (function | () -> Rresult.R.ok `Label)
865865+ | "methodcall" ->
866866+ Rresult.R.bind (t.tget Unit)
867867+ (function | () -> Rresult.R.ok `MethodCall)
868868+ | "modtype" ->
869869+ Rresult.R.bind (t.tget Unit)
870870+ (function | () -> Rresult.R.ok `Modtype)
871871+ | "module" ->
872872+ Rresult.R.bind (t.tget Unit)
873873+ (function | () -> Rresult.R.ok `Module)
874874+ | "type" ->
875875+ Rresult.R.bind (t.tget Unit)
876876+ (function | () -> Rresult.R.ok `Type)
877877+ | "value" ->
878878+ Rresult.R.bind (t.tget Unit)
879879+ (function | () -> Rresult.R.ok `Value)
880880+ | "variant" ->
881881+ Rresult.R.bind (t.tget Unit)
882882+ (function | () -> Rresult.R.ok `Variant)
883883+ | _ ->
884884+ Rresult.R.error_msg
885885+ (Printf.sprintf "Unknown tag '%s'" s))
886886+ } : kind_ty variant)
887887+ and kind_ty = { name = "kind_ty"; description = []; ty = typ_of_kind_ty }
888888+ let _ = typ_of_kind_ty
889889+ and _ = kind_ty
890890+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
891891+type query_protocol_compl_entry = Query_protocol.Compl.entry
892892+include
893893+ struct
894894+ open Rpc.Types
895895+ let _ = fun (_ : query_protocol_compl_entry) -> ()
896896+ let rec query_protocol_compl_entry_name :
897897+ (_, query_protocol_compl_entry) field =
898898+ {
899899+ fname = "name";
900900+ field = typ_of_source;
901901+ fdefault = None;
902902+ fdescription = [];
903903+ fversion = None;
904904+ fget = (fun _r -> _r.name);
905905+ fset = (fun v -> fun _s -> { _s with name = v })
906906+ }
907907+ and query_protocol_compl_entry_kind :
908908+ (_, query_protocol_compl_entry) field =
909909+ {
910910+ fname = "kind";
911911+ field = typ_of_kind_ty;
912912+ fdefault = None;
913913+ fdescription = [];
914914+ fversion = None;
915915+ fget = (fun _r -> _r.kind);
916916+ fset = (fun v -> fun _s -> { _s with kind = v })
917917+ }
918918+ and query_protocol_compl_entry_desc :
919919+ (_, query_protocol_compl_entry) field =
920920+ {
921921+ fname = "desc";
922922+ field = typ_of_source;
923923+ fdefault = None;
924924+ fdescription = [];
925925+ fversion = None;
926926+ fget = (fun _r -> _r.desc);
927927+ fset = (fun v -> fun _s -> { _s with desc = v })
928928+ }
929929+ and query_protocol_compl_entry_info :
930930+ (_, query_protocol_compl_entry) field =
931931+ {
932932+ fname = "info";
933933+ field = typ_of_source;
934934+ fdefault = None;
935935+ fdescription = [];
936936+ fversion = None;
937937+ fget = (fun _r -> _r.info);
938938+ fset = (fun v -> fun _s -> { _s with info = v })
939939+ }
940940+ and query_protocol_compl_entry_deprecated :
941941+ (_, query_protocol_compl_entry) field =
942942+ {
943943+ fname = "deprecated";
944944+ field = (let open Rpc.Types in Basic Bool);
945945+ fdefault = None;
946946+ fdescription = [];
947947+ fversion = None;
948948+ fget = (fun _r -> _r.deprecated);
949949+ fset = (fun v -> fun _s -> { _s with deprecated = v })
950950+ }
951951+ and typ_of_query_protocol_compl_entry =
952952+ Struct
953953+ ({
954954+ fields =
955955+ [BoxedField query_protocol_compl_entry_name;
956956+ BoxedField query_protocol_compl_entry_kind;
957957+ BoxedField query_protocol_compl_entry_desc;
958958+ BoxedField query_protocol_compl_entry_info;
959959+ BoxedField query_protocol_compl_entry_deprecated];
960960+ sname = "query_protocol_compl_entry";
961961+ version = None;
962962+ constructor =
963963+ (fun getter ->
964964+ let open Rresult.R in
965965+ (getter.field_get "deprecated"
966966+ (let open Rpc.Types in Basic Bool))
967967+ >>=
968968+ (fun query_protocol_compl_entry_deprecated ->
969969+ (getter.field_get "info" typ_of_source) >>=
970970+ (fun query_protocol_compl_entry_info ->
971971+ (getter.field_get "desc" typ_of_source) >>=
972972+ (fun query_protocol_compl_entry_desc ->
973973+ (getter.field_get "kind" typ_of_kind_ty) >>=
974974+ (fun query_protocol_compl_entry_kind ->
975975+ (getter.field_get "name" typ_of_source)
976976+ >>=
977977+ (fun query_protocol_compl_entry_name
978978+ ->
979979+ return
980980+ {
981981+ Query_protocol.Compl.name =
982982+ query_protocol_compl_entry_name;
983983+ kind =
984984+ query_protocol_compl_entry_kind;
985985+ desc =
986986+ query_protocol_compl_entry_desc;
987987+ info =
988988+ query_protocol_compl_entry_info;
989989+ deprecated =
990990+ query_protocol_compl_entry_deprecated
991991+ }))))))
992992+ } : query_protocol_compl_entry structure)
993993+ and query_protocol_compl_entry =
994994+ {
995995+ name = "query_protocol_compl_entry";
996996+ description = [];
997997+ ty = typ_of_query_protocol_compl_entry
998998+ }
999999+ let _ = query_protocol_compl_entry_name
10001000+ and _ = query_protocol_compl_entry_kind
10011001+ and _ = query_protocol_compl_entry_desc
10021002+ and _ = query_protocol_compl_entry_info
10031003+ and _ = query_protocol_compl_entry_deprecated
10041004+ and _ = typ_of_query_protocol_compl_entry
10051005+ and _ = query_protocol_compl_entry
10061006+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
10071007+include
10081008+ struct
10091009+ open Rpc.Types
10101010+ let _ = fun (_ : Merlin_kernel.Msource.position) -> ()
10111011+ let rec typ_of_msource_position =
10121012+ Variant
10131013+ ({
10141014+ vname = "msource_position";
10151015+ variants =
10161016+ [BoxedTag
10171017+ {
10181018+ tname = "Start";
10191019+ tcontents = Unit;
10201020+ tversion = None;
10211021+ tdescription = [];
10221022+ tpreview = ((function | `Start -> Some () | _ -> None));
10231023+ treview = ((function | () -> `Start))
10241024+ };
10251025+ BoxedTag
10261026+ {
10271027+ tname = "Offset";
10281028+ tcontents = ((let open Rpc.Types in Basic Int));
10291029+ tversion = None;
10301030+ tdescription = [];
10311031+ tpreview = ((function | `Offset a0 -> Some a0 | _ -> None));
10321032+ treview = ((function | a0 -> `Offset a0))
10331033+ };
10341034+ BoxedTag
10351035+ {
10361036+ tname = "Logical";
10371037+ tcontents =
10381038+ (Tuple
10391039+ (((let open Rpc.Types in Basic Int)),
10401040+ ((let open Rpc.Types in Basic Int))));
10411041+ tversion = None;
10421042+ tdescription = [];
10431043+ tpreview =
10441044+ ((function
10451045+ | `Logical (a0, a1) -> Some (a0, a1)
10461046+ | _ -> None));
10471047+ treview = ((function | (a0, a1) -> `Logical (a0, a1)))
10481048+ };
10491049+ BoxedTag
10501050+ {
10511051+ tname = "End";
10521052+ tcontents = Unit;
10531053+ tversion = None;
10541054+ tdescription = [];
10551055+ tpreview = ((function | `End -> Some () | _ -> None));
10561056+ treview = ((function | () -> `End))
10571057+ }];
10581058+ vdefault = None;
10591059+ vversion = None;
10601060+ vconstructor =
10611061+ (fun s' ->
10621062+ fun t ->
10631063+ let s = String.lowercase_ascii s' in
10641064+ match s with
10651065+ | "start" ->
10661066+ Rresult.R.bind (t.tget Unit)
10671067+ (function | () -> Rresult.R.ok `Start)
10681068+ | "offset" ->
10691069+ Rresult.R.bind
10701070+ (t.tget (let open Rpc.Types in Basic Int))
10711071+ (function | a0 -> Rresult.R.ok (`Offset a0))
10721072+ | "logical" ->
10731073+ Rresult.R.bind
10741074+ (t.tget
10751075+ (Tuple
10761076+ ((let open Rpc.Types in Basic Int),
10771077+ (let open Rpc.Types in Basic Int))))
10781078+ (function
10791079+ | (a0, a1) -> Rresult.R.ok (`Logical (a0, a1)))
10801080+ | "end" ->
10811081+ Rresult.R.bind (t.tget Unit)
10821082+ (function | () -> Rresult.R.ok `End)
10831083+ | _ ->
10841084+ Rresult.R.error_msg
10851085+ (Printf.sprintf "Unknown tag '%s'" s))
10861086+ } : Merlin_kernel.Msource.position variant)
10871087+ and msource_position =
10881088+ {
10891089+ name = "msource_position";
10901090+ description = [];
10911091+ ty = typ_of_msource_position
10921092+ }
10931093+ let _ = typ_of_msource_position
10941094+ and _ = msource_position
10951095+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
10961096+type completions =
10971097+ {
10981098+ from: int ;
10991099+ to_: int ;
11001100+ entries: query_protocol_compl_entry list }[@@deriving rpcty]
11011101+include
11021102+ struct
11031103+ let _ = fun (_ : completions) -> ()
11041104+ let rec completions_from : (_, completions) Rpc.Types.field =
11051105+ {
11061106+ Rpc.Types.fname = "from";
11071107+ Rpc.Types.field = (let open Rpc.Types in Basic Int);
11081108+ Rpc.Types.fdefault = None;
11091109+ Rpc.Types.fdescription = [];
11101110+ Rpc.Types.fversion = None;
11111111+ Rpc.Types.fget = (fun _r -> _r.from);
11121112+ Rpc.Types.fset = (fun v -> fun _s -> { _s with from = v })
11131113+ }
11141114+ and completions_to_ : (_, completions) Rpc.Types.field =
11151115+ {
11161116+ Rpc.Types.fname = "to_";
11171117+ Rpc.Types.field = (let open Rpc.Types in Basic Int);
11181118+ Rpc.Types.fdefault = None;
11191119+ Rpc.Types.fdescription = [];
11201120+ Rpc.Types.fversion = None;
11211121+ Rpc.Types.fget = (fun _r -> _r.to_);
11221122+ Rpc.Types.fset = (fun v -> fun _s -> { _s with to_ = v })
11231123+ }
11241124+ and completions_entries : (_, completions) Rpc.Types.field =
11251125+ {
11261126+ Rpc.Types.fname = "entries";
11271127+ Rpc.Types.field = (Rpc.Types.List typ_of_query_protocol_compl_entry);
11281128+ Rpc.Types.fdefault = None;
11291129+ Rpc.Types.fdescription = [];
11301130+ Rpc.Types.fversion = None;
11311131+ Rpc.Types.fget = (fun _r -> _r.entries);
11321132+ Rpc.Types.fset = (fun v -> fun _s -> { _s with entries = v })
11331133+ }
11341134+ and typ_of_completions =
11351135+ Rpc.Types.Struct
11361136+ ({
11371137+ Rpc.Types.fields =
11381138+ [Rpc.Types.BoxedField completions_from;
11391139+ Rpc.Types.BoxedField completions_to_;
11401140+ Rpc.Types.BoxedField completions_entries];
11411141+ Rpc.Types.sname = "completions";
11421142+ Rpc.Types.version = None;
11431143+ Rpc.Types.constructor =
11441144+ (fun getter ->
11451145+ let open Rresult.R in
11461146+ (getter.Rpc.Types.field_get "entries"
11471147+ (Rpc.Types.List typ_of_query_protocol_compl_entry))
11481148+ >>=
11491149+ (fun completions_entries ->
11501150+ (getter.Rpc.Types.field_get "to_"
11511151+ (let open Rpc.Types in Basic Int))
11521152+ >>=
11531153+ (fun completions_to_ ->
11541154+ (getter.Rpc.Types.field_get "from"
11551155+ (let open Rpc.Types in Basic Int))
11561156+ >>=
11571157+ (fun completions_from ->
11581158+ return
11591159+ {
11601160+ from = completions_from;
11611161+ to_ = completions_to_;
11621162+ entries = completions_entries
11631163+ }))))
11641164+ } : completions Rpc.Types.structure)
11651165+ and completions =
11661166+ {
11671167+ Rpc.Types.name = "completions";
11681168+ Rpc.Types.description = [];
11691169+ Rpc.Types.ty = typ_of_completions
11701170+ }
11711171+ let _ = completions_from
11721172+ and _ = completions_to_
11731173+ and _ = completions_entries
11741174+ and _ = typ_of_completions
11751175+ and _ = completions
11761176+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
11771177+type is_tail_position = [ `No | `Tail_position | `Tail_call ]
11781178+include
11791179+ struct
11801180+ open Rpc.Types
11811181+ let _ = fun (_ : is_tail_position) -> ()
11821182+ let rec typ_of_is_tail_position =
11831183+ Variant
11841184+ ({
11851185+ vname = "is_tail_position";
11861186+ variants =
11871187+ [BoxedTag
11881188+ {
11891189+ tname = "No";
11901190+ tcontents = Unit;
11911191+ tversion = None;
11921192+ tdescription = [];
11931193+ tpreview = ((function | `No -> Some () | _ -> None));
11941194+ treview = ((function | () -> `No))
11951195+ };
11961196+ BoxedTag
11971197+ {
11981198+ tname = "Tail_position";
11991199+ tcontents = Unit;
12001200+ tversion = None;
12011201+ tdescription = [];
12021202+ tpreview =
12031203+ ((function | `Tail_position -> Some () | _ -> None));
12041204+ treview = ((function | () -> `Tail_position))
12051205+ };
12061206+ BoxedTag
12071207+ {
12081208+ tname = "Tail_call";
12091209+ tcontents = Unit;
12101210+ tversion = None;
12111211+ tdescription = [];
12121212+ tpreview = ((function | `Tail_call -> Some () | _ -> None));
12131213+ treview = ((function | () -> `Tail_call))
12141214+ }];
12151215+ vdefault = None;
12161216+ vversion = None;
12171217+ vconstructor =
12181218+ (fun s' ->
12191219+ fun t ->
12201220+ let s = String.lowercase_ascii s' in
12211221+ match s with
12221222+ | "no" ->
12231223+ Rresult.R.bind (t.tget Unit)
12241224+ (function | () -> Rresult.R.ok `No)
12251225+ | "tail_position" ->
12261226+ Rresult.R.bind (t.tget Unit)
12271227+ (function | () -> Rresult.R.ok `Tail_position)
12281228+ | "tail_call" ->
12291229+ Rresult.R.bind (t.tget Unit)
12301230+ (function | () -> Rresult.R.ok `Tail_call)
12311231+ | _ ->
12321232+ Rresult.R.error_msg
12331233+ (Printf.sprintf "Unknown tag '%s'" s))
12341234+ } : is_tail_position variant)
12351235+ and is_tail_position =
12361236+ {
12371237+ name = "is_tail_position";
12381238+ description = [];
12391239+ ty = typ_of_is_tail_position
12401240+ }
12411241+ let _ = typ_of_is_tail_position
12421242+ and _ = is_tail_position
12431243+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
12441244+type index_or_string = [ `Index of int | `String of string ]
12451245+include
12461246+ struct
12471247+ open Rpc.Types
12481248+ let _ = fun (_ : index_or_string) -> ()
12491249+ let rec typ_of_index_or_string =
12501250+ Variant
12511251+ ({
12521252+ vname = "index_or_string";
12531253+ variants =
12541254+ [BoxedTag
12551255+ {
12561256+ tname = "Index";
12571257+ tcontents = ((let open Rpc.Types in Basic Int));
12581258+ tversion = None;
12591259+ tdescription = [];
12601260+ tpreview = ((function | `Index a0 -> Some a0 | _ -> None));
12611261+ treview = ((function | a0 -> `Index a0))
12621262+ };
12631263+ BoxedTag
12641264+ {
12651265+ tname = "String";
12661266+ tcontents = ((let open Rpc.Types in Basic String));
12671267+ tversion = None;
12681268+ tdescription = [];
12691269+ tpreview = ((function | `String a0 -> Some a0 | _ -> None));
12701270+ treview = ((function | a0 -> `String a0))
12711271+ }];
12721272+ vdefault = None;
12731273+ vversion = None;
12741274+ vconstructor =
12751275+ (fun s' ->
12761276+ fun t ->
12771277+ let s = String.lowercase_ascii s' in
12781278+ match s with
12791279+ | "index" ->
12801280+ Rresult.R.bind
12811281+ (t.tget (let open Rpc.Types in Basic Int))
12821282+ (function | a0 -> Rresult.R.ok (`Index a0))
12831283+ | "string" ->
12841284+ Rresult.R.bind
12851285+ (t.tget (let open Rpc.Types in Basic String))
12861286+ (function | a0 -> Rresult.R.ok (`String a0))
12871287+ | _ ->
12881288+ Rresult.R.error_msg
12891289+ (Printf.sprintf "Unknown tag '%s'" s))
12901290+ } : index_or_string variant)
12911291+ and index_or_string =
12921292+ {
12931293+ name = "index_or_string";
12941294+ description = [];
12951295+ ty = typ_of_index_or_string
12961296+ }
12971297+ let _ = typ_of_index_or_string
12981298+ and _ = index_or_string
12991299+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
13001300+type typed_enclosings = (location * index_or_string * is_tail_position)
13011301+[@@deriving rpcty]
13021302+include
13031303+ struct
13041304+ let _ = fun (_ : typed_enclosings) -> ()
13051305+ let rec typ_of_typed_enclosings =
13061306+ Rpc.Types.Tuple3
13071307+ (typ_of_location, typ_of_index_or_string, typ_of_is_tail_position)
13081308+ and typed_enclosings =
13091309+ {
13101310+ Rpc.Types.name = "typed_enclosings";
13111311+ Rpc.Types.description = [];
13121312+ Rpc.Types.ty = typ_of_typed_enclosings
13131313+ }
13141314+ let _ = typ_of_typed_enclosings
13151315+ and _ = typed_enclosings
13161316+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
13171317+type typed_enclosings_list = typed_enclosings list[@@deriving rpcty]
13181318+include
13191319+ struct
13201320+ let _ = fun (_ : typed_enclosings_list) -> ()
13211321+ let rec typ_of_typed_enclosings_list =
13221322+ Rpc.Types.List typ_of_typed_enclosings
13231323+ and typed_enclosings_list =
13241324+ {
13251325+ Rpc.Types.name = "typed_enclosings_list";
13261326+ Rpc.Types.description = [];
13271327+ Rpc.Types.ty = typ_of_typed_enclosings_list
13281328+ }
13291329+ let _ = typ_of_typed_enclosings_list
13301330+ and _ = typed_enclosings_list
13311331+ end[@@ocaml.doc "@inline"][@@merlin.hide ]
13321332+let report_source_to_string =
13331333+ function
13341334+ | Location.Lexer -> "lexer"
13351335+ | Location.Parser -> "parser"
13361336+ | Location.Typer -> "typer"
13371337+ | Location.Warning -> "warning"
13381338+ | Location.Unknown -> "unknown"
13391339+ | Location.Env -> "env"
13401340+ | Location.Config -> "config"
211341type highlight = {
221342 line1: int ;
231343 line2: int ;
···4071727 and _ = typ_of_exec_result
4081728 and _ = exec_result
4091729 end[@@ocaml.doc "@inline"][@@merlin.hide ]
410410-type completion_result =
411411- {
412412- n: int
413413- [@ocaml.doc
414414- " The position in the input string from where the completions may be\n inserted "];
415415- completions: string list [@ocaml.doc " The list of possible completions "]}
416416-[@@deriving rpcty][@@ocaml.doc " The result returned by a 'complete' call. "]
417417-include
418418- struct
419419- let _ = fun (_ : completion_result) -> ()
420420- let rec completion_result_n : (_, completion_result) Rpc.Types.field =
421421- {
422422- Rpc.Types.fname = "n";
423423- Rpc.Types.field = (let open Rpc.Types in Basic Int);
424424- Rpc.Types.fdefault = None;
425425- Rpc.Types.fdescription =
426426- ["The position in the input string from where the completions may be";
427427- "inserted"];
428428- Rpc.Types.fversion = None;
429429- Rpc.Types.fget = (fun _r -> _r.n);
430430- Rpc.Types.fset = (fun v -> fun _s -> { _s with n = v })
431431- }
432432- and completion_result_completions :
433433- (_, completion_result) Rpc.Types.field =
434434- {
435435- Rpc.Types.fname = "completions";
436436- Rpc.Types.field =
437437- (Rpc.Types.List (let open Rpc.Types in Basic String));
438438- Rpc.Types.fdefault = None;
439439- Rpc.Types.fdescription = ["The list of possible completions"];
440440- Rpc.Types.fversion = None;
441441- Rpc.Types.fget = (fun _r -> _r.completions);
442442- Rpc.Types.fset = (fun v -> fun _s -> { _s with completions = v })
443443- }
444444- and typ_of_completion_result =
445445- Rpc.Types.Struct
446446- ({
447447- Rpc.Types.fields =
448448- [Rpc.Types.BoxedField completion_result_n;
449449- Rpc.Types.BoxedField completion_result_completions];
450450- Rpc.Types.sname = "completion_result";
451451- Rpc.Types.version = None;
452452- Rpc.Types.constructor =
453453- (fun getter ->
454454- let open Rresult.R in
455455- (getter.Rpc.Types.field_get "completions"
456456- (Rpc.Types.List (let open Rpc.Types in Basic String)))
457457- >>=
458458- (fun completion_result_completions ->
459459- (getter.Rpc.Types.field_get "n"
460460- (let open Rpc.Types in Basic Int))
461461- >>=
462462- (fun completion_result_n ->
463463- return
464464- {
465465- n = completion_result_n;
466466- completions = completion_result_completions
467467- })))
468468- } : completion_result Rpc.Types.structure)
469469- and completion_result =
470470- {
471471- Rpc.Types.name = "completion_result";
472472- Rpc.Types.description = ["The result returned by a 'complete' call."];
473473- Rpc.Types.ty = typ_of_completion_result
474474- }
475475- let _ = completion_result_n
476476- and _ = completion_result_completions
477477- and _ = typ_of_completion_result
478478- and _ = completion_result
479479- end[@@ocaml.doc "@inline"][@@merlin.hide ]
4801730type cma =
4811731 {
4821732 url: string [@ocaml.doc " URL where the cma is available "];
···5371787 and _ = cma
5381788 end[@@ocaml.doc "@inline"][@@merlin.hide ]
5391789type init_libs = {
540540- cmi_urls: string list ;
17901790+ path: string ;
17911791+ cmis: cmis ;
5411792 cmas: cma list }[@@deriving rpcty]
5421793include
5431794 struct
5441795 let _ = fun (_ : init_libs) -> ()
545545- let rec init_libs_cmi_urls : (_, init_libs) Rpc.Types.field =
17961796+ let rec init_libs_path : (_, init_libs) Rpc.Types.field =
17971797+ {
17981798+ Rpc.Types.fname = "path";
17991799+ Rpc.Types.field = (let open Rpc.Types in Basic String);
18001800+ Rpc.Types.fdefault = None;
18011801+ Rpc.Types.fdescription = [];
18021802+ Rpc.Types.fversion = None;
18031803+ Rpc.Types.fget = (fun _r -> _r.path);
18041804+ Rpc.Types.fset = (fun v -> fun _s -> { _s with path = v })
18051805+ }
18061806+ and init_libs_cmis : (_, init_libs) Rpc.Types.field =
5461807 {
547547- Rpc.Types.fname = "cmi_urls";
548548- Rpc.Types.field =
549549- (Rpc.Types.List (let open Rpc.Types in Basic String));
18081808+ Rpc.Types.fname = "cmis";
18091809+ Rpc.Types.field = typ_of_cmis;
5501810 Rpc.Types.fdefault = None;
5511811 Rpc.Types.fdescription = [];
5521812 Rpc.Types.fversion = None;
553553- Rpc.Types.fget = (fun _r -> _r.cmi_urls);
554554- Rpc.Types.fset = (fun v -> fun _s -> { _s with cmi_urls = v })
18131813+ Rpc.Types.fget = (fun _r -> _r.cmis);
18141814+ Rpc.Types.fset = (fun v -> fun _s -> { _s with cmis = v })
5551815 }
5561816 and init_libs_cmas : (_, init_libs) Rpc.Types.field =
5571817 {
···5671827 Rpc.Types.Struct
5681828 ({
5691829 Rpc.Types.fields =
570570- [Rpc.Types.BoxedField init_libs_cmi_urls;
18301830+ [Rpc.Types.BoxedField init_libs_path;
18311831+ Rpc.Types.BoxedField init_libs_cmis;
5711832 Rpc.Types.BoxedField init_libs_cmas];
5721833 Rpc.Types.sname = "init_libs";
5731834 Rpc.Types.version = None;
···5781839 (Rpc.Types.List typ_of_cma))
5791840 >>=
5801841 (fun init_libs_cmas ->
581581- (getter.Rpc.Types.field_get "cmi_urls"
582582- (Rpc.Types.List
583583- (let open Rpc.Types in Basic String)))
584584- >>=
585585- (fun init_libs_cmi_urls ->
586586- return
587587- {
588588- cmi_urls = init_libs_cmi_urls;
589589- cmas = init_libs_cmas
590590- })))
18421842+ (getter.Rpc.Types.field_get "cmis" typ_of_cmis) >>=
18431843+ (fun init_libs_cmis ->
18441844+ (getter.Rpc.Types.field_get "path"
18451845+ (let open Rpc.Types in Basic String))
18461846+ >>=
18471847+ (fun init_libs_path ->
18481848+ return
18491849+ {
18501850+ path = init_libs_path;
18511851+ cmis = init_libs_cmis;
18521852+ cmas = init_libs_cmas
18531853+ }))))
5911854 } : init_libs Rpc.Types.structure)
5921855 and init_libs =
5931856 {
···5951858 Rpc.Types.description = [];
5961859 Rpc.Types.ty = typ_of_init_libs
5971860 }
598598- let _ = init_libs_cmi_urls
18611861+ let _ = init_libs_path
18621862+ and _ = init_libs_cmis
5991863 and _ = init_libs_cmas
6001864 and _ = typ_of_init_libs
6011865 and _ = init_libs
···6681932 let implementation = implement description
6691933 let unit_p = Param.mk Types.unit
6701934 let phrase_p = Param.mk Types.string
19351935+ let id_p = Param.mk Types.string
6711936 let typecheck_result_p = Param.mk exec_result
6721937 let exec_result_p = Param.mk exec_result
673673- let completion_p = Param.mk completion_result
19381938+ let source_p = Param.mk source
19391939+ let position_p = Param.mk msource_position
19401940+ let completions_p = Param.mk completions
19411941+ let error_list_p = Param.mk error_list
19421942+ let typed_enclosings_p = Param.mk typed_enclosings_list
6741943 let init_libs =
6751944 Param.mk ~name:"init_libs"
6761945 ~description:["Libraries to load during the initialisation of the toplevel. ";
···6951964 declare "exec"
6961965 ["Execute a phrase using the toplevel. The toplevel must have been";
6971966 "Initialised first."] (phrase_p @-> (returning exec_result_p err))
698698- let complete =
699699- declare "complete"
700700- ["Find completions of the incomplete phrase. Completion occurs at the";
701701- "end of the phrase passed in. If completion is required at a point";
702702- "other than the end of a string, then take the substring before calling";
703703- "this API."] (phrase_p @-> (returning completion_p err))
19671967+ let compile_js =
19681968+ declare "compile_js"
19691969+ ["Compile a phrase to javascript. The toplevel must have been";
19701970+ "Initialised first."]
19711971+ (id_p @-> (phrase_p @-> (returning phrase_p err)))
19721972+ let complete_prefix =
19731973+ declare "complete_prefix" ["Complete a prefix"]
19741974+ (source_p @-> (position_p @-> (returning completions_p err)))
19751975+ let query_errors =
19761976+ declare "query_errors" ["Query the errors in the given source"]
19771977+ (source_p @-> (returning error_list_p err))
19781978+ let type_enclosing =
19791979+ declare "type_enclosing" ["Get the type of the enclosing expression"]
19801980+ (source_p @-> (position_p @-> (returning typed_enclosings_p err)))
7041981 end
···11+(* Implementation *)
22+open Js_top_worker_rpc
33+module M = Idl.IdM (* Server is synchronous *)
44+module IdlM = Idl.Make (M)
55+66+type captured = { stdout : string; stderr : string }
77+88+module type S = sig
99+ val capture : (unit -> 'a) -> unit -> captured * 'a
1010+ val create_file : name:string -> content:string -> unit
1111+ val sync_get : string -> string option
1212+end
1313+1414+module Make (S : S) = struct
1515+ let functions : (unit -> unit) list option ref = ref None
1616+ let path : string option ref = ref None
1717+1818+ let refill_lexbuf s p ppf buffer len =
1919+ if !p = String.length s then 0
2020+ else
2121+ let len', nl =
2222+ try (String.index_from s !p '\n' - !p + 1, false)
2323+ with _ -> (String.length s - !p, true)
2424+ in
2525+ let len'' = min len len' in
2626+ String.blit s !p buffer 0 len'';
2727+ (match ppf with
2828+ | Some ppf ->
2929+ Format.fprintf ppf "%s" (Bytes.sub_string buffer 0 len'');
3030+ if nl then Format.pp_print_newline ppf ();
3131+ Format.pp_print_flush ppf ()
3232+ | None -> ());
3333+ p := !p + len'';
3434+ len''
3535+3636+ (* RPC function implementations *)
3737+3838+ (* These are all required to return the appropriate value for the API within the
3939+ [IdlM.T] monad. The simplest way to do this is to use [IdlM.ErrM.return] for
4040+ the success case and [IdlM.ErrM.return_err] for the failure case *)
4141+4242+ let exec' s =
4343+ S.capture
4444+ (fun () ->
4545+ let res : bool = Toploop.use_silently Format.std_formatter (String s) in
4646+ if not res then Format.eprintf "error while evaluating %s@." s)
4747+ ()
4848+4949+ let setup functions () =
5050+ let stdout_buff = Buffer.create 100 in
5151+ let stderr_buff = Buffer.create 100 in
5252+5353+ let combine o =
5454+ Buffer.add_string stdout_buff o.stdout;
5555+ Buffer.add_string stderr_buff o.stderr
5656+ in
5757+5858+ let exec' s =
5959+ let o, () = exec' s in
6060+ combine o
6161+ in
6262+ Logs.info (fun m -> m "Setting up toplevel");
6363+ Sys.interactive := false;
6464+ Logs.info (fun m -> m "Finished this bit 1");
6565+6666+ Toploop.input_name := "//toplevel//";
6767+ Logs.info (fun m -> m "Finished this bit 2");
6868+ let path =
6969+ match !path with Some p -> p | None -> failwith "Path not set"
7070+ in
7171+7272+ Topdirs.dir_directory path;
7373+7474+ 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");
8383+ Toploop.initialize_toplevel_env ();
8484+ Logs.info (fun m -> m "Finished this bit 4");
8585+8686+ List.iter (fun f -> f ()) functions;
8787+ exec' "open Stdlib";
8888+ let header1 = Printf.sprintf " %s version %%s" "OCaml" in
8989+ exec' (Printf.sprintf "Format.printf \"%s@.\" Sys.ocaml_version;;" header1);
9090+ exec' "#enable \"pretty\";;";
9191+ exec' "#disable \"shortvar\";;";
9292+ Sys.interactive := true;
9393+ Logs.info (fun m -> m "Setup complete");
9494+ {
9595+ stdout = Buffer.contents stdout_buff;
9696+ stderr = Buffer.contents stderr_buff;
9797+ }
9898+9999+ let stdout_buff = Buffer.create 100
100100+ let stderr_buff = Buffer.create 100
101101+102102+ let buff_opt b =
103103+ match String.trim (Buffer.contents b) with "" -> None | s -> Some s
104104+105105+ let string_opt s = match String.trim s with "" -> None | s -> Some s
106106+107107+ let loc = function
108108+ | Syntaxerr.Error x -> Some (Syntaxerr.location_of_error x)
109109+ | Lexer.Error (_, loc)
110110+ | Typecore.Error (loc, _, _)
111111+ | Typetexp.Error (loc, _, _)
112112+ | Typeclass.Error (loc, _, _)
113113+ | Typemod.Error (loc, _, _)
114114+ | Typedecl.Error (loc, _)
115115+ | Translcore.Error (loc, _)
116116+ | Translclass.Error (loc, _)
117117+ | Translmod.Error (loc, _) ->
118118+ Some loc
119119+ | _ -> None
120120+121121+ let execute printval ?pp_code ?highlight_location pp_answer s =
122122+ let lb = Lexing.from_function (refill_lexbuf s (ref 0) pp_code) in
123123+ (try
124124+ while true do
125125+ try
126126+ let phr = !Toploop.parse_toplevel_phrase lb in
127127+ ignore (Toploop.execute_phrase printval pp_answer phr : bool)
128128+ with
129129+ | End_of_file -> raise End_of_file
130130+ | x ->
131131+ (match highlight_location with
132132+ | None -> ()
133133+ | Some f -> ( match loc x with None -> () | Some loc -> f loc));
134134+ Errors.report_error Format.err_formatter x
135135+ done
136136+ with End_of_file -> ());
137137+ flush_all ()
138138+139139+ let execute :
140140+ string ->
141141+ (Toplevel_api_gen.exec_result, Toplevel_api_gen.err) IdlM.T.resultb =
142142+ let code_buff = Buffer.create 100 in
143143+ let res_buff = Buffer.create 100 in
144144+ let pp_code = Format.formatter_of_buffer code_buff in
145145+ let pp_result = Format.formatter_of_buffer res_buff in
146146+ let highlighted = ref None in
147147+ let highlight_location loc =
148148+ let _file1, line1, col1 = Location.get_pos_info loc.Location.loc_start in
149149+ let _file2, line2, col2 = Location.get_pos_info loc.Location.loc_end in
150150+ highlighted := Some Toplevel_api_gen.{ line1; col1; line2; col2 }
151151+ in
152152+ fun phrase ->
153153+ Buffer.clear code_buff;
154154+ Buffer.clear code_buff;
155155+ Buffer.clear res_buff;
156156+ Buffer.clear stderr_buff;
157157+ Buffer.clear stdout_buff;
158158+ let o, () =
159159+ S.capture
160160+ (fun () -> execute true ~pp_code ~highlight_location pp_result phrase)
161161+ ()
162162+ in
163163+ let mime_vals = Mime_printer.get () in
164164+ Format.pp_print_flush pp_code ();
165165+ Format.pp_print_flush pp_result ();
166166+ IdlM.ErrM.return
167167+ Toplevel_api_gen.
168168+ {
169169+ stdout = string_opt o.stdout;
170170+ stderr = string_opt o.stderr;
171171+ sharp_ppf = buff_opt code_buff;
172172+ caml_ppf = buff_opt res_buff;
173173+ highlight = !highlighted;
174174+ mime_vals;
175175+ }
176176+177177+ let filename_of_module unit_name =
178178+ Printf.sprintf "%s.cmi" (String.uncapitalize_ascii unit_name)
179179+180180+ let reset_dirs () =
181181+ Ocaml_utils.Directory_content_cache.clear ();
182182+ let open Ocaml_utils.Load_path in
183183+ let dirs = get_paths () in
184184+ reset ();
185185+ List.iter (fun p -> prepend_dir (Dir.create p)) dirs
186186+187187+ let add_dynamic_cmis dcs =
188188+ let open Ocaml_typing.Persistent_env.Persistent_signature in
189189+ let old_loader = !load in
190190+191191+ let fetch filename =
192192+ let url = Filename.concat dcs.Toplevel_api_gen.dcs_url filename in
193193+ S.sync_get url
194194+ in
195195+ let path =
196196+ match !path with Some p -> p | None -> failwith "Path not set"
197197+ in
198198+199199+ List.iter
200200+ (fun name ->
201201+ let filename = filename_of_module name in
202202+ match fetch (filename_of_module name) with
203203+ | Some content ->
204204+ let name = Filename.(concat path filename) in
205205+ S.create_file ~name ~content
206206+ | None -> ())
207207+ dcs.dcs_toplevel_modules;
208208+209209+ let new_load ~unit_name =
210210+ let filename = filename_of_module unit_name in
211211+212212+ let fs_name = Filename.(concat path filename) in
213213+ (* Check if it's already been downloaded. This will be the
214214+ case for all toplevel cmis. Also check whether we're supposed
215215+ to handle this cmi *)
216216+ (if
217217+ (not (Sys.file_exists fs_name))
218218+ && List.exists
219219+ (fun prefix -> String.starts_with ~prefix filename)
220220+ dcs.dcs_file_prefixes
221221+ then
222222+ match fetch filename with
223223+ | Some x ->
224224+ S.create_file ~name:fs_name ~content:x;
225225+ (* At this point we need to tell merlin that the dir contents
226226+ have changed *)
227227+ reset_dirs ()
228228+ | None ->
229229+ Printf.eprintf "Warning: Expected to find cmi at: %s\n%!"
230230+ (Filename.concat dcs.Toplevel_api_gen.dcs_url filename));
231231+ old_loader ~unit_name
232232+ in
233233+ load := new_load
234234+235235+ let init (init_libs : Toplevel_api_gen.init_libs) =
236236+ try
237237+ Logs.info (fun m -> m "init()");
238238+ path := Some init_libs.path;
239239+240240+ Clflags.no_check_prims := true;
241241+ List.iter
242242+ (fun { Toplevel_api_gen.sc_name; sc_content } ->
243243+ let filename =
244244+ Printf.sprintf "%s.cmi" (String.uncapitalize_ascii sc_name)
245245+ in
246246+ let name = Filename.(concat init_libs.path filename) in
247247+ S.create_file ~name ~content:sc_content)
248248+ init_libs.cmis.static_cmis;
249249+ Option.iter add_dynamic_cmis init_libs.cmis.dynamic_cmis;
250250+251251+ (*import_scripts
252252+ (List.map (fun cma -> cma.Toplevel_api_gen.url) init_libs.cmas);
253253+ functions :=
254254+ Some
255255+ (List.map
256256+ (fun func_name ->
257257+ Logs.info (fun m -> m "Function: %s" func_name);
258258+ let func = Js.Unsafe.js_expr func_name in
259259+ fun () ->
260260+ Js.Unsafe.fun_call func [| Js.Unsafe.inject Dom_html.window |])
261261+ (List.map (fun cma -> cma.Toplevel_api_gen.fn) init_libs.cmas)); *)
262262+ functions := Some [];
263263+ Logs.info (fun m -> m "init() finished");
264264+265265+ IdlM.ErrM.return ()
266266+ with e ->
267267+ IdlM.ErrM.return_err
268268+ (Toplevel_api_gen.InternalError (Printexc.to_string e))
269269+270270+ let setup () =
271271+ try
272272+ Logs.info (fun m -> m "setup()");
273273+274274+ let o =
275275+ match !functions with
276276+ | Some l -> setup l ()
277277+ | None -> failwith "Error: toplevel has not been initialised"
278278+ in
279279+ IdlM.ErrM.return
280280+ Toplevel_api_gen.
281281+ {
282282+ stdout = string_opt o.stdout;
283283+ stderr = string_opt o.stderr;
284284+ sharp_ppf = None;
285285+ caml_ppf = None;
286286+ highlight = None;
287287+ mime_vals = [];
288288+ }
289289+ with e ->
290290+ IdlM.ErrM.return_err
291291+ (Toplevel_api_gen.InternalError (Printexc.to_string e))
292292+293293+ let complete _phrase = failwith "Not implemented"
294294+295295+ let typecheck_phrase :
296296+ string ->
297297+ (Toplevel_api_gen.exec_result, Toplevel_api_gen.err) IdlM.T.resultb =
298298+ let res_buff = Buffer.create 100 in
299299+ let pp_result = Format.formatter_of_buffer res_buff in
300300+ let highlighted = ref None in
301301+ let highlight_location loc =
302302+ let _file1, line1, col1 = Location.get_pos_info loc.Location.loc_start in
303303+ let _file2, line2, col2 = Location.get_pos_info loc.Location.loc_end in
304304+ highlighted := Some Toplevel_api_gen.{ line1; col1; line2; col2 }
305305+ in
306306+ fun phr ->
307307+ Buffer.clear res_buff;
308308+ Buffer.clear stderr_buff;
309309+ Buffer.clear stdout_buff;
310310+ try
311311+ let lb = Lexing.from_function (refill_lexbuf phr (ref 0) None) in
312312+ let phr = !Toploop.parse_toplevel_phrase lb in
313313+ let phr = Toploop.preprocess_phrase pp_result phr in
314314+ match phr with
315315+ | Parsetree.Ptop_def sstr ->
316316+ let oldenv = !Toploop.toplevel_env in
317317+ Typecore.reset_delayed_checks ();
318318+ let str, sg, sn, _, newenv =
319319+ Typemod.type_toplevel_phrase oldenv sstr
320320+ in
321321+ let sg' = Typemod.Signature_names.simplify newenv sn sg in
322322+ ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg');
323323+ Typecore.force_delayed_checks ();
324324+ Printtyped.implementation pp_result str;
325325+ Format.pp_print_flush pp_result ();
326326+ Warnings.check_fatal ();
327327+ flush_all ();
328328+ IdlM.ErrM.return
329329+ Toplevel_api_gen.
330330+ {
331331+ stdout = buff_opt stdout_buff;
332332+ stderr = buff_opt stderr_buff;
333333+ sharp_ppf = None;
334334+ caml_ppf = buff_opt res_buff;
335335+ highlight = !highlighted;
336336+ mime_vals = [];
337337+ }
338338+ | _ -> failwith "Typechecking"
339339+ with x ->
340340+ (match loc x with None -> () | Some loc -> highlight_location loc);
341341+ Errors.report_error Format.err_formatter x;
342342+ IdlM.ErrM.return
343343+ Toplevel_api_gen.
344344+ {
345345+ stdout = buff_opt stdout_buff;
346346+ stderr = buff_opt stderr_buff;
347347+ sharp_ppf = None;
348348+ caml_ppf = buff_opt res_buff;
349349+ highlight = !highlighted;
350350+ mime_vals = [];
351351+ }
352352+353353+ let split_primitives p =
354354+ let len = String.length p in
355355+ let rec split beg cur =
356356+ if cur >= len then []
357357+ else if Char.equal p.[cur] '\000' then
358358+ String.sub p beg (cur - beg) :: split (cur + 1) (cur + 1)
359359+ else split beg (cur + 1)
360360+ in
361361+ Array.of_list (split 0 0)
362362+363363+ let compile_js id prog =
364364+ let open Js_of_ocaml_compiler in
365365+ let open Js_of_ocaml_compiler.Stdlib in
366366+ try
367367+ let str = Printf.sprintf "let _ = Mime_printer.id := \"%s\"\n%s" id prog in
368368+ let l = Lexing.from_string str in
369369+ let phr = Parse.toplevel_phrase l in
370370+ Typecore.reset_delayed_checks ();
371371+ Env.reset_cache_toplevel ();
372372+ let oldenv = !Toploop.toplevel_env in
373373+ (* let oldenv = Compmisc.initial_env() in *)
374374+ match phr with
375375+ | Ptop_def sstr ->
376376+ let str, sg, sn, _shape, newenv =
377377+ try Typemod.type_toplevel_phrase oldenv sstr
378378+ with Env.Error e ->
379379+ Env.report_error Format.err_formatter e;
380380+ exit 1
381381+ in
382382+ let sg' = Typemod.Signature_names.simplify newenv sn sg in
383383+ ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg');
384384+ Typecore.force_delayed_checks ();
385385+ let lam = Translmod.transl_toplevel_definition str in
386386+ let slam = Simplif.simplify_lambda lam in
387387+ let init_code, fun_code = Bytegen.compile_phrase slam in
388388+ let code, reloc, _events = Emitcode.to_memory init_code fun_code in
389389+ Toploop.toplevel_env := newenv;
390390+ (* let prims = split_primitives (Symtable.data_primitive_names ()) in *)
391391+ let b = Buffer.create 100 in
392392+ let cmo =
393393+ Cmo_format.
394394+ {
395395+ cu_name = "test";
396396+ cu_pos = 0;
397397+ cu_codesize = Misc.LongString.length code;
398398+ cu_reloc = reloc;
399399+ cu_imports = [];
400400+ cu_required_globals = [];
401401+ cu_primitives = [];
402402+ cu_force_link = false;
403403+ cu_debug = 0;
404404+ cu_debugsize = 0;
405405+ }
406406+ in
407407+ let fmt = Pretty_print.to_buffer b in
408408+ (* Symtable.patch_object code reloc;
409409+ Symtable.check_global_initialized reloc;
410410+ Symtable.update_global_table(); *)
411411+ let oc = open_out "/tmp/test.cmo" in
412412+ Misc.LongString.output oc code 0 (Misc.LongString.length code);
413413+414414+ (* let code = String.init (Misc.LongString.length code) ~f:(fun i -> Misc.LongString.get code i) in *)
415415+ close_out oc;
416416+ Driver.configure fmt;
417417+ 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
420420+ fmt p.debug p.code;
421421+ Format.(pp_print_flush std_formatter ());
422422+ Format.(pp_print_flush err_formatter ());
423423+ flush stdout;
424424+ flush stderr;
425425+ let js = Buffer.contents b in
426426+ IdlM.ErrM.return js
427427+ | _ -> IdlM.ErrM.return_err (Toplevel_api_gen.InternalError "Parse error")
428428+ with e -> IdlM.ErrM.return ("Exception: %s" ^ Printexc.to_string e)
429429+430430+ let config () =
431431+ let path =
432432+ match !path with Some p -> p | None -> failwith "Path not set"
433433+ in
434434+ let initial = Merlin_kernel.Mconfig.initial in
435435+ { initial with merlin = { initial.merlin with stdlib = Some path } }
436436+437437+ let make_pipeline source = Merlin_kernel.Mpipeline.make (config ()) source
438438+439439+ let wdispatch source query =
440440+ let pipeline = make_pipeline source in
441441+ Merlin_kernel.Mpipeline.with_pipeline pipeline @@ fun () ->
442442+ Query_commands.dispatch pipeline query
443443+444444+ module Completion = struct
445445+ open Merlin_utils
446446+ open Std
447447+ open Merlin_kernel
448448+449449+ (* Prefixing code from ocaml-lsp-server *)
450450+ let rfindi =
451451+ let rec loop s ~f i =
452452+ if i < 0 then None
453453+ else if f (String.unsafe_get s i) then Some i
454454+ else loop s ~f (i - 1)
455455+ in
456456+ fun ?from s ~f ->
457457+ let from =
458458+ let len = String.length s in
459459+ match from with
460460+ | None -> len - 1
461461+ | Some i ->
462462+ if i > len - 1 then
463463+ raise @@ Invalid_argument "rfindi: invalid from"
464464+ else i
465465+ in
466466+ loop s ~f from
467467+468468+ let lsplit2 s ~on =
469469+ match String.index_opt s on with
470470+ | None -> None
471471+ | Some i ->
472472+ let open StdLabels.String in
473473+ Some (sub s ~pos:0 ~len:i, sub s ~pos:(i + 1) ~len:(length s - i - 1))
474474+475475+ (** @see <https://ocaml.org/manual/lex.html> reference *)
476476+ let prefix_of_position ?(short_path = false) source position =
477477+ match Msource.text source with
478478+ | "" -> ""
479479+ | text ->
480480+ let from =
481481+ let (`Offset index) = Msource.get_offset source position in
482482+ min (String.length text - 1) (index - 1)
483483+ in
484484+ let pos =
485485+ let should_terminate = ref false in
486486+ let has_seen_dot = ref false in
487487+ let is_prefix_char c =
488488+ if !should_terminate then false
489489+ else
490490+ match c with
491491+ | 'a' .. 'z'
492492+ | 'A' .. 'Z'
493493+ | '0' .. '9'
494494+ | '\'' | '_'
495495+ (* Infix function characters *)
496496+ | '$' | '&' | '*' | '+' | '-' | '/' | '=' | '>' | '@' | '^'
497497+ | '!' | '?' | '%' | '<' | ':' | '~' | '#' ->
498498+ true
499499+ | '`' ->
500500+ if !has_seen_dot then false
501501+ else (
502502+ should_terminate := true;
503503+ true)
504504+ | '.' ->
505505+ has_seen_dot := true;
506506+ not short_path
507507+ | _ -> false
508508+ in
509509+ rfindi text ~from ~f:(fun c -> not (is_prefix_char c))
510510+ in
511511+ let pos = match pos with None -> 0 | Some pos -> pos + 1 in
512512+ let len = from - pos + 1 in
513513+ let reconstructed_prefix = StdLabels.String.sub text ~pos ~len in
514514+ (* if we reconstructed [~f:ignore] or [?f:ignore], we should take only
515515+ [ignore], so: *)
516516+ if
517517+ String.is_prefixed ~by:"~" reconstructed_prefix
518518+ || String.is_prefixed ~by:"?" reconstructed_prefix
519519+ then
520520+ match lsplit2 reconstructed_prefix ~on:':' with
521521+ | Some (_, s) -> s
522522+ | None -> reconstructed_prefix
523523+ else reconstructed_prefix
524524+525525+ let at_pos source position =
526526+ let prefix = prefix_of_position source position in
527527+ let (`Offset to_) = Msource.get_offset source position in
528528+ let from =
529529+ to_
530530+ - String.length (prefix_of_position ~short_path:true source position)
531531+ in
532532+ if prefix = "" then None
533533+ else
534534+ let query =
535535+ Query_protocol.Complete_prefix (prefix, position, [], true, true)
536536+ in
537537+ Some (from, to_, wdispatch source query)
538538+ end
539539+540540+ let complete_prefix source position =
541541+ let source = Merlin_kernel.Msource.make source in
542542+ match Completion.at_pos source position with
543543+ | Some (from, to_, compl) ->
544544+ let entries = compl.entries in
545545+ IdlM.ErrM.return { Toplevel_api_gen.from; to_; entries }
546546+ | None ->
547547+ IdlM.ErrM.return { Toplevel_api_gen.from = 0; to_ = 0; entries = [] }
548548+549549+ let query_errors source =
550550+ let source = Merlin_kernel.Msource.make source in
551551+ let query =
552552+ Query_protocol.Errors { lexing = true; parsing = true; typing = true }
553553+ in
554554+ let errors =
555555+ wdispatch source query
556556+ |> StdLabels.List.map
557557+ ~f:(fun
558558+ (Ocaml_parsing.Location.{ kind; main = _; sub; source } as error)
559559+ ->
560560+ let of_sub sub =
561561+ Ocaml_parsing.Location.print_sub_msg Format.str_formatter sub;
562562+ String.trim (Format.flush_str_formatter ())
563563+ in
564564+ let loc = Ocaml_parsing.Location.loc_of_report error in
565565+ let main =
566566+ Format.asprintf "@[%a@]" Ocaml_parsing.Location.print_main error
567567+ |> String.trim
568568+ in
569569+ {
570570+ Toplevel_api_gen.kind;
571571+ loc;
572572+ main;
573573+ sub = StdLabels.List.map ~f:of_sub sub;
574574+ source;
575575+ })
576576+ in
577577+ IdlM.ErrM.return errors
578578+579579+ let type_enclosing source position =
580580+ let source = Merlin_kernel.Msource.make source in
581581+ let query = Query_protocol.Type_enclosing (None, position, None) in
582582+ let enclosing = wdispatch source query in
583583+ IdlM.ErrM.return enclosing
584584+end
+9-10
lib/uTop.mli
···2121(** {6 Parsing} *)
22222323type location = int * int
2424- (** Type of a string-location. It is composed of a start and stop
2424+(** Type of a string-location. It is composed of a start and stop
2525 offsets (in bytes). *)
26262727-type lines = {
2828- start: int;
2929- stop: int;
3030-}
3131- (** Type for a range of lines in a buffer from start to stop. *)
2727+type lines = { start : int; stop : int }
2828+(** Type for a range of lines in a buffer from start to stop. *)
32293330(** Result of a function processing a programx. *)
3431type 'a result =
···8077(** [get_message printer x] applies [printer] on [x] and returns everything it
8178 prints as a string. *)
82798383-val get_ocaml_error_message : exn -> location * string * (lines option)
8484- (** [get_ocaml_error_message exn] returns the location and error
8080+val get_ocaml_error_message : exn -> location * string * lines option
8181+(** [get_ocaml_error_message exn] returns the location and error
8582 message for the exception [exn] which must be an exception from
8683 the compiler. *)
87848888-val check_phrase : Parsetree.toplevel_phrase -> (location list * string * lines option list) option
8989- (** [check_phrase phrase] checks that [phrase] can be executed
8585+val check_phrase :
8686+ Parsetree.toplevel_phrase ->
8787+ (location list * string * lines option list) option
8888+(** [check_phrase phrase] checks that [phrase] can be executed
9089 without typing or compilation errors. It returns [None] if
9190 [phrase] is OK and an error message otherwise.
9291 If the result is [None] it is guaranteed that
-397
lib/worker.cppo.ml
···11-open Js_of_ocaml_toplevel
22-open Js_top_worker_rpc
33-44-let optbind : 'a option -> ('a -> 'b option) -> 'b option = fun x fn -> match x with | None -> None | Some a -> fn a
55-66-let log fmt =
77- Format.kasprintf
88- (fun s -> Js_of_ocaml.(Firebug.console##log (Js.string s)))
99- fmt
1010-1111-(* OCamlorg toplevel in a web worker
1212-1313- This communicates with the toplevel code via the API defined in
1414- {!Toplevel_api}. This allows the OCaml execution to not block the "main
1515- thread" keeping the page responsive. *)
1616-1717-module Version = struct
1818- type t = int list
1919-2020- let split_char ~sep p =
2121- let len = String.length p in
2222- let rec split beg cur =
2323- if cur >= len then
2424- if cur - beg > 0 then [ String.sub p beg (cur - beg) ] else []
2525- else if sep p.[cur] then
2626- String.sub p beg (cur - beg) :: split (cur + 1) (cur + 1)
2727- else split beg (cur + 1)
2828- in
2929- split 0 0
3030-3131- let split v =
3232- match
3333- split_char ~sep:(function '+' | '-' | '~' -> true | _ -> false) v
3434- with
3535- | [] -> assert false
3636- | x :: _ ->
3737- List.map int_of_string
3838- (split_char ~sep:(function '.' -> true | _ -> false) x)
3939-4040- let current = split Sys.ocaml_version
4141- let compint (a : int) b = compare a b
4242-4343- let rec compare v v' =
4444- match (v, v') with
4545- | [ x ], [ y ] -> compint x y
4646- | [], [] -> 0
4747- | [], y :: _ -> compint 0 y
4848- | x :: _, [] -> compint x 0
4949- | x :: xs, y :: ys -> (
5050- match compint x y with 0 -> compare xs ys | n -> n)
5151-end
5252-5353-let exec' s =
5454- let res : bool = JsooTop.use Format.std_formatter s in
5555- if not res then Format.eprintf "error while evaluating %s@." s
5656-5757-let setup functions () =
5858- JsooTop.initialize ();
5959- List.iter (fun f -> f ()) functions;
6060- Sys.interactive := false;
6161- if Version.compare Version.current [ 4; 07 ] >= 0 then exec' "open Stdlib";
6262- let header1 = Printf.sprintf " %s version %%s" "OCaml" in
6363- let header2 =
6464- Printf.sprintf " Compiled with Js_of_ocaml version %s"
6565- Js_of_ocaml.Sys_js.js_of_ocaml_version
6666- in
6767- exec' (Printf.sprintf "Format.printf \"%s@.\" Sys.ocaml_version;;" header1);
6868- exec' (Printf.sprintf "Format.printf \"%s@.\";;" header2);
6969- exec' "#enable \"pretty\";;";
7070- exec' "#disable \"shortvar\";;";
7171- Toploop.add_directive "load_js"
7272- (Toploop.Directive_string
7373- (fun name -> Js_of_ocaml.Js.Unsafe.global##load_script_ name))
7474- Toploop.{ section = ""; doc = "Load a javascript script" };
7575- Sys.interactive := true;
7676- ()
7777-7878-let setup_printers () =
7979- exec' "let _print_unit fmt (_ : 'a) : 'a = Format.pp_print_string fmt \"()\"";
8080- Topdirs.dir_install_printer Format.std_formatter
8181- Longident.(Lident "_print_unit")
8282-8383-let stdout_buff = Buffer.create 100
8484-let stderr_buff = Buffer.create 100
8585-8686-(* RPC function implementations *)
8787-8888-module M = Idl.IdM (* Server is synchronous *)
8989-9090-module IdlM = Idl.Make (M)
9191-module Server = Toplevel_api_gen.Make (IdlM.GenServer ())
9292-9393-(* These are all required to return the appropriate value for the API within the
9494- [IdlM.T] monad. The simplest way to do this is to use [IdlM.ErrM.return] for
9595- the success case and [IdlM.ErrM.return_err] for the failure case *)
9696-9797-let buff_opt b = match Buffer.contents b with "" -> None | s -> Some s
9898-9999-let execute =
100100- let code_buff = Buffer.create 100 in
101101- let res_buff = Buffer.create 100 in
102102- let pp_code = Format.formatter_of_buffer code_buff in
103103- let pp_result = Format.formatter_of_buffer res_buff in
104104- let highlighted = ref None in
105105- let highlight_location loc =
106106- let _file1, line1, col1 = Location.get_pos_info loc.Location.loc_start in
107107- let _file2, line2, col2 = Location.get_pos_info loc.Location.loc_end in
108108- highlighted := Some Toplevel_api_gen.{ line1; col1; line2; col2 }
109109- in
110110- fun phrase ->
111111- Buffer.clear code_buff;
112112- Buffer.clear res_buff;
113113- Buffer.clear stderr_buff;
114114- Buffer.clear stdout_buff;
115115- JsooTop.execute true ~pp_code ~highlight_location pp_result phrase;
116116- let mime_vals = Mime_printer.get () in
117117- Format.pp_print_flush pp_code ();
118118- Format.pp_print_flush pp_result ();
119119- IdlM.ErrM.return
120120- Toplevel_api_gen.
121121- {
122122- stdout = buff_opt stdout_buff;
123123- stderr = buff_opt stderr_buff;
124124- sharp_ppf = buff_opt code_buff;
125125- caml_ppf = buff_opt res_buff;
126126- highlight = !highlighted;
127127- mime_vals;
128128- }
129129-130130-let sync_get url =
131131- let open Js_of_ocaml in
132132- let x = XmlHttpRequest.create () in
133133- x##.responseType := Js.string "arraybuffer";
134134- x##_open (Js.string "GET") (Js.string url) Js._false;
135135- x##send Js.null;
136136- match x##.status with
137137- | 200 ->
138138- Js.Opt.case
139139- (File.CoerceTo.arrayBuffer x##.response)
140140- (fun () ->
141141- Firebug.console##log (Js.string "Failed to receive file");
142142- None)
143143- (fun b -> Some (Typed_array.String.of_arrayBuffer b))
144144- | _ -> None
145145-146146-type signature = Types.signature_item list
147147-type flags = Cmi_format.pers_flags list
148148-type header = string * signature
149149-type crcs = (string * Digest.t option) list
150150-151151-(** The following two functions are taken from cmi_format.ml in
152152- the compiler, but changed to work on bytes rather than input
153153- channels *)
154154-let input_cmi str =
155155- let offset = 0 in
156156- let (name, sign) = (Marshal.from_bytes str offset : header) in
157157- let offset = offset + Marshal.total_size str offset in
158158- let crcs = (Marshal.from_bytes str offset : crcs) in
159159- let offset = offset + Marshal.total_size str offset in
160160- let flags = (Marshal.from_bytes str offset : flags) in
161161- {
162162- Cmi_format.cmi_name = name;
163163- cmi_sign = sign;
164164- cmi_crcs = crcs;
165165- cmi_flags = flags;
166166- }
167167-168168-let read_cmi filename str =
169169- let magic_len = String.length Config.cmi_magic_number in
170170- let buffer = Bytes.sub str 0 magic_len in
171171- (if buffer <> Bytes.of_string Config.cmi_magic_number then
172172- let pre_len = String.length Config.cmi_magic_number - 3 in
173173- if
174174- Bytes.sub buffer 0 pre_len
175175- = Bytes.of_string @@ String.sub Config.cmi_magic_number 0 pre_len
176176- then
177177- let msg =
178178- if buffer < Bytes.of_string Config.cmi_magic_number then "an older"
179179- else "a newer"
180180- in
181181- raise (Cmi_format.Error (Wrong_version_interface (filename, msg)))
182182- else raise (Cmi_format.Error (Not_an_interface filename)));
183183- input_cmi (Bytes.sub str magic_len (Bytes.length str - magic_len))
184184-185185-let functions : (unit -> unit) list option ref = ref None
186186-187187-let init (init_libs : Toplevel_api_gen.init_libs) =
188188- let open Js_of_ocaml in
189189- try
190190- Clflags.no_check_prims := true;
191191- let cmi_files =
192192- List.map
193193- (fun cmi -> (Filename.basename cmi |> Filename.chop_extension, cmi))
194194- init_libs.cmi_urls
195195- in
196196-#if OCAML_VERSION < (4,9,0)
197197- let open Env.Persistent_signature in
198198-#else
199199- let open Persistent_env.Persistent_signature in
200200-#endif
201201- let old_loader = !load in
202202- (load :=
203203- fun ~unit_name ->
204204- let result =
205205- optbind
206206- (try Some (List.assoc (String.uncapitalize_ascii unit_name) cmi_files) with _ -> None)
207207- sync_get
208208- in
209209- match result with
210210- | Some x ->
211211- Some
212212- {
213213- filename =
214214- Sys.executable_name;
215215- cmi = read_cmi unit_name (Bytes.of_string x);
216216- }
217217- | _ -> old_loader ~unit_name);
218218- Js_of_ocaml.Worker.import_scripts
219219- (List.map (fun cma -> cma.Toplevel_api_gen.url) init_libs.cmas);
220220- functions :=
221221- Some
222222- (List.map
223223- (fun func_name ->
224224- Firebug.console##log (Js.string ("Function: " ^ func_name));
225225- let func = Js.Unsafe.js_expr func_name in
226226- fun () ->
227227- Js.Unsafe.fun_call func [| Js.Unsafe.inject Dom_html.window |])
228228- (List.map (fun cma -> cma.Toplevel_api_gen.fn) init_libs.cmas));
229229- IdlM.ErrM.return ()
230230- with e ->
231231- IdlM.ErrM.return_err (Toplevel_api_gen.InternalError (Printexc.to_string e))
232232-233233-let setup () =
234234- let open Js_of_ocaml in
235235- try
236236- Sys_js.set_channel_flusher stdout (Buffer.add_string stdout_buff);
237237- Sys_js.set_channel_flusher stderr (Buffer.add_string stderr_buff);
238238- (match !functions with
239239- | Some l -> setup l ()
240240- | None -> failwith "Error: toplevel has not been initialised");
241241- setup_printers ();
242242- IdlM.ErrM.return
243243- Toplevel_api_gen.
244244- {
245245- stdout = buff_opt stdout_buff;
246246- stderr = buff_opt stderr_buff;
247247- sharp_ppf = None;
248248- caml_ppf = None;
249249- highlight = None;
250250- mime_vals = [];
251251- }
252252- with e ->
253253- IdlM.ErrM.return_err (Toplevel_api_gen.InternalError (Printexc.to_string e))
254254-255255-let complete phrase =
256256- let contains_double_underscore s =
257257- let len = String.length s in
258258- let rec aux i =
259259- if i > len - 2 then false
260260- else if s.[i] = '_' && s.[i + 1] = '_' then true
261261- else aux (i + 1)
262262- in
263263- aux 0
264264- in
265265- let n, res = UTop_complete.complete ~phrase_terminator:";;" ~input:phrase in
266266- let res =
267267- List.filter (fun (l, _) -> not (contains_double_underscore l)) res
268268- in
269269- let completions = List.map fst res in
270270- IdlM.ErrM.return Toplevel_api_gen.{ n; completions }
271271-272272-let server process e =
273273- log "Worker received: %s" e;
274274- let (_, id, call) = Jsonrpc.version_id_and_call_of_string e in
275275- M.bind (process call) (fun response ->
276276- let rtxt = Jsonrpc.string_of_response ~id response in
277277- log "Worker sending: %s" rtxt;
278278- Js_of_ocaml.Worker.post_message rtxt);
279279- ()
280280-281281- let loc = function
282282- | Syntaxerr.Error x ->
283283- Some (Syntaxerr.location_of_error x)
284284- | Lexer.Error (_, loc)
285285- | Typecore.Error (loc, _, _)
286286- | Typetexp.Error (loc, _, _)
287287- | Typeclass.Error (loc, _, _)
288288- | Typemod.Error (loc, _, _)
289289- | Typedecl.Error (loc, _)
290290- | Translcore.Error (loc, _)
291291- | Translclass.Error (loc, _)
292292- | Translmod.Error (loc, _) ->
293293- Some loc
294294- | _ ->
295295- None
296296-297297-let refill_lexbuf s p ppf buffer len =
298298- if !p = String.length s then
299299- 0
300300- else
301301- let len', nl =
302302- try String.index_from s !p '\n' - !p + 1, false with
303303- | _ ->
304304- String.length s - !p, true
305305- in
306306- let len'' = min len len' in
307307- String.blit s !p buffer 0 len'';
308308- (match ppf with
309309- | Some ppf ->
310310- Format.fprintf ppf "%s" (Bytes.sub_string buffer 0 len'');
311311- if nl then Format.pp_print_newline ppf ();
312312- Format.pp_print_flush ppf ()
313313- | None ->
314314- ());
315315- p := !p + len'';
316316- len''
317317-318318-let typecheck_phrase =
319319- let res_buff = Buffer.create 100 in
320320- let pp_result = Format.formatter_of_buffer res_buff in
321321- let highlighted = ref None in
322322- let highlight_location loc =
323323- let _file1, line1, col1 = Location.get_pos_info loc.Location.loc_start in
324324- let _file2, line2, col2 = Location.get_pos_info loc.Location.loc_end in
325325- highlighted := Some Toplevel_api_gen.{ line1; col1; line2; col2 }
326326- in
327327- fun phr ->
328328- Buffer.clear res_buff;
329329- Buffer.clear stderr_buff;
330330- Buffer.clear stdout_buff;
331331- try
332332- let lb = Lexing.from_function (refill_lexbuf phr (ref 0) None) in
333333- let phr = !Toploop.parse_toplevel_phrase lb in
334334- let phr = Toploop.preprocess_phrase pp_result phr in
335335- match phr with
336336- | Parsetree.Ptop_def sstr ->
337337- let oldenv = !Toploop.toplevel_env in
338338- Typecore.reset_delayed_checks ();
339339-#if OCAML_VERSION >= (4,8,0) && OCAML_VERSION < (4,14,0)
340340- let str, sg, sn, newenv = Typemod.type_toplevel_phrase oldenv sstr in
341341- let sg' = Typemod.Signature_names.simplify newenv sn sg in
342342- ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg');
343343-#elif OCAML_VERSION >= (4,14,0)
344344- let str, sg, sn, _, newenv = Typemod.type_toplevel_phrase oldenv sstr in
345345- let sg' = Typemod.Signature_names.simplify newenv sn sg in
346346- ignore (Includemod.signatures ~mark:Mark_positive oldenv sg sg');
347347-#else
348348- let str, sg, newenv = Typemod.type_toplevel_phrase oldenv sstr in
349349- let sg' = Typemod.simplify_signature sg in
350350- ignore (Includemod.signatures oldenv sg sg');
351351-#endif
352352- Typecore.force_delayed_checks ();
353353- Printtyped.implementation pp_result str;
354354- Format.pp_print_flush pp_result ();
355355- Warnings.check_fatal ();
356356- flush_all ();
357357- IdlM.ErrM.return
358358- Toplevel_api_gen.
359359- { stdout = buff_opt stdout_buff
360360- ; stderr = buff_opt stderr_buff
361361- ; sharp_ppf = None
362362- ; caml_ppf = buff_opt res_buff
363363- ; highlight = !highlighted
364364- ; mime_vals = []
365365- }
366366- | _ ->
367367- failwith "Typechecking"
368368- with
369369- | x ->
370370- (match loc x with None -> () | Some loc -> highlight_location loc);
371371- Errors.report_error Format.err_formatter x;
372372- IdlM.ErrM.return
373373- Toplevel_api_gen.
374374- { stdout = buff_opt stdout_buff
375375- ; stderr = buff_opt stderr_buff
376376- ; sharp_ppf = None
377377- ; caml_ppf = buff_opt res_buff
378378- ; highlight = !highlighted
379379- ; mime_vals = []
380380- }
381381-382382-let run () =
383383- (* Here we bind the server stub functions to the implementations *)
384384- let open Js_of_ocaml in
385385- try
386386- (Js_top_worker_rpc.Idl.logfn :=
387387- fun s -> Js_of_ocaml.(Firebug.console##log s));
388388- Server.complete complete;
389389- Server.exec execute;
390390- Server.setup setup;
391391- Server.init init;
392392- Server.typecheck typecheck_phrase;
393393- let rpc_fn = IdlM.server Server.implementation in
394394- Js_of_ocaml.Worker.set_onmessage (server rpc_fn);
395395- Firebug.console##log (Js.string "All finished")
396396- with e ->
397397- Firebug.console##log (Js.string ("Exception: " ^ Printexc.to_string e))
+104
lib/worker.ml
···11+open Js_top_worker_rpc
22+open Js_top_worker
33+44+let optbind : 'a option -> ('a -> 'b option) -> 'b option =
55+ fun x fn -> match x with None -> None | Some a -> fn a
66+77+let log fmt =
88+ Format.kasprintf
99+ (fun s -> Js_of_ocaml.(Firebug.console##log (Js.string s)))
1010+ fmt
1111+1212+let sync_get url =
1313+ let open Js_of_ocaml in
1414+ let x = XmlHttpRequest.create () in
1515+ x##.responseType := Js.string "arraybuffer";
1616+ x##_open (Js.string "GET") (Js.string url) Js._false;
1717+ x##send Js.null;
1818+ match x##.status with
1919+ | 200 ->
2020+ Js.Opt.case
2121+ (File.CoerceTo.arrayBuffer x##.response)
2222+ (fun () ->
2323+ Firebug.console##log (Js.string "Failed to receive file");
2424+ None)
2525+ (fun b -> Some (Typed_array.String.of_arrayBuffer b))
2626+ | _ -> None
2727+2828+module Server = Toplevel_api_gen.Make (Impl.IdlM.GenServer ())
2929+3030+(* OCamlorg toplevel in a web worker
3131+3232+ This communicates with the toplevel code via the API defined in
3333+ {!Toplevel_api}. This allows the OCaml execution to not block the "main
3434+ thread" keeping the page responsive. *)
3535+3636+let server process e =
3737+ log "Worker received: %s" e;
3838+ let _, id, call = Jsonrpc.version_id_and_call_of_string e in
3939+ Impl.M.bind (process call) (fun response ->
4040+ let rtxt = Jsonrpc.string_of_response ~id response in
4141+ log "Worker sending: %s" rtxt;
4242+ Js_of_ocaml.Worker.post_message rtxt;
4343+ Impl.M.return ())
4444+4545+let loc = function
4646+ | Syntaxerr.Error x -> Some (Syntaxerr.location_of_error x)
4747+ | Lexer.Error (_, loc)
4848+ | Typecore.Error (loc, _, _)
4949+ | Typetexp.Error (loc, _, _)
5050+ | Typeclass.Error (loc, _, _)
5151+ | Typemod.Error (loc, _, _)
5252+ | Typedecl.Error (loc, _)
5353+ | Translcore.Error (loc, _)
5454+ | Translclass.Error (loc, _)
5555+ | Translmod.Error (loc, _) ->
5656+ Some loc
5757+ | _ -> None
5858+5959+module S : Impl.S = struct
6060+ let capture : (unit -> 'a) -> unit -> Impl.captured * 'a =
6161+ fun f () ->
6262+ let stdout_buff = Buffer.create 1024 in
6363+ let stderr_buff = Buffer.create 1024 in
6464+ Js_of_ocaml.Sys_js.set_channel_flusher stdout
6565+ (Buffer.add_string stdout_buff);
6666+ Js_of_ocaml.Sys_js.set_channel_flusher stderr
6767+ (Buffer.add_string stderr_buff);
6868+ let x = f () in
6969+ let captured =
7070+ {
7171+ Impl.stdout = Buffer.contents stdout_buff;
7272+ stderr = Buffer.contents stderr_buff;
7373+ }
7474+ in
7575+ (captured, x)
7676+7777+ let sync_get = sync_get
7878+ let create_file = Js_of_ocaml.Sys_js.create_file
7979+end
8080+8181+module M = Impl.Make (S)
8282+8383+let run () =
8484+ (* Here we bind the server stub functions to the implementations *)
8585+ let open Js_of_ocaml in
8686+ let open M in
8787+ try
8888+ Firebug.console##log (Js.string "Starting worker...");
8989+9090+ Logs.set_reporter (Logs_browser.console_reporter ());
9191+ Logs.set_level (Some Logs.Info);
9292+ Server.exec execute;
9393+ Server.setup setup;
9494+ Server.init init;
9595+ Server.typecheck typecheck_phrase;
9696+ Server.complete_prefix complete_prefix;
9797+ Server.query_errors query_errors;
9898+ Server.type_enclosing type_enclosing;
9999+ Server.compile_js compile_js;
100100+ let rpc_fn = Impl.IdlM.server Server.implementation in
101101+ Js_of_ocaml.Worker.set_onmessage (fun x -> ignore (server rpc_fn x));
102102+ Firebug.console##log (Js.string "All finished")
103103+ with e ->
104104+ Firebug.console##log (Js.string ("Exception: " ^ Printexc.to_string e))