123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114(************************************************************************)(* * The Coq Proof Assistant / The Coq Development Team *)(* v * INRIA, CNRS and contributors - Copyright 1999-2018 *)(* <O___,, * (see CREDITS file for the list of authors) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(************************************************************************)(* Coq Language Server Protocol / SerAPI *)(* Copyright 2016-2019 MINES ParisTech -- Dual License LGPL 2.1 / GPL3+ *)(* Written by: Emilio J. Gallego Arias *)(************************************************************************)(**************************************************************************)(* Low-level, internal Coq initialization *)(**************************************************************************)typecoq_opts={load_module:string->unit(** callback to load cma/cmo files *);load_plugin:Mltop.PluginSpec.t->unit(** callback to load findlib packages *);debug:bool(** Enable Coq Debug mode *);vm:bool(** Enable Coq's VM *);warnings:stringoption(** Coq's Warnings *)}letcoq_lvl_to_severity(lvl:Feedback.level)=letopenLang.Diagnostic.Severityinmatchlvlwith|Feedback.Debug->hint(* Debug has not LSP number *)|Feedback.Info->hint|Feedback.Notice->information|Feedback.Warning->warning|Feedback.Error->error(* let qf_of_coq qf = let range = Quickfix.loc qf in let newText = Quickfix.pp
qf |> Pp.string_of_ppcmds in { Lang.Qf.range; newText } *)letadd_messagelvlrange_qfmsgq=letlvl=coq_lvl_to_severitylvlin(* let quickFix = if qf = [] then None else Some (List.map qf_of_coq qf) in *)letquickFix=Noneinletpayload=Message.Payload.make?range?quickFixmsginq:=(lvl,payload)::!qletmk_fb_handlerqFeedback.{contents;_}=matchcontentswith|Message(lvl,loc,msg)->add_messagelvllocNonemsgq|_->()letcoq_initopts=(* Core Coq initialization *)Lib.init();Global.set_VMopts.vm;Global.set_native_compilerfalse;ifopts.debugthenCDebug.set_flags"backtrace";(**************************************************************************)(* Feedback setup *)(**************************************************************************)(* Initialize logging. *)letfb_handler=mk_fb_handlerProtect.fb_queueinignore(Feedback.add_feederfb_handler);(* Custom toplevel is used for bytecode-to-js dynlink *)letser_mltop:Mltop.toplevel=letopenMltopin{load_plugin=opts.load_plugin;load_module=opts.load_module;add_dir=(fun_->());ml_loop=(fun?init_file:__->())}inMltop.set_topser_mltop;(* Maybe set warnings *)Option.iterCWarnings.set_flagsopts.warnings;(* This should go away in Coq itself *)Safe_typing.allow_delayed_constants:=true;(**************************************************************************)(* Add root state!! *)(**************************************************************************)Vernacstate.freeze_full_state()|>State.of_coq(* End of core initialization *)(**************************************************************************)(* Per-document, internal Coq initialization *)(**************************************************************************)(* Inits the context for a document *)letdoc_init~intern~root_state~workspace~uri()=(* Lsp.Io.log_error "init" "starting"; *)Vernacstate.unfreeze_full_state(State.to_coqroot_state);(* Set load paths from workspace info. *Important*, this has to happen before
we declare the library below as [Declaremods/Library] will infer the module
name by looking at the load path! *)Workspace.apply~intern~uriworkspace;(* We return the state at this point! *)Vernacstate.freeze_full_state()|>State.of_coqletdoc_init~token:_~intern~root_state~workspace~uri=(* Don't interrupt document creation. *)lettoken=Limits.create_atomic()inProtect.eval~token~f:(doc_init~intern~root_state~workspace~uri)()