123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830(*
* 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.Migrate_astopenMdx.Compat#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8lettry_finally=Misc.try_finally#elselettry_finallyf~always=Misc.try_finallyfalways#endifmoduleToploop=structincludeToploopletexecute_phraseverboseppfp=execute_phraseverboseppf(to_current.copy_toplevel_phrasep)endletredirect~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_error(start:Lexing.position)=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8letaux(msg:Location.msg)={msgwithloc=shift_toplevel_location~startmsg.loc}infun(report:Location.report)->{reportwithmain=auxreport.main;sub=List.mapauxreport.sub;}#elseletopenLocationinletrecaux(error:Location.error)={errorwithsub=List.mapauxerror.sub;loc=shift_toplevel_location~starterror.loc}inaux#endifletposition_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=matchLocation.error_of_exnexnwith|None->raiseexn#ifOCAML_MAJOR>=4&&OCAML_MINOR>5|Some`Already_displayed->raiseexn|Some(`Okerror)->Location.Error(Lexbuf.shift_location_errorstartposerror)#else|Someerror->Location.Error(Lexbuf.shift_location_errorstartposerror)#endifiniflexbuf.Lexing.lex_last_action<>Lexbuf.semisemi_actionthenbeginletrecaux()=matchLexer.tokenlexbufwith|Parser.SEMISEMI|Parser.EOF->()|exceptionLexer.Error(_,_)->()|_->aux()inaux();end;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@[";;"]inmatchparselineswith|exceptionEnd_of_file->None|t->Sometletis_findlib_directive=letfindlib_directive=function|"require"|"use"|"camlp4o"|"camlp4r"|"thread"->true|_->falseinfunction|{parsed=Ok(Ptop_dir(dir,_));_}->findlib_directivedir|_->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.parse"Lwt.t"inletrunner=Longident.parse"Lwt_main.run"inletwitness=Longident.parse"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.parse"Async.Deferred.t"inletrunner=Longident.parse"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;_}->beginmatchCtype.expand_headenvtywith|{Types.desc=Types.Tconstr(path,_,_);_}->path|_->pathend|_->pathletis_persistent_valueenvlongident=letrecis_persistent_path=function|Path.Pidentid->Ident.persistentid#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8|Path.Pdot(p,_)->is_persistent_pathp#else|Path.Pdot(p,_,_)->is_persistent_pathp#endif|Path.Papply(_,p)->is_persistent_pathpintryis_persistent_path(fst(Env.lookup_valuelongidentenv))withNot_found->falseletapplytsenvpstr_itempathe=letrecaux=function|[]->pstr_item|h::t->#ifOCAML_MAJOR>=4&&OCAML_MINOR<4letlooked_up_path=Env.lookup_typeh.typenv|>fstin#elseletlooked_up_path=Env.lookup_typeh.typenvin#endifletty=normalize_type_pathenvlooked_up_pathinifPath.samety(normalize_type_pathenvpath)then(letloc=pstr_item.Parsetree.pstr_locin{Parsetree.pstr_desc=Parsetree.Pstr_eval(h.rewriteloce,[]);Parsetree.pstr_loc=loc})elseauxtinauxtsletitemtsenvpstr_itemtstr_item=matchpstr_item.Parsetree.pstr_desc,tstr_item.Typedtree.str_descwith|(Parsetree.Pstr_eval(e,_),Typedtree.Tstr_eval({Typedtree.exp_type=typ;_},_))->beginmatch(Ctype.reprtyp).Types.descwith|Types.Tconstr(path,_,_)->applytsenvpstr_itempathe|_->pstr_itemend|_->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=try#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8lettstr,_tsg,_,env=#elselettstr,_tsg,env=#endifTypemod.type_structure!Toploop.toplevel_envpstrLocation.noneinList.map2(itemtsenv)pstrtstr.Typedtree.str_itemswith_->pstrinBtype.backtracksnap;Ptop_defpstr)|_->phraseletpreloadverboseppf=letrequirepkg=letp=Ptop_dir("require",Pdir_stringpkg)inlet_=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[][]lletevaltcmd=letbuf=Buffer.create1024inletppf=Format.formatter_of_bufferbufinleterrors=reffalseinletexec_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'inbeginmatchtoplevel_exec_phrasetppfphrasewith|ok->errors:=notok||!errors;restore()|exceptionexn->errors:=true;restore();Location.report_exceptionppfexnend;Format.pp_print_flushppf();capture();ift.silent||(nott.verbose_findlib&&Phrase.is_findlib_directivephrase)then[]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[]#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3letsection_env="Environment queries"#endifletstd_out=lazy(Format.formatter_of_out_channelstdout)#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3letshow_primto_sigppflid=letenv=!Toploop.toplevel_envinletloc=Location.noneintrylets=matchlidwith|Longident.Lidents->s|Longident.Ldot(_,s)->s|Longident.Lapply_->Format.fprintfppf"Invalid path %a@."Printtyp.longidentlid;raiseExitinletid=Ident.create_persistentsinletsg=to_sigenvlocidlidinPrinttyp.wrap_printing_envenv(fun()->Format.fprintfppf"@[%a@]@."Printtyp.signaturesg)with|Not_found->Format.fprintfppf"@[Unknown element.@]@."|Exit->()#endifletreg_show_primnameto_sigdoc=letlazyppf=std_outinall_show_funs:=to_sig::!all_show_funs;#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3Toploop.add_directivename(Toploop.Directive_ident(show_primto_sigppf)){section=section_env;doc}#elseignore(name,doc,ppf)#endifletshow_val()=reg_show_prim"show_val"(funenvlocidlid->let_path,desc=Typetexp.find_valueenvloclidin#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Types.Sig_value(id,desc,Exported)]#else[Types.Sig_value(id,desc)]#endif)"Print the signature of the corresponding value."letshow_type()=reg_show_prim"show_type"(funenvlocidlid->let_path,desc=Typetexp.find_typeenvloclidin#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Sig_type(id,desc,Trec_not,Exported)]#else[Sig_type(id,desc,Trec_not)]#endif)"Print the signature of the corresponding type constructor."letshow_exception()=reg_show_prim"show_exception"(funenvlocidlid->letdesc=Typetexp.find_constructorenvloclidinifnot(Ctype.equalenvtrue[desc.cstr_res][Predef.type_exn])thenraiseNot_found;letret_type=ifdesc.cstr_generalizedthenSomePredef.type_exnelseNoneinletext={ext_type_path=Predef.path_exn;ext_type_params=[];#ifOCAML_MAJOR>=4&&OCAML_MINOR<3ext_args=desc.cstr_args;#elseext_args=Cstr_tupledesc.cstr_args;#endifext_ret_type=ret_type;ext_private=Asttypes_.Public;Types.ext_loc=desc.cstr_loc;Types.ext_attributes=desc.cstr_attributes;}in#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Sig_typext(id,ext,Text_exception,Exported)]#else[Sig_typext(id,ext,Text_exception)]#endif)"Print the signature of the corresponding exception."letshow_module()=letopenTypesinlettrim_signature=function|Mty_signaturesg->Mty_signature(List.map(function#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8Sig_module(id,mp,md,rs,visibility)->Sig_module(id,mp,{mdwithmd_attributes={attr_name=Location.mknoloc"...";attr_payload=Parsetree_.PStr[];attr_loc=Location.none}::md.md_attributes},rs,visibility)#elseSig_module(id,md,rs)->Sig_module(id,{mdwithmd_attributes=(Location.mknoloc"...",Parsetree_.PStr[])::md.md_attributes},rs)#endif(*| Sig_modtype (id, Modtype_manifest mty) ->
Sig_modtype (id, Modtype_manifest (trim_modtype mty))*)|item->item)sg)|mty->mtyinreg_show_prim"show_module"(funenvlocidlid->letrecaccum_aliasespathacc=letmd=Env.find_modulepathenvinletacc=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8Sig_module(id,Mp_present,{mdwithmd_type=trim_signaturemd.md_type},Trec_not,Exported)::accin#elseSig_module(id,{mdwithmd_type=trim_signaturemd.md_type},Trec_not)::accin#endifmatchmd.md_typewith#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8|Mty_alias(path)->accum_aliasespathacc#elifOCAML_MAJOR>=4&&OCAML_MINOR>3|Mty_alias(_,path)->accum_aliasespathacc#else|Mty_aliaspath->accum_aliasespathacc#endif|Mty_ident_|Mty_signature_|Mty_functor_->List.revaccinletpath,_=Typetexp.find_moduleenvloclidinaccum_aliasespath[])"Print the signature of the corresponding module."letshow_module_type()=reg_show_prim"show_module_type"(funenvlocidlid->let_path,desc=Typetexp.find_modtypeenvloclidin#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Sig_modtype(id,desc,Exported)]#else[Sig_modtype(id,desc)]#endif)"Print the signature of the corresponding module type."letshow_class()=reg_show_prim"show_class"(funenvlocidlid->let_path,desc=Typetexp.find_classenvloclidin#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Sig_class(id,desc,Trec_not,Exported)]#else[Sig_class(id,desc,Trec_not)]#endif)"Print the signature of the corresponding class."letshow_class_type()=reg_show_prim"show_class_type"(funenvlocidlid->let_path,desc=Typetexp.find_class_typeenvloclidin#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8[Sig_class_type(id,desc,Trec_not,Exported)]#else[Sig_class_type(id,desc,Trec_not)]#endif)"Print the signature of the corresponding class type."letshow()=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3letlazypp=std_outinletshowenvlocidlid=letsg=List.fold_left(funsgf->try(fenvlocidlid)@sgwith_->sg)[]!all_show_funsinifsg=[]thenraiseNot_foundelsesginToploop.add_directive"show"(Toploop.Directive_ident(show_primshowpp)){section=section_env;doc="Print the signatures of components \
from any of the categories below.";}#else()#endifletverboset=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3Toploop.add_directive"verbose"(Toploop.Directive_bool(funx->t.verbose<-x)){section=section_env;doc="Be verbose"}#elseignoret#endifletsilentt=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3Toploop.add_directive"silent"(Toploop.Directive_bool(funx->t.silent<-x)){section=section_env;doc="Be silent"}#elseignoret#endifmoduleLinked=structinclude(Topdirs:sigend)#ifOCAML_MAJOR>=4&&OCAML_MINOR>=3include(Ephemeron:sigend)#endifinclude(Uchar:sigend)include(Condition:sigend)end(* BLACK MAGIC: patch field of a module at runtime *)letmonkey_patch(typea)(typeb)(m:a)(prj:unit->b)(v:b)=letm=Obj.reprminletv=Obj.reprvinletv'=Obj.repr(prj())inifv'==vthen()else(tryfori=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()letinit~verbose:v~silent:s~verbose_findlib()=Clflags.real_paths:=false;Toploop.set_paths();Compmisc.init_pathtrue;Toploop.toplevel_env:=Compmisc.initial_env();Sys.interactive:=false;patch_env();Topfind.don't_load_deeply["unix";"findlib.top";"findlib.internal";"compiler-libs.toplevel"];Topfind.add_predicates["byte";"toploop"];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;tmodulePart=Partletenvs=Hashtbl.create8letis_predef_or_globalid=#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8Ident.is_predefid||Ident.globalid#elseIdent.binding_timeid<1000#endifletrecsave_summaryaccs=letopenEnvinmatchswith|Env_value(summary,id,_)->save_summary(Ident.nameid::acc)summary#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8|Env_module(summary,id,_,_)#else|Env_module(summary,id,_)#endif|Env_class(summary,id,_)|Env_functor_arg(summary,id)|Env_open(summary,#ifOCAML_MAJOR=4&&OCAML_MINOR=7_,#endifPidentid)|Env_extension(summary,id,_)->letacc=ifnot(is_predef_or_globalid)thenIdent.unique_toplevel_nameid::accelseaccinsave_summaryaccsummary|Env_empty->acc#ifOCAML_MAJOR>=4&&OCAML_MINOR>=4|Env_constraints(summary,_)#endif|Env_cltype(summary,_,_)|Env_modtype(summary,_,_)|Env_type(summary,_,_)|Env_open(summary,#ifOCAML_MAJOR=4&&OCAML_MINOR=7_,#endif_)#ifOCAML_MAJOR>=4&&OCAML_MINOR>=6|Env_copy_types(summary,_)#endif#ifOCAML_MAJOR>=4&&OCAML_MINOR>=8|Env_persistent(summary,_)#endif->save_summaryaccsummaryletdefault_env=ref(Compmisc.initial_env())letfirst_call=reftrueletenv_depsenv=letnames=save_summary[](Env.summaryenv)inletobjs=List.mapToploop.getvaluenamesinenv,names,objsletload_envenvnamesobjs=Toploop.toplevel_env:=env;List.iter2Toploop.setvaluenamesobjsletin_envenv_namef=if!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