Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file mdx_top.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688(*
* Copyright (c) 2017 Frédéric Bour
* Copyright (c) 2018 Thomas Gazagnaire <thomas@gazagnaire.org>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*)openMdx.CompatopenCompat_toptypedirective=Directoryofstring|Loadofstringletredirect~f=letstdout_backup=Unix.dupUnix.stdoutinletstderr_backup=Unix.dupUnix.stdoutinletfilename=Filename.temp_file"ocaml-mdx""stdout"inletfd_out=Unix.openfilefilenameUnix.[O_WRONLY;O_CREAT;O_TRUNC]0o600inUnix.dup2fd_outUnix.stdout;Unix.dup2fd_outUnix.stderr;letic=open_infilenameinletread_up_to=ref0inletcapturebuf=flushstdout;flushstderr;letpos=Unix.lseekfd_out0Unix.SEEK_CURinletlen=pos-!read_up_toinread_up_to:=pos;Buffer.add_channelbuficlenintry_finally(fun()->f~capture)~always:(fun()->close_in_noerric;Unix.closefd_out;Unix.dup2stdout_backupUnix.stdout;Unix.dup2stderr_backupUnix.stderr;Unix.closestdout_backup;Unix.closestderr_backup;Sys.removefilename)moduleLexbuf=structopenLexingtypet={contents:string;lexbuf:lexbuf}lettoplevel_fname="//toplevel//"letshift_toplevel_position~startpos={pos_fname=toplevel_fname;pos_lnum=pos.pos_lnum-start.pos_lnum+1;pos_bol=pos.pos_bol-start.pos_cnum-1;pos_cnum=pos.pos_cnum-start.pos_cnum;}letshift_toplevel_location~startloc=letopenLocationin{locwithloc_start=shift_toplevel_position~startloc.loc_start;loc_end=shift_toplevel_position~startloc.loc_end;}letsemisemi_action=letlexbuf=Lexing.from_string";;"inmatchLexer.tokenlexbufwith|Parser.SEMISEMI->lexbuf.Lexing.lex_last_action|_->assertfalseletshift_location_errorstart=map_error_loc~f:(shift_toplevel_location~start)letposition_mapperstart=letopenAst_mapperinletstart={startwithpos_fname=toplevel_fname}inletlocationmapperloc=shift_toplevel_location~start(default_mapper.locationmapperloc)in{default_mapperwithlocation}endmodulePhrase=structopenLexingopenParsetreetypet={doc:Lexbuf.t;startpos:position;endpos:position;parsed:(toplevel_phrase,exn)Result.result;}letresultt=t.parsedletstartt=t.startposletparselines=letcontents=String.concat"\n"linesinletlexbuf=Lexing.from_stringcontentsinletstartpos=lexbuf.Lexing.lex_start_pinletparsed=matchParse.toplevel_phraselexbufwith|phrase->Result.Okphrase|exceptionexn->letexn=matcherror_of_exnexnwith|None->raiseexn|Someerror->Location.Error(Lexbuf.shift_location_errorstartposerror)in(iflexbuf.Lexing.lex_last_action<>Lexbuf.semisemi_actionthenletrecaux()=matchLexer.tokenlexbufwith|Parser.SEMISEMI|Parser.EOF->()|exceptionLexer.Error(_,_)->()|_->aux()inaux());Errorexninletendpos=lexbuf.Lexing.lex_curr_pin{doc={lexbuf;contents};startpos;endpos;parsed}letends_by_semi_semic=matchList.revcwith|h::_->letlen=String.lengthhinlen>2&&h.[len-1]=';'&&h.[len-2]=';'|_->falseletparselines=letlines=ifends_by_semi_semilinesthenlineselselines@[";;"]inmatchparselineswithexceptionEnd_of_file->None|t->Sometletis_findlib_directive=letfindlib_directive=function|"require"|"use"|"camlp4o"|"camlp4r"|"thread"->true|_->falseinfunction|{parsed=Oktoplevel_phrase;_}->(matchCompat_top.top_directive_nametoplevel_phrasewith|Somedir->findlib_directivedir|None->false)|_->falseendopenParsetreemoduleRewrite=structtypet={typ:Longident.t;witness:Longident.t;runner:Longident.t;rewrite:Location.t->expression->expression;mutablepreload:stringoption;}(* Rewrite Lwt.t expressions to Lwt_main.run <expr> *)letlwt=lettyp=Longident.(Ldot(Lident"Lwt","t"))inletrunner=Longident.(Ldot(Lident"Lwt_main","run"))inletwitness=Longident.(Ldot(Lident"Lwt","return"))inletpreload=Some"lwt.unix"inletopenAst_helperinletrewriteloce=with_default_locloc(fun()->Exp.apply(Exp.ident(Location.mklocrunnerloc))[(Asttypes.Nolabel,e)])in{typ;runner;rewrite;witness;preload}(* Rewrite Async.Defered.t expressions to
Async.Thread_safe.block_on_async_exn (fun () -> <expr>). *)letasync=lettyp=Longident.(Ldot(Ldot(Lident"Async","Deferred"),"t"))inletrunner=Longident.(Ldot(Ldot(Lident"Async","Thread_safe"),"block_on_async_exn"))inletwitness=runnerinletpreload=NoneinletopenAst_helperinletrewriteloce=letpunit=Pat.construct(Location.mkloc(Longident.Lident"()")loc)Noneinwith_default_locloc@@fun()->Exp.apply(Exp.ident(Location.mklocrunnerloc))[(Asttypes.Nolabel,Exp.fun_Asttypes.NolabelNonepunite)]in{typ;runner;rewrite;witness;preload}letnormalize_type_pathenvpath=matchEnv.find_typepathenvwith|{Types.type_manifest=Somety;_}->(matchCtype.expand_headenvtywith|{Types.desc=Types.Tconstr(path,_,_);_}->path|_->path)|_->pathletis_persistent_valueenvlongident=letis_persistent_pathp=Ident.persistent(get_id_in_pathp)intryis_persistent_path(fst(Compat_top.lookup_valuelongidentenv))withNot_found->falseletapplytsenvpstr_itempathe=letrecaux=function|[]->pstr_item|h::t->letlooked_up_path=lookup_typeh.typenvinletty=normalize_type_pathenvlooked_up_pathinifPath.samety(normalize_type_pathenvpath)thenletloc=pstr_item.Parsetree.pstr_locin{Parsetree.pstr_desc=Parsetree.Pstr_eval(h.rewriteloce,[]);Parsetree.pstr_loc=loc;}elseauxtinauxtsletitemtsenvpstr_itemtstr_item=match(pstr_item.Parsetree.pstr_desc,tstr_item.Typedtree.str_desc)with|(Parsetree.Pstr_eval(e,_),Typedtree.Tstr_eval({Typedtree.exp_type=typ;_},_))->(match(Ctype.reprtyp).Types.descwith|Types.Tconstr(path,_,_)->applytsenvpstr_itempathe|_->pstr_item)|_->pstr_itemletactive_rewriters()=List.filter(funt->is_persistent_value!Toploop.toplevel_envt.witness)[lwt;async]letphrasephrase=letis_eval=function|{pstr_desc=Pstr_eval_;_}->true|_->falseinmatchphrasewith|Ptop_defpstrwhenList.existsis_evalpstr->letts=active_rewriters()inifts=[]thenphraseelse(Env.reset_cache_toplevel();letsnap=Btype.snapshot()inletpstr=trylettstr,env=type_structure!Toploop.toplevel_envpstrLocation.noneinList.map2(itemtsenv)pstrtstr.Typedtree.str_itemswith_->pstrinBtype.backtracksnap;Ptop_defpstr)|_->phraseletpreloadverboseppf=letrequirepkg=letp=Compat_top.top_directive_requirepkginlet_=Toploop.execute_phraseverboseppfpin()inmatchactive_rewriters()with|[]->()|ts->letts=List.fold_left(funacct->matcht.preloadwith|None->acc|Somex->t.preload<-None;x::acc)[]tsinList.iter(funpkg->ifverbosethenrequirepkgelseredirect~f:(fun~capture:_->requirepkg))tsendtypet={mutableverbose:bool;mutablesilent:bool;verbose_findlib:bool;}lettoplevel_exec_phrasetppfp=matchPhrase.resultpwith|Errorexn->raiseexn|Okphrase->Warnings.reset_fatal();letmapper=Lexbuf.position_mapper(Phrase.startp)inletphrase=matchphrasewith|Ptop_defstr->Ptop_def(mapper.Ast_mapper.structuremapperstr)|Ptop_dir_asx->xinletphrase=matchphrasewith|Ptop_dir_asx->x|Ptop_defs->Ptop_def(Pparse.apply_rewriters_str~tool_name:"ocaml-mdx"s)inRewrite.preloadt.verbose_findlibppf;letphrase=Rewrite.phrasephraseinif!Clflags.dump_parsetreethenPrintast.top_phraseppfphrase;if!Clflags.dump_sourcethenPprintast.top_phraseppfphrase;Env.reset_cache_toplevel();Toploop.execute_phraset.verboseppfphrasetypevar_and_value=V:'aref*'a->var_and_valueletprotect_vars=letset_varsl=List.iter(fun(V(r,v))->r:=v)linfunvars~f->letbackup=List.map(fun(V(r,_))->V(r,!r))varsinset_varsvars;try_finallyf~always:(fun()->set_varsbackup)letcapture_compiler_stuffppf~f=protect_vars[V(Location.formatter_for_warnings,ppf)]~fletrecltrim=function""::t->ltrimt|l->llettrim_linestr=letlen=String.lengthstriniflen=0thenstrelselettrim_from=ifstr.[0]='\n'then1else0inlettrim_to=ifstr.[len-1]='\n'thenlen-1elseleniniftrim_to-trim_from<=0then""elseString.substrtrim_from(trim_to-trim_from)letrtriml=List.rev(ltrim(List.revl))lettriml=ltrim(rtrim(List.maptrim_linel))letcut_into_sentencesl=letends_by_semi_semih=letlen=String.lengthhinlen>2&&h.[len-1]=';'&&h.[len-2]=';'inletrecauxaccsentence=function|[]->List.rev(List.revsentence::acc)|h::twhenends_by_semi_semih->aux(List.rev(h::sentence)::acc)[]t|h::t->auxacc(h::sentence)tinaux[][]lleterrors=reffalseletevaltcmd=letbuf=Buffer.create1024inletppf=Format.formatter_of_out_channelstderrinerrors:=false;letexec_code~capturephrase=letlines=ref[]inletcapture()=capturebuf;matchBuffer.contentsbufwith|""->()|s->Buffer.clearbuf;lines:=s::!linesinletout_phrase'=!Oprint.out_phraseinletout_phraseppfphr=matchphrwith|Outcometree.Ophr_exception_->out_phrase'ppfphr|_->capture();out_phrase'ppfphr;capture()inOprint.out_phrase:=out_phrase;letrestore()=Oprint.out_phrase:=out_phrase'in(matchtoplevel_exec_phrasetppfphrasewith|ok->errors:=(notok)||!errors;restore()|exceptionexn->errors:=true;restore();Location.report_exceptionppfexn);Format.pp_print_flushppf();capture();ift.silent||(not!errors)&&(nott.verbose_findlib)&&Phrase.is_findlib_directivephrasethen[]elsetrim(List.rev!lines)inredirect~f:(fun~capture->capture_compiler_stuffppf~f:(fun()->letcmd=matchcmdwith|[]|[_]->cmd|h::t->h::List.map((^)" ")tinletphrases=cut_into_sentencescmdinList.map(funphrase->matchPhrase.parsephrasewith|Somet->exec_code~capturet|None->[])phrases|>List.concat|>funx->if!errorsthenResult.ErrorxelseResult.Okx))letall_show_funs=ref[]letreg_show_primnameto_sigdoc=all_show_funs:=to_sig::!all_show_funs;add_directive~name~doc(`Show_primto_sig)letshow_val()=reg_show_prim"show_val"(funenvlocidlid->let_path,desc=Compat_top.find_valueenvloclidin[sig_valueiddesc])"Print the signature of the corresponding value."letshow_type()=reg_show_prim"show_type"(funenvlocidlid->let_path,desc=Compat_top.find_typeenvloclidin[sig_typeiddesc])"Print the signature of the corresponding type constructor."letshow_exception()=reg_show_prim"show_exception"(funenvlocidlid->letdesc=Compat_top.find_constructorenvloclidinifnot(Compat_top.ctype_is_equalenvtrue[desc.cstr_res][Predef.type_exn])thenraiseNot_found;letret_type=ifdesc.cstr_generalizedthenSomePredef.type_exnelseNoneinletext=extension_constructor~ext_type_path:Predef.path_exn~ext_type_params:[]~ext_args:desc.cstr_args~ext_ret_type:ret_type~ext_private:Asttypes.Public~ext_loc:desc.cstr_loc~ext_attributes:desc.cstr_attributesin[sig_typextidext])"Print the signature of the corresponding exception."letshow_module()=letopenTypesinlettrim_signature=function|Mty_signaturesg->Mty_signature(map_sig_attributessg~f:(funattrs->attribute~name:(Location.mknoloc"...")~payload:(Parsetree.PStr[])::attrs))|mty->mtyinreg_show_prim"show_module"(funenvlocidlid->letrecaccum_aliasespathacc=letmd=Env.find_modulepathenvinletacc=sig_moduleid{mdwithmd_type=trim_signaturemd.md_type}::accinmatchmty_pathmd.md_typewith|Somepath->accum_aliasespathacc|None->List.revaccinletpath,_=Compat_top.find_moduleenvloclidinaccum_aliasespath[])"Print the signature of the corresponding module."letshow_module_type()=reg_show_prim"show_module_type"(funenvlocidlid->let_path,desc=Compat_top.find_modtypeenvloclidin[sig_modtypeiddesc])"Print the signature of the corresponding module type."letshow_class()=reg_show_prim"show_class"(funenvlocidlid->let_path,desc=Compat_top.find_classenvloclidin[sig_classiddesc])"Print the signature of the corresponding class."letshow_class_type()=reg_show_prim"show_class_type"(funenvlocidlid->let_path,desc=Compat_top.find_class_typeenvloclidin[sig_class_typeiddesc])"Print the signature of the corresponding class type."letshow()=letto_sigenvlocidlid=letsg=List.fold_left(funsgf->tryfenvlocidlid@sgwith_->sg)[]!all_show_funsinifsg=[]thenraiseNot_foundelsesginadd_directive~name:"show"~doc:"Print the signatures of components from any of the categories below."(`Show_primto_sig)letverboset=add_directive~name:"verbose"~doc:"Be verbose"(`Bool(funx->t.verbose<-x))letsilentt=add_directive~name:"silent"~doc:"Be silent"(`Bool(funx->t.silent<-x))(* BLACK MAGIC: patch field of a module at runtime *)letmonkey_patch(typea)(m:a)(typeb)(prj:unit->b)(v:b)=letm=Obj.reprminletv=Obj.reprvinletv'=Obj.repr(prj())inifv'==vthen()elsetryfori=0toObj.sizem-1doifObj.fieldmi==v'then(Obj.set_fieldmiv;ifObj.repr(prj())==vthenraiseExit;Obj.set_fieldmiv')done;invalid_arg"monkey_patch: field not found"withExit->()letpatch_env()=letmoduleM=structmoduletypeT=moduletypeofEnvletfield()=Env.without_cmisletreplacementfx=fxlet()=monkey_patch(moduleEnv:T)fieldreplacementendin()letprotectfarg=trylet_=fargin()with|Failures->errors:=true;print_strings|Fl_package_base.No_such_package(pkg,reason)->errors:=true;print_string("No such package: "^pkg^ifreason<>""then" - "^reasonelse"")|Fl_package_base.Package_looppkg->errors:=true;print_string("Package requires itself: "^pkg)letin_wordss=(* splits s in words separated by commas and/or whitespace *)letl=String.lengthsinletrecsplitij=ifj<lthenmatchs.[j]with|' '|'\t'|'\n'|'\r'|','->ifi<jthenString.subsi(j-i)::split(j+1)(j+1)elsesplit(j+1)(j+1)|_->spliti(j+1)elseifi<jthen[String.subsi(j-i)]else[]insplit00letinit~verbose:v~silent:s~verbose_findlib~directives~packages~predicates()=Clflags.real_paths:=false;Toploop.set_paths();Mdx.Compat.init_path();Toploop.toplevel_env:=Compmisc.initial_env();Sys.interactive:=false;patch_env();List.iter(function|Directorypath->Topdirs.dir_directorypath|Loadpath->Topdirs.dir_loadFormat.err_formatterpath)directives;Topfind.don't_load_deeplypackages;Topfind.add_predicatespredicates;(* [require] directive is overloaded to toggle the [errors] reference when
an exception is raised. *)Toploop.add_directive"require"(Toploop.Directive_string(funs->protectTopfind.load_deeply(in_wordss))){Toploop.section="Loading code";doc="Load an ocamlfind package"};lett={verbose=v;silent=s;verbose_findlib}inshow();show_val();show_type();show_module();show_module_type();show_exception();show_class();show_class_type();verboset;silentt;tletenvs=Hashtbl.create8letrecsave_summaryaccs=letdefault_casesummary=save_summaryaccsummaryinletaddsummaryid=letacc=ifnot(is_predef_or_globalid)thenletname=Translmod.toplevel_nameidinname::accelseaccinsave_summaryaccsummaryinmatch_envs~value:add~module_:(funsummaryid~present->matchpresentwithtrue->addsummaryid|false->acc)~open_:(funsummaryx->matchxwith|Pidentid->addsummaryid|Pdot_|Papply_->default_casesummary)~class_:add~functor_arg:add~extension:add~empty:(fun()->acc)~constraints:default_case~cltype:default_case~modtype:default_case~type_:default_case~copy_types:default_case~persistent:default_case~value_unbound:default_case~module_unbound:default_caseletdefault_env=ref(Compmisc.initial_env())letfirst_call=reftrueletenv_depsenv=letnames=save_summary[](Env.summaryenv)inletobjs=List.mapToploop.getvaluenamesin(env,names,objs)letload_envenvnamesobjs=Toploop.toplevel_env:=env;List.iter2Toploop.setvaluenamesobjsletin_envef=letenv_name=Mdx.Ocaml_env.nameeinif!first_callthen((* We will start from the *correct* initial environment with
everything loaded, for each environment. *)default_env:=!Toploop.toplevel_env;first_call:=false);letenv,names,objs=tryHashtbl.findenvsenv_namewithNot_found->env_deps!default_envinload_envenvnamesobjs;letres=f()inletenv=!Toploop.toplevel_envinletenv,names,objs=env_depsenvinHashtbl.replaceenvsenv_name(env,names,objs);res