Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file info.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232(* This module is trying to minimize dependencies on modules in Core, so as to allow
[Info], [Error], and [Or_error] to be used in as many places as possible. Please avoid
adding new dependencies. *)open!ImportincludeInfo_intfmoduleString=String0moduleMessage=structtypet=|Could_not_constructofSexp.t|Stringofstring|Exnofexn|SexpofSexp.t|Tag_sexpofstring*Sexp.t*Source_code_position0.toption|Tag_tofstring*t|Tag_argofstring*Sexp.t*t|Of_listofintoption*tlist|With_backtraceoft*string(* backtrace *)[@@deriving_inlinesexp_of]letrecsexp_of_t=(function|Could_not_constructv0->letv0=Sexp.sexp_of_tv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Could_not_construct";v0]|Stringv0->letv0=sexp_of_stringv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"String";v0]|Exnv0->letv0=sexp_of_exnv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Exn";v0]|Sexpv0->letv0=Sexp.sexp_of_tv0inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Sexp";v0]|Tag_sexp(v0,v1,v2)->letv0=sexp_of_stringv0andv1=Sexp.sexp_of_tv1andv2=sexp_of_optionSource_code_position0.sexp_of_tv2inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Tag_sexp";v0;v1;v2]|Tag_t(v0,v1)->letv0=sexp_of_stringv0andv1=sexp_of_tv1inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Tag_t";v0;v1]|Tag_arg(v0,v1,v2)->letv0=sexp_of_stringv0andv1=Sexp.sexp_of_tv1andv2=sexp_of_tv2inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Tag_arg";v0;v1;v2]|Of_list(v0,v1)->letv0=sexp_of_optionsexp_of_intv0andv1=sexp_of_listsexp_of_tv1inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"Of_list";v0;v1]|With_backtrace(v0,v1)->letv0=sexp_of_tv0andv1=sexp_of_stringv1inPpx_sexp_conv_lib.Sexp.List[Ppx_sexp_conv_lib.Sexp.Atom"With_backtrace";v0;v1]:t->Ppx_sexp_conv_lib.Sexp.t)[@@@end]letrecto_strings_humtac=(* We use [Sexp.to_string_mach], despite the fact that we are implementing
[to_strings_hum], because we want the info to fit on a single line, and once we've
had to resort to sexps, the message is going to start not looking so pretty
anyway. *)matchtwith|Could_not_constructsexp->"could not construct info: "::Sexp.to_string_machsexp::ac|Stringstring->string::ac|Exnexn->Sexp.to_string_mach(Exn.sexp_of_texn)::ac|Sexpsexp->Sexp.to_string_machsexp::ac|Tag_sexp(tag,sexp,_)->tag::": "::Sexp.to_string_machsexp::ac|Tag_t(tag,t)->tag::": "::to_strings_humtac|Tag_arg(tag,sexp,t)->letbody=Sexp.to_string_machsexp::": "::to_strings_humtacinifString.lengthtag=0thenbodyelsetag::": "::body|With_backtrace(t,backtrace)->to_strings_humt("\nBacktrace:\n"::backtrace::ac)|Of_list(trunc_after,ts)->letts=matchtrunc_afterwith|None->ts|Somemax->letn=List.lengthtsinifn<=maxthentselseList.taketsmax@[String(Printf.sprintf"and %d more info"(n-max))]inList.fold(List.revts)~init:ac~f:(funact->to_strings_humt(ifList.is_emptyacthenacelse"; "::ac));;letto_string_hum_deprecatedt=String.concat(to_strings_humt[])letrecto_sexps_humtac=matchtwith|Could_not_construct_ast->sexp_of_tt::ac|Stringstring->Atomstring::ac|Exnexn->Exn.sexp_of_texn::ac|Sexpsexp->sexp::ac|Tag_sexp(tag,sexp,here)->List(Atomtag::sexp::(matchherewith|None->[]|Somehere->[Source_code_position0.sexp_of_there]))::ac|Tag_t(tag,t)->List(Atomtag::to_sexps_humt[])::ac|Tag_arg(tag,sexp,t)->letbody=sexp::to_sexps_humt[]inifString.lengthtag=0thenListbody::acelseList(Atomtag::body)::ac|With_backtrace(t,backtrace)->Sexp.List[to_sexp_humt;Sexp.Atombacktrace]::ac|Of_list(_,ts)->List.fold(List.revts)~init:ac~f:(funact->to_sexps_humtac)andto_sexp_humt=matchto_sexps_humt[]with|[sexp]->sexp|sexps->Sexp.Listsexps;;(* We use [protect] to guard against exceptions raised by user-supplied functions, so
that failure to produce one part of an info doesn't interfere with other parts. *)letprotectf=tryf()with|exn->Could_not_construct(Exn.sexp_of_texn);;letof_infoinfo=protect(fun()->Lazy.forceinfo)letto_infot=lazytendopenMessagetypet=Message.tLazy.tletinvariant_=()letto_message=Message.of_infoletof_message=Message.to_info(* It is OK to use [Message.to_sexp_hum], which is not stable, because [t_of_sexp] below
can handle any sexp. *)letsexp_of_tt=Message.to_sexp_hum(to_messaget)lett_of_sexpsexp=lazy(Message.Sexpsexp)letcomparet1t2=Sexp.compare(sexp_of_tt1)(sexp_of_tt2)letequalt1t2=Sexp.equal(sexp_of_tt1)(sexp_of_tt2)lethash_fold_tstatet=Sexp.hash_fold_tstate(sexp_of_tt)lethasht=Hash.runhash_fold_ttletto_string_humt=matchto_messagetwith|Strings->s|message->Sexp.to_string_hum(Message.to_sexp_hummessage);;letto_string_hum_deprecatedt=Message.to_string_hum_deprecated(to_messaget)letto_string_macht=Sexp.to_string_mach(sexp_of_tt)letof_lazyl=lazy(protect(fun()->String(Lazy.forcel)))letof_lazy_tlazy_t=Lazy.joinlazy_tletof_stringmessage=Lazy.from_val(Stringmessage)letcreatefformat=Printf.ksprintfof_stringformatletof_thunkf=lazy(protect(fun()->String(f())))letcreate?here?stricttagxsexp_of_x=matchstrictwith|None->lazy(protect(fun()->Tag_sexp(tag,sexp_of_xx,here)))|Some()->of_message(Tag_sexp(tag,sexp_of_xx,here));;letcreate_ssexp=Lazy.from_val(Sexpsexp)lettagt~tag=lazy(Tag_t(tag,to_messaget))lettag_st~tag=lazy(protect(fun()->Tag_arg("",tag,to_messaget)))lettag_argttagxsexp_of_x=lazy(protect(fun()->Tag_arg(tag,sexp_of_xx,to_messaget)));;letof_list?trunc_afterts=lazy(Of_list(trunc_after,List.mapts~f:to_message))exceptionExnoftlet()=(* We install a custom exn-converter rather than use
[exception Exn of t [@@deriving_inline sexp][@@@end]] to eliminate the extra wrapping of
"(Exn ...)". *)Sexplib.Conv.Exn_converter.add[%extension_constructorExn](function|Exnt->sexp_of_tt|_->(* Reaching this branch indicates a bug in sexplib. *)assertfalse);;letto_exnt=ifnot(Lazy.is_valt)thenExntelse(matchLazy.forcetwith|Message.Exnexn->exn|_->Exnt);;letof_exn?backtraceexn=letbacktrace=matchbacktracewith|None->None|Some`Get->Some(Caml.Printexc.get_backtrace())|Some(`Thiss)->Somesinmatchexn,backtracewith|Exnt,None->t|Exnt,Somebacktrace->lazy(With_backtrace(to_messaget,backtrace))|_,None->Lazy.from_val(Message.Exnexn)|_,Somebacktrace->lazy(With_backtrace(Sexp(Exn.sexp_of_texn),backtrace));;includePretty_printer.Register_pp(structtypenonrect=tletmodule_name="Base.Info"letppppft=Caml.Format.pp_print_stringppf(to_string_humt)end)moduleInternal_repr=Message