123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140(*************************************************************************)(* Copyright 2015-2019 MINES ParisTech -- Dual License LGPL 2.1+ / GPL3+ *)(* Copyright 2019-2024 Inria -- Dual License LGPL 2.1+ / GPL3+ *)(* Copyright 2024-2025 Emilio J. Gallego Arias -- LGPL 2.1+ / GPL3+ *)(* Copyright 2025 CNRS -- LGPL 2.1+ / GPL3+ *)(* Written by: Emilio J. Gallego Arias & coq-lsp contributors *)(*************************************************************************)(* Rocq Language Server Protocol: .vo file API *)(*************************************************************************)typet=Names.DirPath.tletnamen=nletloaded~token~st=State.in_state~token~st~f:Library.loaded_libraries()(* Function to extract definitions and lemmas from the environment *)moduleDynHandle=Libobject.Dyn.Map(structtype'at='a->unitend)(* Prefix is the module / section things are defined *)letconst_handler(fn:Names.Constant.t->Decls.logical_kind->Constr.t->unit)prefix(id,obj)=letopenNamesinletkn=KerName.makeprefix.Nametab.obj_mp(Label.of_idid)inletcst=Global.constant_of_delta_knkninletgr=GlobRef.ConstRefcstinletenv=Global.env()inlettyp,_=Typeops.type_of_global_in_contextenvgrinletkind=Declare.Internal.Constant.kindobjinfncstkindtypletiter_constructorsindspufnenvnconstr=fori=1tonconstrdolettyp=Inductive.type_of_constructor((indsp,i),u)(Inductive.lookup_mind_specifenvindsp)infn(Names.GlobRef.ConstructRef(indsp,i))typdoneletind_handlerfnprefix(id,(_obj:DeclareInd.Internal.inductive_obj))=letopenNamesinletkn=KerName.makeprefix.Nametab.obj_mp(Label.of_idid)inletmind=Global.mind_of_delta_knkninletmib=Global.lookup_mindmindinletenv=Global.env()inletiter_packetimip=letind=(mind,i)inletu=UVars.make_abstract_instance(Declareops.inductive_polymorphic_contextmib)inlettyp=Inductive.type_of_inductive(Inductive.lookup_mind_specifenvind,u)inlet()=fn(GlobRef.IndRefind)typinletlen=Array.lengthmip.Declarations.mind_user_lciniter_constructorsindufnenvleninArray.iteriiter_packetmib.mind_packetslethandlerfn_cfn_iprefix=DynHandle.addDeclare.Internal.Constant.tag(const_handlerfn_cprefix)@@DynHandle.addDeclareInd.Internal.objInductive(ind_handlerfn_iprefix)@@DynHandle.emptylethandleh(Libobject.Dyn.Dyn(tag,o))=matchDynHandle.findtaghwith|f->fo|exceptionStdlib.Not_found->()letobj_actionfn_cfn_iprefixlobj=matchlobjwith|Libobject.AtomicObjecto->handle(handlerfn_cfn_iprefix)o|_->()letconstructor_namecidx=letcname=Nametab.shortest_qualid_of_globalNames.Id.Set.empty(Names.GlobRef.ConstructRef(c,idx))inLibnames.string_of_qualidcnameletconstructor_info(gref:Names.GlobRef.t)=matchgrefwith|ConstructRef(ind,idx)->letind_dp=Names.(MutInd.modpath(fstind)|>ModPath.dp)inSome(ind_dp,constructor_nameindidx)|VarRef_|ConstRef_|IndRef_->Noneletbelongs_to_libdpsdp=List.exists(funp->Libnames.is_dirpath_prefix_ofpdp)dpsmoduleEntry=structtypet={name:string;typ:Constr.t;file:string}endletfind_v_filedir=matchLoadpath.locate_absolute_librarydirwith(* EJGA: we want to improve this as to pass the error to the client *)|Error_->"error when trying to locate the .v file"|Okfile->filelettocdps:Entry.tlist=letres:Entry.tlistref=ref[]inletobj_action=letfn_c(cst:Names.Constant.t)(_:Decls.logical_kind)(typ:Constr.t)=letcst_dp=Names.(Constant.modpathcst|>ModPath.dp)inifbelongs_to_libdpscst_dpthen(* let () = F.eprintf "cst found: %s@\n%!" (Names.Constant.to_string
cst) in *)letname=Names.Constant.to_stringcstinletfile=find_v_filecst_dpinres:={name;typ;file}::!reselse()in(* We do nothing for inductives, note this is called both on constructors
and inductives, with the name and type *)letfn_i(gref:Names.GlobRef.t)(typ:Constr.t)=matchconstructor_infogrefwith|None->()|Some(ind_dp,name)->ifbelongs_to_libdpsind_dpthenletfile=find_v_fileind_dpinres:={name;typ;file}::!resinobj_actionfn_cfn_iinlet()=Declaremods.iter_all_interp_segmentsobj_actioninList.rev!reslettoc~token~stdps=State.in_state~token~st~f:tocdps