Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file extend_main.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177moduleP=Extend_protocolmoduleR=P.ReadermoduleDescription=structtypet=P.descriptionletmake_v0~name~version={P.name;version}endmoduleReader=structtypet=(moduleR.V0)letmake_v0(x:(moduleR.V0)):t=xmoduleMake(V:R.V0)=structopenP.Readerletbuffer=refNoneletget_buffer()=match!bufferwith|None->invalid_arg"No buffer loaded"|Somebuffer->bufferletexec=function|Req_loadbuf->buffer:=Some(V.loadbuf);Res_loaded|Req_parse->Res_parse(V.parse(get_buffer()))|Req_parse_line(pos,str)->Res_parse(V.parse_line(get_buffer())posstr)|Req_parse_for_completionpos->letinfo,tree=V.for_completion(get_buffer())posinRes_parse_for_completion(info,tree)|Req_get_ident_atpos->Res_get_ident_at(V.ident_at(get_buffer())pos)|Req_print_outcometrees->letprintt=V.print_outcomeFormat.str_formattert;Format.flush_str_formatter()inlettrees=List.rev_mapprinttreesinRes_print_outcome(List.revtrees)|Req_pretty_printp->V.pretty_printFormat.str_formatterp;Res_pretty_print(Format.flush_str_formatter())endendmoduleUtils=struct(* Postpone messages until ready *)letsend,set_ready=letis_ready=reffalseinletpostponed=ref[]inletreally_sendmsg=output_valuestdoutmsginletset_ready()=is_ready:=true;letpostponed'=List.rev!postponedinpostponed:=[];List.iterreally_sendpostponed'inletsendmsg=if!is_readythenreally_sendmsgelsepostponed:=msg::!postponedinsend,set_readyletnotifymsg=send(P.Notifymsg)letdebugmsg=send(P.Debugmsg)endmoduleHandshake=structletmagic_number:string="MERLINEXTEND002"typeversions={ast_impl_magic_number:string;ast_intf_magic_number:string;cmi_magic_number:string;cmt_magic_number:string;}letversions=Config.({ast_impl_magic_number;ast_intf_magic_number;cmi_magic_number;cmt_magic_number;})letnegotiate(capabilities:P.capabilities)=output_stringstdoutmagic_number;output_valuestdoutversions;output_valuestdoutcapabilities;flushstdout;Utils.set_ready();matchinput_valuestdinwith|exceptionEnd_of_file->exit0|P.Start_communication->()|_->prerr_endline"Unexpected value after handshake.";exit1letnegotiate_driverext_nameio=letmagic'=really_input_stringi(String.lengthmagic_number)inifmagic'<>magic_numberthen(letmsg=Printf.sprintf"Extension %s has incompatible protocol version %S (expected %S)"ext_namemagic'magic_numberinfailwithmsg);letversions':versions=input_valueiinletcheck_vprjname=ifprjversions<>prjversions'thenletmsg=Printf.sprintf"Extension %s %s has incompatible version %S (expected %S)"ext_namename(prjversions')(prjversions)infailwithmsgincheck_v(funx->x.ast_impl_magic_number)"implementation AST";check_v(funx->x.ast_intf_magic_number)"interface AST";check_v(funx->x.cmi_magic_number)"compiled interface (CMI)";check_v(funx->x.cmt_magic_number)"typedtree (CMT)";output_valueoP.Start_communication;flusho;letcapabilities:P.capabilities=input_valueiincapabilitiesend(** The main entry point of an extension. *)letextension_main?readerdesc=(* Check if invoked from Merlin *)beginmatchSys.getenv"__MERLIN_MASTER_PID"with|exceptionNot_found->Printf.eprintf"This is %s merlin extension, version %s.\n\
This binary should be invoked from merlin and \
cannot be used directly.\n%!"desc.P.namedesc.P.version;exit1;|_->()end;(* Communication happens on stdin/stdout. *)Handshake.negotiate{P.reader=reader<>None};letreader=matchreaderwith|None->(fun_->failwith"No reader")|Some(moduleR:R.V0)->letmoduleM=Reader.Make(R)inM.execinletrespondf=matchf()with|(r:P.response)->Utils.sendr|exceptionexn->letname=Printexc.exn_slot_nameexninletdesc=Printexc.to_stringexninUtils.send(P.Exception(name,desc))inletrecloop()=flushstdout;matchinput_valuestdinwith|exceptionEnd_of_file->exit0|P.Start_communication->prerr_endline"Unexpected message.";exit2|P.Reader_requestrequest->respond(fun()->P.Reader_response(readerrequest));loop()inloop()