123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695(*
* Copyright (c) 2016 Thomas Refis <trefis@janestreet.com>
*
* 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.
*)openOdoc_model.NamesmoduleLocation=Odoc_model.Location_modulePaths=Odoc_model.PathsopenTypesmoduleO=CodefmtopenO.Infix(* TODO: Title formatting should be a renderer decision *)letformat_titlekindname=letmktitle=letlevel=0andlabel=Nonein[Item.Heading{level;label;title}]inletprefixs=mk(inline(Text(s^" "))::O.code(O.txtname))inmatchkindwith|`Mod->prefix"Module"|`Arg->prefix"Parameter"|`Mty->prefix"Module type"|`Cty->prefix"Class type"|`Class->prefix"Class"|`Page->mk[inline@@Textname]letmake_name_from_path{Url.Path.name;parent;_}=matchparentwith|None->name|Somep->Printf.sprintf"%s.%s"p.namenameletlabelt=matchtwith|Odoc_model.Lang.TypeExpr.Labels->O.txts|Optionals->O.txt"?"++O.txtslettagtagt=O.span~attr:tagtlettype_vartv=tag"type-var"(O.txttv)letenclose~l~rx=O.span(O.txtl++x++O.txtr)letpathptxt=O.elt[inline@@InternalLink(InternalLink.Resolved(Url.from_pathp,txt))]letresolvedptxt=O.elt[inline@@InternalLink(InternalLink.Resolved(p,txt))]letunresolvedtxt=O.elt[inline@@InternalLink(InternalLink.Unresolvedtxt)]letpath_to_idpath=matchUrl.Anchor.from_identifier(path:>Paths.Identifier.t)with|Error_->None|Okurl->Someurlletattach_expansion?(status=`Default)(eq,o,e)pagetext=matchpagewith|None->O.documentedSrctext|Some(page:Page.t)->leturl=page.urlinletsummary=O.rendertextinletexpansion=O.documentedSrc(O.txteq++O.keywordo)@DocumentedSrc.[Subpage{status;content=page}]@O.documentedSrc(O.keyworde)inDocumentedSrc.[Alternative(Expansion{summary;url;status;expansion})](** Returns the preamble as an item. Stop the preamble at the first heading. The
rest is inserted into [items]. *)letprepare_preamblecommentitems=letpreamble,first_comment=Utils.split_at~f:(function|{Odoc_model.Location_.value=`Heading_;_}->true|_->false)commentin(Comment.standalonepreamble,Comment.standalonefirst_comment@items)letmake_expansion_pagetitlekindurl?(header_title=make_name_from_pathurl)commentsitems=letcomment=List.concatcommentsinletpreamble,items=prepare_preamblecommentitemsinletheader=format_titlekindheader_title@preamblein{Page.title;header;items;url}includeGenerator_signaturesmoduleMake(Syntax:SYNTAX)=structmoduleLink:sigvalfrom_path:Paths.Path.t->textvalfrom_fragment:Paths.Fragment.leaf->textend=structopenPathsletrecfrom_path:Path.t->text=funpath->matchpathwith|`Identifier(id,_)->unresolved[inline@@Text(Identifier.nameid)]|`Rootroot->unresolved[inline@@Textroot]|`Forwardroot->unresolved[inline@@Textroot](* FIXME *)|`Dot(prefix,suffix)->letlink=from_path(prefix:>Path.t)inlink++O.txt("."^suffix)|`Apply(p1,p2)->letlink1=from_path(p1:>Path.t)inletlink2=from_path(p2:>Path.t)inlink1++O.txt"("++link2++O.txt")"|`Resolved_whenPaths.Path.is_hiddenpath->lettxt=Url.render_pathpathinFormat.eprintf"Warning, resolved hidden path: %s\n%!"txt;unresolved[inline@@Texttxt]|`Resolvedrp->((* If the path is pointing to an opaque module or module type
there won't be a page generated - so we stop before; at
the parent page, and link instead to the anchor representing
the declaration of the opaque module(_type) *)letstop_before=matchrpwith|`OpaqueModule_|`OpaqueModuleType_->true|_->falseinletid=Paths.Path.Resolved.identifierrpinlettxt=Url.render_pathpathinmatchUrl.from_identifier~stop_beforeidwith|Okhref->resolvedhref[inline@@Texttxt]|Error(Url.Error.Not_linkable_)->O.txttxt|Errorexn->Printf.eprintf"Id.href failed: %S\n%!"(Url.Error.to_stringexn);O.txttxt)letdotprefixsuffix=prefix^"."^suffixletrecrender_fragment_any:Fragment.t->string=funfragment->matchfragmentwith|`Resolvedrr->render_resolved_fragmentrr|`Dot(`Root,suffix)->suffix|`Dot(prefix,suffix)->dot(render_fragment_any(prefix:>Fragment.t))suffix|`Root->assertfalseandrender_resolved_fragment:Fragment.Resolved.t->string=letopenFragment.Resolvedinfunfragment->matchfragmentwith|`Root_->assertfalse|`Subst(_,rr)->render_resolved_fragment(rr:>t)|`Alias(_,rr)->render_resolved_fragment(rr:>t)|`Module(`Root_,s)->ModuleName.to_strings|`Module_type(`Root_,s)->ModuleTypeName.to_strings|`Type(`Root_,s)->TypeName.to_strings|`Class(`Root_,s)->ClassName.to_strings|`ClassType(`Root_,s)->ClassTypeName.to_strings|`Module(rr,s)->dot(render_resolved_fragment(rr:>t))(ModuleName.to_strings)|`Module_type(rr,s)->dot(render_resolved_fragment(rr:>t))(ModuleTypeName.to_strings)|`Type(rr,s)->dot(render_resolved_fragment(rr:>t))(TypeName.to_strings)|`Class(rr,s)->dot(render_resolved_fragment(rr:>t))(ClassName.to_strings)|`ClassType(rr,s)->dot(render_resolved_fragment(rr:>t))(ClassTypeName.to_strings)|`OpaqueModuler->render_resolved_fragment(r:>t)letresolved_fragment_to_ir:Fragment.Resolved.leaf->text=funfragment->letopenFragmentinletid=Resolved.identifier(fragment:>Resolved.t)inlettxt=render_resolved_fragment(fragment:>Resolved.t)inmatchUrl.from_identifier~stop_before:falseidwith|Okhref->resolvedhref[inline@@Texttxt]|Error(Not_linkable_)->unresolved[inline@@Texttxt]|Errorexn->Printf.eprintf"[FRAG] Id.href failed: %S\n%!"(Url.Error.to_stringexn);unresolved[inline@@Texttxt]letfrom_fragment:Fragment.leaf->text=function|`Resolvedrwhennot(Fragment.Resolved.is_hidden(r:>Fragment.Resolved.t))->resolved_fragment_to_irr|f->lettxt=render_fragment_any(f:>Fragment.t)inunresolved[inline@@Texttxt]endmoduleType_expression:sigvaltype_expr:?needs_parentheses:bool->Lang.TypeExpr.t->textvalformat_type_path:delim:[`parens|`brackets]->Lang.TypeExpr.tlist->text->textend=structletrecte_variant(t:Odoc_model.Lang.TypeExpr.Polymorphic_variant.t)=letstyle_arguments~constantarguments=(* Multiple arguments in a polymorphic variant constructor correspond
to a conjunction of types, not a product: [`Lbl int&float].
If constant is [true], the conjunction starts with an empty type,
for instance [`Lbl &int].
*)letwrapped_type_expr=(* type conjunction in Reason is printed as `Lbl (t1)&(t2)` *)ifSyntax.Type.Variant.parenthesize_paramsthenfunx->enclose~l:"("~r:")"(type_exprx)elsefunx->type_exprxinletarguments=O.listarguments~sep:(O.txt" & ")~f:wrapped_type_exprinifconstantthenO.txt"& "++argumentselseargumentsinletrecstyle_elements~add_pipe=function|[]->O.noop|first::rest->letfirst=matchfirstwith|Odoc_model.Lang.TypeExpr.Polymorphic_variant.Typete->letres=O.box_hv@@type_exprteinifadd_pipethenO.sp++O.span(O.txt"| "++res)elseres|Constructor{constant;name;arguments;_}->letconstr=letname="`"^nameinifadd_pipethenO.span(O.txt("| "^name))elseO.txtnameinletres=O.box_hv(matchargumentswith|[]->constr|_->letarguments=style_arguments~constantargumentsinO.span(ifSyntax.Type.Variant.parenthesize_paramsthenconstr++argumentselseconstr++O.txt" of"++O.sp++arguments))inifadd_pipethenO.sp++reselseresinfirst++style_elements~add_pipe:truerestinletelements=style_elements~add_pipe:falset.elementsinO.box_hv_no_indent@@O.span(matcht.kindwith|Fixed->O.txt"[ "++elements++O.txt" ]"|Open->O.txt"[> "++elements++O.txt" ]"|Closed[]->O.txt"[< "++elements++O.txt" ]"|Closedlst->letconstrs=String.concat" "lstinO.txt"[< "++elements++O.txt(" "^constrs^" ]"))andte_object(t:Odoc_model.Lang.TypeExpr.Object.t)=letfields=O.list~sep:(O.sp++O.txtSyntax.Obj.field_separator)t.fields~f:(function|Odoc_model.Lang.TypeExpr.Object.Method{name;type_}->O.box_hv_no_indent@@O.txt(name^Syntax.Type.annotation_separator)++O.cut++type_exprtype_|Inherittype_->O.box_hv_no_indent@@type_exprtype_)inletopen_tag=ift.open_thenO.txtSyntax.Obj.open_tag_extendableelseO.txtSyntax.Obj.open_tag_closedinletclose_tag=ift.open_thenO.txtSyntax.Obj.close_tag_extendableelseO.txtSyntax.Obj.close_tag_closedinO.span(open_tag++fields++close_tag)andformat_type_path~delim(params:Odoc_model.Lang.TypeExpr.tlist)(path:text):text=O.box_hv@@matchparamswith|[]->path|[param]->letparam=type_expr~needs_parentheses:trueparaminletargs=ifSyntax.Type.parenthesize_constructorthenO.txt"("++param++O.txt")"elseparaminSyntax.Type.handle_constructor_paramspathargs|params->letparams=O.listparams~sep:(O.txt","++O.sp)~f:type_exprinletparams=matchdelimwith|`parens->enclose~l:"( "params~r:" )"|`brackets->enclose~l:"[ "params~r:" ]"inSyntax.Type.handle_constructor_paramspath(O.box_hvparams)andtype_expr?(needs_parentheses=false)(t:Odoc_model.Lang.TypeExpr.t)=matchtwith|Vars->type_var(Syntax.Type.var_prefix^s)|Any->type_varSyntax.Type.any|Alias(te,alias)->type_expr~needs_parentheses:truete++O.txt" "++O.keyword"as"++O.txt" '"++O.txtalias|Arrow(None,src,dst)->letres=O.span((O.box_hv@@type_expr~needs_parentheses:truesrc)++O.txt" "++Syntax.Type.arrow)++O.sp++type_exprdst(* ++ O.end_hv *)inifnotneeds_parenthesesthenreselseenclose~l:"( "res~r:" )"|Arrow(Somelbl,src,dst)->letres=O.span((O.box_hv@@labellbl++O.txt":"++O.cut++(O.box_hv@@type_expr~needs_parentheses:truesrc))++O.txt" "++Syntax.Type.arrow)++O.sp++type_exprdstinifnotneeds_parenthesesthenreselseenclose~l:"( "res~r:" )"|Tuplelst->letres=O.box_hv_no_indent(O.listlst~sep:Syntax.Type.Tuple.element_separator~f:(type_expr~needs_parentheses:true))inifSyntax.Type.Tuple.always_parenthesize||needs_parenthesesthenenclose~l:"("res~r:")"elseres|Constr(path,args)->letlink=Link.from_path(path:>Paths.Path.t)informat_type_path~delim:`parensargslink|Polymorphic_variantv->te_variantv|Objecto->te_objecto|Class(path,args)->format_type_path~delim:`bracketsargs(Link.from_path(path:>Paths.Path.t))|Poly(polyvars,t)->O.txt("'"^String.concat" '"polyvars^". ")++type_exprt|Packagepkg->enclose~l:"("~r:")"(O.keyword"module"++O.txt" "++Link.from_path(pkg.path:>Paths.Path.t)++matchpkg.substitutionswith|[]->O.noop|fst::lst->O.sp++O.box_hv(O.keyword"with"++O.txt" "++package_substfst)++O.listlst~f:(funs->O.cut++(O.box_hv@@O.txt" "++O.keyword"and"++O.txt" "++package_substs)))andpackage_subst((frag_typ,te):Paths.Fragment.Type.t*Odoc_model.Lang.TypeExpr.t):text=lettypath=Link.from_fragment(frag_typ:>Paths.Fragment.leaf)inO.keyword"type"++O.txt" "++typath++O.txt" ="++O.sp++type_exprteendopenType_expression(* Also handles constructor declarations for exceptions and extensible
variants, and exposes a few helpers used in formatting classes and signature
constraints. *)moduleType_declaration:sigvaltype_decl:?is_substitution:bool->Lang.Signature.recursive*Lang.TypeDecl.t->Item.tvalextension:Lang.Extension.t->Item.tvalexn:Lang.Exception.t->Item.tvalformat_params:?delim:[`parens|`brackets]->Lang.TypeDecl.paramlist->textvalformat_manifest:?is_substitution:bool->?compact_variants:bool->Lang.TypeDecl.Equation.t->text*boolvalformat_constraints:(Lang.TypeExpr.t*Lang.TypeExpr.t)list->textend=structletrecordfields=letfieldmutable_idtyp=matchUrl.from_identifier~stop_before:trueidwith|Errore->failwith(Url.Error.to_stringe)|Okurl->letname=Paths.Identifier.nameidinletattrs=["def";"record";Url.Anchor.string_of_kindurl.kind]inletcell=(* O.td ~a:[ O.a_class ["def"; kind ] ]
* [O.a ~a:[O.a_href ("#" ^ anchor); O.a_class ["anchor"]] []
* ; *)O.code((ifmutable_thenO.keyword"mutable"++O.txt" "elseO.noop)++O.txtname++O.txtSyntax.Type.annotation_separator++type_exprtyp++O.txtSyntax.Type.Record.field_separator)(* ] *)in(url,attrs,cell)inletrows=fields|>List.map(funfld->letopenOdoc_model.Lang.TypeDecl.Fieldinleturl,attrs,code=fieldfld.mutable_(fld.id:>Paths.Identifier.t)fld.type_inletanchor=Someurlinletrhs=Comment.to_irfld.docinletdoc=ifnot(Comment.has_docfld.doc)then[]elserhsinletmarkers=Syntax.Comment.markersinDocumentedSrc.Documented{anchor;attrs;code;doc;markers})inletcontent=O.documentedSrc(O.txt"{")@rows@O.documentedSrc(O.txt"}")incontentletconstructor:Paths.Identifier.t->Odoc_model.Lang.TypeDecl.Constructor.argument->Odoc_model.Lang.TypeExpr.toption->DocumentedSrc.t=funidargsret_type->letname=Paths.Identifier.nameidinletkind=Url.(kindid|>Anchor.string_of_kind)inletcstr=tagkind(O.txtname)inletis_gadt,ret_type=matchret_typewith|None->(false,O.noop)|Somete->letconstant=matchargswithTuple[]->true|_->falseinletret_type=O.txt" "++(ifconstantthenO.txt":"elseSyntax.Type.GADT.arrow)++O.txt" "++type_exprtein(true,ret_type)inmatchargswith|Tuple[]->O.documentedSrc(cstr++ret_type)|Tuplelst->letparams=O.listlst~sep:Syntax.Type.Tuple.element_separator~f:(type_expr~needs_parentheses:is_gadt)inO.documentedSrc(cstr++(ifSyntax.Type.Variant.parenthesize_paramsthenO.txt"("++params++O.txt")"else(ifis_gadtthenO.txtSyntax.Type.annotation_separatorelseO.txt" "++O.keyword"of"++O.txt" ")++params)++ret_type)|Recordfields->ifis_gadtthenO.documentedSrc(cstr++O.txtSyntax.Type.annotation_separator)@recordfields@O.documentedSrcret_typeelseO.documentedSrc(cstr++O.txt" "++O.keyword"of"++O.txt" ")@recordfieldsletrecread_typ_exptyp_expr=letopenLang.TypeExprinletopenPaths.Pathinmatchtyp_exprwith|Constr(p,ts)->is_hidden(p:>Paths.Path.t)||List.exists(funt->read_typ_expt)ts|Poly(_,t)|Alias(t,_)->read_typ_expt|Arrow(_,t,t2)->read_typ_expt||read_typ_expt2|Tuplets|Class(_,ts)->List.exists(funt->read_typ_expt)ts|_->falseletinternal_cstr_argt=letopenLang.TypeDecl.ConstructorinletopenLang.TypeDecl.Fieldinmatcht.argswith|Tupletype_exprs->List.exists(funtype_expr->read_typ_exptype_expr)type_exprs|Recordfields->List.exists(funfield->read_typ_expfield.type_)fieldsletvariantcstrs:DocumentedSrc.t=letconstructoridargsres=matchUrl.from_identifier~stop_before:trueidwith|Errore->failwith(Url.Error.to_stringe)|Okurl->letattrs=["def";"variant";Url.Anchor.string_of_kindurl.kind]inletcontent=letdoc=constructoridargsresinO.documentedSrc(O.txt"| ")@docin(url,attrs,content)inmatchcstrswith|[]->O.documentedSrc(O.txt"|")|_::_->letrows=cstrs|>List.filter(funcstr->not(internal_cstr_argcstr))|>List.map(funcstr->letopenOdoc_model.Lang.TypeDecl.Constructorinleturl,attrs,code=constructor(cstr.id:>Paths.Identifier.t)cstr.argscstr.resinletanchor=Someurlinletrhs=Comment.to_ircstr.docinletdoc=ifnot(Comment.has_doccstr.doc)then[]elserhsinletmarkers=Syntax.Comment.markersinDocumentedSrc.Nested{anchor;attrs;code;doc;markers})inrowsletextension_constructor(t:Odoc_model.Lang.Extension.Constructor.t)=letid=(t.id:>Paths.Identifier.t)inmatchUrl.from_identifier~stop_before:trueidwith|Errore->failwith(Url.Error.to_stringe)|Okurl->letanchor=Someurlinletattrs=["def";Url.Anchor.string_of_kindurl.kind]inletcode=O.documentedSrc(O.txt"| ")@constructoridt.argst.resinletdoc=Comment.to_irt.docinletmarkers=Syntax.Comment.markersinDocumentedSrc.Nested{anchor;attrs;code;doc;markers}letextension(t:Odoc_model.Lang.Extension.t)=letprefix=O.keyword"type"++O.txt" "++Link.from_path(t.type_path:>Paths.Path.t)++O.txt" +="++O.spinletcontent=O.documentedSrcprefix@List.mapextension_constructort.constructors@O.documentedSrc(ifSyntax.Type.type_def_semicolonthenO.txt";"elseO.noop)inletattr=["type";"extension"]inletanchor=Some(Url.Anchor.extension_declt)inletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}letexn(t:Odoc_model.Lang.Exception.t)=letcstr=constructor(t.id:>Paths.Identifier.t)t.argst.resinletcontent=O.documentedSrc(O.keyword"exception"++O.txt" ")@cstr@O.documentedSrc(ifSyntax.Type.Exception.semicolonthenO.txt";"elseO.noop)inletattr=["exception"]inletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}letpolymorphic_variant~type_ident(t:Odoc_model.Lang.TypeExpr.Polymorphic_variant.t)=letrowitem=letkind_approx,cstr,doc=matchitemwith|Odoc_model.Lang.TypeExpr.Polymorphic_variant.Typete->("unknown",O.code(type_exprte),None)|Constructor{constant;name;arguments;doc;_}->(letcstr="`"^namein("constructor",(matchargumentswith|[]->O.code(O.txtcstr)|_->(* Multiple arguments in a polymorphic variant constructor correspond
to a conjunction of types, not a product: [`Lbl int&float].
If constant is [true], the conjunction starts with an empty type,
for instance [`Lbl &int].
*)letwrapped_type_expr=(* type conjunction in Reason is printed as `Lbl (t1)&(t2)` *)ifSyntax.Type.Variant.parenthesize_paramsthenfunx->O.txt"("++type_exprx++O.txt")"elsefunx->type_exprxinletparams=O.box_hv@@O.listarguments~sep:(O.txt" &"++O.sp)~f:wrapped_type_exprinletparams=ifconstantthenO.txt"& "++paramselseparamsinO.code(O.txtcstr++ifSyntax.Type.Variant.parenthesize_paramsthenparamselseO.txt" "++O.keyword"of"++O.sp++params)),matchdocwith[]->None|_->Some(Comment.to_irdoc)))inletmarkers=Syntax.Comment.markersintryleturl=Url.Anchor.polymorphic_variant~type_identiteminletattrs=["def";Url.Anchor.string_of_kindurl.kind]inletanchor=Someurlinletcode=O.code(O.txt"| ")@cstrinletdoc=matchdocwithNone->[]|Somedoc->docinDocumentedSrc.Documented{attrs;anchor;code;doc;markers}withFailures->Printf.eprintf"ERROR: %s\n%!"s;letcode=O.code(O.txt"| ")@cstrinletattrs=["def";kind_approx]inletdoc=[]inletanchor=NoneinDocumentedSrc.Documented{attrs;anchor;code;doc;markers}inletvariants=List.maprowt.elementsinletintro,ending=matcht.kindwith|Fixed->(O.documentedSrc(O.txt"[ "),O.documentedSrc(O.txt" ]"))|Open->(O.documentedSrc(O.txt"[> "),O.documentedSrc(O.txt" ]"))|Closed[]->(O.documentedSrc(O.txt"[< "),O.documentedSrc(O.txt" ]"))|Closedlst->letconstrs=String.concat" "lstin(O.documentedSrc(O.txt"[< "),O.documentedSrc(O.txt(" "^constrs^" ]")))inintro@variants@endingletformat_params:'row.?delim:[`parens|`brackets]->Odoc_model.Lang.TypeDecl.paramlist->text=fun?(delim=`parens)params->letformat_param{Odoc_model.Lang.TypeDecl.desc;variance;injectivity}=letdesc=matchdescwith|Odoc_model.Lang.TypeDecl.Any->["_"]|Vars->["'";s]inletvar_desc=matchvariancewith|None->desc|SomeOdoc_model.Lang.TypeDecl.Pos->"+"::desc|SomeOdoc_model.Lang.TypeDecl.Neg->"-"::descinletfinal=ifinjectivitythen"!"::var_descelsevar_descinString.concat""finalinO.txt(matchparamswith|[]->""|[x]->format_paramx|>Syntax.Type.handle_format_params|lst->(letparams=String.concat", "(List.mapformat_paramlst)in(matchdelimwith`parens->"("|`brackets->"[")^params^matchdelimwith`parens->")"|`brackets->"]"))letformat_constraintsconstraints=O.listconstraints~f:(fun(t1,t2)->O.sp++(O.box_hv@@O.keyword"constraint"++O.sp++O.box_hv_no_indent(type_exprt1)++O.txt" ="++O.sp++O.box_hv_no_indent(type_exprt2)))letformat_manifest:'inner_row'outer_row.?is_substitution:bool->?compact_variants:bool->Odoc_model.Lang.TypeDecl.Equation.t->text*bool=fun?(is_substitution=false)?(compact_variants=true)equation->let_=compact_variantsin(* TODO *)letprivate_=equation.private_inmatchequation.manifestwith|None->(O.noop,private_)|Somet->letmanifest=O.txt(ifis_substitutionthen" :="else" =")++O.sp++(ifprivate_thenO.keywordSyntax.Type.private_keyword++O.txt" "elseO.noop)++type_exprtin(manifest,false)lettype_decl?(is_substitution=false)((recursive,t):Lang.Signature.recursive*Lang.TypeDecl.t)=letkeyword'=matchrecursivewith|Ordinary|Rec->O.keyword"type"|And->O.keyword"and"|Nonrec->O.keyword"type"++O.txt" "++O.keyword"nonrec"inlettyname=Paths.Identifier.namet.idinlettconstr=matcht.equation.paramswith|[]->O.txttyname|l->letparams=format_paramslinSyntax.Type.handle_constructor_params(O.txttyname)paramsinletintro=keyword'++O.txt" "++tconstrinletconstraints=format_constraintst.equation.constraintsinletmanifest,need_private,long_prefix=matcht.equation.manifestwith|Some(Odoc_model.Lang.TypeExpr.Polymorphic_variantvariant)->letcode=polymorphic_variant~type_ident:(t.id:>Paths.Identifier.t)variantinletmanifest=O.documentedSrc(O.ignoreintro++O.txt(ifis_substitutionthen" :="else" =")++O.sp++ift.equation.private_thenO.keywordSyntax.Type.private_keyword++O.txt" "elseO.noop)@codein(manifest,false,O.noop)|_->letmanifest,need_private=format_manifest~is_substitutiont.equationinlettext=O.ignoreintro++manifestin(O.documentedSrc@@text,need_private,text)inletrepresentation=matcht.representationwith|None->[]|Somerepr->letcontent=matchreprwith|Extensible->O.documentedSrc(O.txt"..")|Variantcstrs->variantcstrs|Recordfields->recordfieldsinifList.lengthcontent>0thenO.documentedSrc(O.ignorelong_prefix++O.txt" ="++O.sp++ifneed_privatethenO.keywordSyntax.Type.private_keyword++O.txt" "elseO.noop)@contentelse[]inletcontent=O.documentedSrcintro@manifest@representation@O.documentedSrcconstraints@O.documentedSrc(ifSyntax.Type.type_def_semicolonthenO.txt";"elseO.noop)inletattr="type"::(ifis_substitutionthen["subst"]else[])inletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}endopenType_declarationmoduleValue:sigvalvalue:Lang.Value.t->Item.tend=structletvalue(t:Odoc_model.Lang.Value.t)=letextra_attr,semicolon=matcht.valuewith|Abstract->([],Syntax.Value.semicolon)|External_->(["external"],Syntax.Type.External.semicolon)inletname=Paths.Identifier.namet.idinletcontent=O.documentedSrc(O.box_hv@@O.keywordSyntax.Value.variable_keyword++O.txt" "++O.txtname++O.txtSyntax.Type.annotation_separator++O.cut++type_exprt.type_++ifsemicolonthenO.txt";"elseO.noop)inletattr=["value"]@extra_attrinletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}endopenValue(* This chunk of code is responsible for sectioning list of items
according to headings by extracting headings as Items.
TODO: This sectioning would be better done as a pass on the model directly.
*)moduleSectioning:sigopenOdoc_modelvalcomment_items:Comment.docs->Item.tlistvaldocs:Comment.docs->Item.tlist*Item.tlistend=structlettake_until_heading_or_end(docs:Odoc_model.Comment.docs)=letcontent,_,rest=Doctree.Take.untildocs~classify:(funb->matchb.Location.valuewith|`Heading_->Stop_and_keep|#Odoc_model.Comment.attached_block_elementasdoc->letcontent=Comment.attached_block_elementdocinAccumcontent)in(content,rest)letcomment_items(input0:Odoc_model.Comment.docs)=letrecloopinput_commentacc=matchinput_commentwith|[]->List.revacc|element::input_comment->(matchelement.Location.valuewith|`Headingh->letitem=Comment.headinghinloopinput_comment(item::acc)|_->letcontent,input_comment=take_until_heading_or_end(element::input_comment)inletitem=Item.Textcontentinloopinput_comment(item::acc))inloopinput0[](* For doc pages, we want the header to contain everything until
the first heading, then everything before the next heading which
is either lower, or a section.
*)letdocsinput_comment=letitems=comment_itemsinput_commentinletuntil_first_heading,o,items=Doctree.Take.untilitems~classify:(function|Item.Headinghasi->Stop_and_accum([i],Someh.level)|i->Accum[i])inmatchowith|None->(until_first_heading,items)|Somelevel->letmax_level=iflevel=1then2elselevelinletbefore_second_heading,_,items=Doctree.Take.untilitems~classify:(function|Item.Headinghwhenh.level>=max_level->Stop_and_keep|i->Accum[i])inletheader=until_first_heading@before_second_headingin(header,items)endmoduleClass:sigvalclass_:Lang.Class.t->Item.tvalclass_type:Lang.ClassType.t->Item.tend=structletclass_type_expr(cte:Odoc_model.Lang.ClassType.expr)=matchctewith|Constr(path,args)->letlink=Link.from_path(path:>Paths.Path.t)informat_type_path~delim:`bracketsargslink|Signature_->Syntax.Class.open_tag++O.txt" ... "++Syntax.Class.close_tagletmethod_(t:Odoc_model.Lang.Method.t)=letname=Paths.Identifier.namet.idinletvirtual_=ift.virtual_thenO.keyword"virtual"++O.txt" "elseO.noopinletprivate_=ift.private_thenO.keyword"private"++O.txt" "elseO.noopinletcontent=O.documentedSrc(O.keyword"method"++O.txt" "++private_++virtual_++O.txtname++O.txtSyntax.Type.annotation_separator++type_exprt.type_)inletattr=["method"]inletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}letinstance_variable(t:Odoc_model.Lang.InstanceVariable.t)=letname=Paths.Identifier.namet.idinletvirtual_=ift.virtual_thenO.keyword"virtual"++O.txt" "elseO.noopinletmutable_=ift.mutable_thenO.keyword"mutable"++O.txt" "elseO.noopinletcontent=O.documentedSrc(O.keyword"val"++O.txt" "++mutable_++virtual_++O.txtname++O.txtSyntax.Type.annotation_separator++type_exprt.type_)inletattr=["value";"instance-variable"]inletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}letinherit_cte=letcontent=O.documentedSrc(O.keyword"inherit"++O.txt" "++class_type_exprcte)inletattr=["inherit"]inletanchor=Noneinletdoc=[]inItem.Declaration{attr;anchor;doc;content}letconstraint_t1t2=letcontent=O.documentedSrc(format_constraints[(t1,t2)])inletattr=[]inletanchor=Noneinletdoc=[]inItem.Declaration{attr;anchor;doc;content}letclass_signature(c:Lang.ClassSignature.t)=letreclooplacc_items=matchlwith|[]->List.revacc_items|item::rest->(letcontinueitem=looprest(item::acc_items)inmatch(item:Lang.ClassSignature.item)with|Inherit(Signature_)->assertfalse(* Bold. *)|Inheritcty->continue@@inherit_cty|Methodm->continue@@method_m|InstanceVariablev->continue@@instance_variablev|Constraint(t1,t2)->continue@@constraint_t1t2|Comment`Stop->letrest=Utils.skip_untilrest~p:(function|Lang.ClassSignature.Comment`Stop->true|_->false)inlooprestacc_items|Comment(`Docsc)->letitems=Sectioning.comment_itemscinlooprest(List.rev_appenditemsacc_items))in(* FIXME: use [t.self] *)(c.doc,loopc.items[])letrecclass_decl(cd:Odoc_model.Lang.Class.decl)=matchcdwith|ClassTypeexpr->class_type_exprexpr(* TODO: factorize the following with [type_expr] *)|Arrow(None,src,dst)->O.span(type_expr~needs_parentheses:truesrc++O.txt" "++Syntax.Type.arrow)++O.txt" "++class_decldst|Arrow(Somelbl,src,dst)->O.span(labellbl++O.txt":"++type_expr~needs_parentheses:truesrc++O.txt" "++Syntax.Type.arrow)++O.txt" "++class_decldstletclass_(t:Odoc_model.Lang.Class.t)=letname=Paths.Identifier.namet.idinletparams=format_params~delim:`bracketst.paramsinletvirtual_=ift.virtual_thenO.keyword"virtual"++O.txt" "elseO.noopinletcname,expansion,expansion_doc=matcht.expansionwith|None->(O.documentedSrc@@O.txtname,None,None)|Somecsig->letexpansion_doc,items=class_signaturecsiginleturl=Url.Path.from_identifiert.idinletpage=make_expansion_pagename`Classurl[t.doc;expansion_doc]itemsin(O.documentedSrc@@pathurl[inline@@Textname],Somepage,Someexpansion_doc)inletsummary=O.txtSyntax.Type.annotation_separator++class_declt.type_inletcd=attach_expansion(Syntax.Type.annotation_separator,"object","end")expansionsummaryinletcontent=O.documentedSrc(O.keyword"class"++O.txt" "++virtual_++params++O.txt" ")@cname@cdinletattr=["class"]inletanchor=path_to_idt.idinletdoc=Comment.synopsis~decl_doc:t.doc~expansion_docinItem.Declaration{attr;anchor;doc;content}letclass_type(t:Odoc_model.Lang.ClassType.t)=letname=Paths.Identifier.namet.idinletparams=format_params~delim:`bracketst.paramsinletvirtual_=ift.virtual_thenO.keyword"virtual"++O.txt" "elseO.noopinletcname,expansion,expansion_doc=matcht.expansionwith|None->(O.documentedSrc@@O.txtname,None,None)|Somecsig->leturl=Url.Path.from_identifiert.idinletexpansion_doc,items=class_signaturecsiginletpage=make_expansion_pagename`Ctyurl[t.doc;expansion_doc]itemsin(O.documentedSrc@@pathurl[inline@@Textname],Somepage,Someexpansion_doc)inletsummary=O.txt" = "++class_type_exprt.exprinletexpr=attach_expansion(" = ","object","end")expansionsummaryinletcontent=O.documentedSrc(O.keyword"class"++O.txt" "++O.keyword"type"++O.txt" "++virtual_++params++O.txt" ")@cname@exprinletattr=["class-type"]inletanchor=path_to_idt.idinletdoc=Comment.synopsis~decl_doc:t.doc~expansion_docinItem.Declaration{attr;anchor;doc;content}endopenClassmoduleModule:sigvalsignature:Lang.Signature.t->Comment.Comment.docs*Item.tlist(** Returns [header_doc, content]. *)end=structletinternal_modulem=letopenLang.Moduleinmatchm.idwith|`Module(_,name)whenModuleName.is_internalname->true|_->falseletinternal_typet=letopenLang.TypeDeclinmatcht.idwith|`Type(_,name)whenTypeName.is_internalname->true|_->falseletinternal_valuev=letopenLang.Valueinmatchv.idwith|`Value(_,name)whenValueName.is_internalname->true|_->falseletinternal_module_typet=letopenLang.ModuleTypeinmatcht.idwith|`ModuleType(_,name)whenModuleTypeName.is_internalname->true|_->falseletinternal_module_substitutiont=letopenLang.ModuleSubstitutioninmatcht.idwith|`Module(_,name)whenModuleName.is_internalname->true|_->falseletinternal_module_type_substitutiont=letopenLang.ModuleTypeSubstitutioninmatcht.idwith|`ModuleType(_,name)whenModuleTypeName.is_internalname->true|_->falseletrecsignature(s:Lang.Signature.t)=letreclooplacc_items=matchlwith|[]->List.revacc_items|item::rest->(letcontinue(item:Item.t)=looprest(item::acc_items)inmatch(item:Lang.Signature.item)with|Module(_,m)wheninternal_modulem->looprestacc_items|Type(_,t)wheninternal_typet->looprestacc_items|Valuevwheninternal_valuev->looprestacc_items|ModuleTypemwheninternal_module_typem->looprestacc_items|ModuleSubstitutionmwheninternal_module_substitutionm->looprestacc_items|ModuleTypeSubstitutionmwheninternal_module_type_substitutionm->looprestacc_items|ModuleTypeSubstitutionm->continue@@module_type_substitutionm|Module(_,m)->continue@@module_m|ModuleTypem->continue@@module_typem|Class(_,c)->continue@@class_c|ClassType(_,c)->continue@@class_typec|Includem->continue@@include_m|ModuleSubstitutionm->continue@@module_substitutionm|TypeSubstitutiont->continue@@type_decl~is_substitution:true(Ordinary,t)|Type(r,t)->continue@@type_decl(r,t)|TypExte->continue@@extensione|Exceptione->continue@@exne|Valuev->continue@@valuev|Openo->letitems=Sectioning.comment_itemso.docinlooprest(List.rev_appenditemsacc_items)|Comment`Stop->letrest=Utils.skip_untilrest~p:(function|Lang.Signature.Comment`Stop->true|_->false)inlooprestacc_items|Comment(`Docsc)->letitems=Sectioning.comment_itemscinlooprest(List.rev_appenditemsacc_items))in(Lang.extract_signature_docs,loops.items[])andfunctor_parameter:Odoc_model.Lang.FunctorParameter.parameter->DocumentedSrc.t=funarg->letopenOdoc_model.Lang.FunctorParameterinletname=Paths.Identifier.namearg.idinletrender_ty=arg.exprinletmodtyp=mty_in_decl(arg.id:>Paths.Identifier.Signature.t)render_tyinletmodname,mod_decl=matchexpansion_of_module_type_exprarg.exprwith|None->letmodname=O.txt(Paths.Identifier.namearg.id)in(modname,O.documentedSrcmodtyp)|Some(expansion_doc,items)->leturl=Url.Path.from_identifierarg.idinletmodname=pathurl[inline@@Textname]inlettype_with_expansion=letcontent=make_expansion_pagename`Argurl[expansion_doc]itemsinletsummary=O.rendermodtypinletstatus=`Defaultinletexpansion=O.documentedSrc(O.txtSyntax.Type.annotation_separator++O.keyword"sig")@DocumentedSrc.[Subpage{content;status}]@O.documentedSrc(O.keyword"end")inDocumentedSrc.[Alternative(Expansion{status=`Default;summary;url;expansion});]in(modname,type_with_expansion)inO.documentedSrc(O.keyword"module"++O.txt" ")@O.documentedSrcmodname@mod_declandmodule_substitution(t:Odoc_model.Lang.ModuleSubstitution.t)=letname=Paths.Identifier.namet.idinletpath=Link.from_path(t.manifest:>Paths.Path.t)inletcontent=O.documentedSrc(O.keyword"module"++O.txt" "++O.txtname++O.txt" :="++O.sp++path)inletattr=["module-substitution"]inletanchor=path_to_idt.idinletdoc=Comment.to_irt.docinItem.Declaration{attr;anchor;doc;content}andmodule_type_substitution(t:Odoc_model.Lang.ModuleTypeSubstitution.t)=letprefix=O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "inletmodname=Paths.Identifier.namet.idinletmodname,expansion_doc,mty=module_type_manifest~subst:truemodnamet.idt.doc(Somet.manifest)prefixinletcontent=O.documentedSrc(prefix++modname)@mty@O.documentedSrc(ifSyntax.Mod.close_tag_semicolonthenO.txt";"elseO.noop)inletattr=["module-type"]inletanchor=path_to_idt.idinletdoc=Comment.synopsis~decl_doc:t.doc~expansion_docinItem.Declaration{attr;anchor;doc;content}andsimple_expansion:Odoc_model.Lang.ModuleType.simple_expansion->Comment.Comment.docs*Item.tlist=funt->letrecextract_functor_params(f:Odoc_model.Lang.ModuleType.simple_expansion)=matchfwith|Signaturesg->(None,sg)|Functor(p,expansion)->letadd_toparams=matchpwithUnit->params|Namedp->p::paramsinletparams,sg=extract_functor_paramsexpansioninletparams=matchparamswithNone->[]|Somep->pin(Some(add_toparams),sg)inmatchextract_functor_paramstwith|None,sg->signaturesg|Someparams,sg->letsg_doc,content=signaturesginletparams=Utils.flatmapparams~f:(funarg->letcontent=functor_parameterarginletattr=["parameter"]inletanchor=Utils.option_of_result@@Url.Anchor.from_identifier(arg.id:>Paths.Identifier.t)inletdoc=[]in[Item.Declaration{content;anchor;attr;doc}])inletprelude=Item.Heading{label=Some"parameters";level=1;title=[inline@@Text"Parameters"];}::paramsandcontent=Item.Heading{label=Some"signature";level=1;title=[inline@@Text"Signature"];}::contentin(sg_doc,prelude@content)andexpansion_of_module_type_expr:Odoc_model.Lang.ModuleType.expr->(Comment.Comment.docs*Item.tlist)option=funt->letrecsimple_expansion_of(t:Odoc_model.Lang.ModuleType.expr)=matchtwith|Path{p_expansion=None;_}|TypeOf{t_expansion=None;_}|With{w_expansion=None;_}->None|Path{p_expansion=Somee;_}|TypeOf{t_expansion=Somee;_}|With{w_expansion=Somee;_}->Somee|Signaturesg->Some(Signaturesg)|Functor(f_parameter,e)->(matchsimple_expansion_ofewith|Somee->Some(Functor(f_parameter,e))|None->None)inmatchsimple_expansion_oftwith|None->None|Somee->Some(simple_expansione)andmodule_:Odoc_model.Lang.Module.t->Item.t=funt->letmodname=Paths.Identifier.namet.idinletexpansion=matcht.type_with|Alias(_,Somee)->Some(simple_expansione)|Alias(_,None)->None|ModuleTypee->expansion_of_module_type_expreinletmodname,status,expansion,expansion_doc=matchexpansionwith|None->(O.txtmodname,`Default,None,None)|Some(expansion_doc,items)->letstatus=matcht.type_with|ModuleType(Signature_)->`Inline|_->`Defaultinleturl=Url.Path.from_identifiert.idinletlink=pathurl[inline@@Textmodname]inletpage=make_expansion_pagemodname`Modurl[t.doc;expansion_doc]itemsin(link,status,Somepage,Someexpansion_doc)inletintro=O.keyword"module"++O.txt" "++modnameinletsummary=O.ignoreintro++mdexpr_in_declt.idt.type_inletmodexpr=attach_expansion~status(Syntax.Type.annotation_separator,"sig","end")expansionsummaryinletcontent=O.documentedSrcintro@modexpr@O.documentedSrc(ifSyntax.Mod.close_tag_semicolonthenO.txt";"elseO.noop)inletattr=["module"]inletanchor=path_to_idt.idinletdoc=Comment.synopsis~decl_doc:t.doc~expansion_docinItem.Declaration{attr;anchor;doc;content}andsimple_expansion_in_decl(base:Paths.Identifier.Module.t)se=letrecty_of_se:Lang.ModuleType.simple_expansion->Lang.ModuleType.expr=function|Signaturesg->Signaturesg|Functor(arg,sg)->Functor(arg,ty_of_sesg)inmty_in_decl(base:>Paths.Identifier.Signature.t)(ty_of_sese)andmdexpr_in_decl(base:Paths.Identifier.Module.t)md=letsig_dotdotdot=O.txtSyntax.Type.annotation_separator++O.cut++Syntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_taginmatchmdwith|Alias(_,Somese)->simple_expansion_in_declbasese|Alias(p,_)whennotPaths.Path.(is_hidden(p:>t))->O.txt" ="++O.sp++mdexprmd|Alias_->sig_dotdotdot|ModuleTypemt->mty_in_decl(base:>Paths.Identifier.Signature.t)mtandmdexpr:Odoc_model.Lang.Module.decl->text=function|Alias(mod_path,_)->Link.from_path(mod_path:>Paths.Path.t)|ModuleTypemt->mtymtandmodule_type_manifest~substmodnameiddocmanifestprefix=letexpansion=matchmanifestwith|None->None|Somee->expansion_of_module_type_expreinletmodname,expansion,expansion_doc=matchexpansionwith|None->(O.txtmodname,None,None)|Some(expansion_doc,items)->leturl=Url.Path.from_identifieridinletlink=pathurl[inline@@Textmodname]inletpage=make_expansion_pagemodname`Mtyurl[doc;expansion_doc]itemsin(link,Somepage,Someexpansion_doc)inletsummary=matchmanifestwith|None->O.noop|Someexpr->O.ignore(prefix++modname)++(ifsubstthenO.txt" :="++O.spelseO.txt" ="++O.sp)++mtyexprin(modname,expansion_doc,attach_expansion(" = ","sig","end")expansionsummary)andmodule_type(t:Odoc_model.Lang.ModuleType.t)=letprefix=O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "inletmodname=Paths.Identifier.namet.idinletmodname,expansion_doc,mty=module_type_manifest~subst:falsemodnamet.idt.doct.exprprefixinletcontent=O.documentedSrc(prefix++modname)@mty@O.documentedSrc(ifSyntax.Mod.close_tag_semicolonthenO.txt";"elseO.noop)inletattr=["module-type"]inletanchor=path_to_idt.idinletdoc=Comment.synopsis~decl_doc:t.doc~expansion_docinItem.Declaration{attr;anchor;doc;content}andumty_hidden:Odoc_model.Lang.ModuleType.U.expr->bool=function|Pathp->Paths.Path.(is_hidden(p:>t))|With(_,expr)->umty_hiddenexpr|TypeOf{t_desc=ModPathm;_}|TypeOf{t_desc=StructIncludem;_}->Paths.Path.(is_hidden(m:>t))|Signature_->falseandmty_hidden:Odoc_model.Lang.ModuleType.expr->bool=function|Path{p_path=mty_path;_}->Paths.Path.(is_hidden(mty_path:>t))|With{w_expr;_}->umty_hiddenw_expr|TypeOf{t_desc=ModPathm;_}|TypeOf{t_desc=StructIncludem;_}->Paths.Path.(is_hidden(m:>t))|_->falseandmty_withsubsexpr=umtyexpr++O.sp++O.keyword"with"++O.txt" "++O.list~sep:(O.cut++O.txt" "++O.keyword"and"++O.txt" ")~f:(funx->O.span(substitutionx))subsandmty_typeoft_desc=matcht_descwith|Odoc_model.Lang.ModuleType.ModPathm->O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "++O.keyword"of"++O.txt" "++Link.from_path(m:>Paths.Path.t)|StructIncludem->O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "++O.keyword"of"++O.txt" "++O.keyword"struct"++O.txt" "++O.keyword"include"++O.txt" "++Link.from_path(m:>Paths.Path.t)++O.txt" "++O.keyword"end"andis_elidable_with_u:Odoc_model.Lang.ModuleType.U.expr->bool=function|Path_->false|Signature_->true|With(_,expr)->is_elidable_with_uexpr|TypeOf_->falseandumty:Odoc_model.Lang.ModuleType.U.expr->text=funm->matchmwith|Pathp->Link.from_path(p:>Paths.Path.t)|Signature_->Syntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_tag|With(_,expr)whenis_elidable_with_uexpr->Syntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_tag|With(subs,expr)->mty_withsubsexpr|TypeOf{t_desc;_}->mty_typeoft_descandmty:Odoc_model.Lang.ModuleType.expr->text=funm->ifmty_hiddenmthenSyntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_tagelsematchmwith|Path{p_path=mty_path;_}->Link.from_path(mty_path:>Paths.Path.t)|Functor(Unit,expr)->(ifSyntax.Mod.functor_keywordthenO.keyword"functor"elseO.noop)++O.span(O.txt" () "++Syntax.Type.arrow)++O.sp++mtyexpr|Functor(Namedarg,expr)->letarg_expr=arg.exprinletstop_before=expansion_of_module_type_exprarg_expr=Noneinletname=letopenOdoc_model.Lang.FunctorParameterinletname=Paths.Identifier.namearg.idinmatchUrl.from_identifier~stop_before(arg.id:>Paths.Identifier.t)with|Error_->O.txtname|Okhref->resolvedhref[inline@@Textname]in(ifSyntax.Mod.functor_keywordthenO.keyword"functor"elseO.noop)++(O.box_hv@@O.span@@O.txt" ("++name++O.txtSyntax.Type.annotation_separator++mtyarg_expr++O.txt")"++O.txt" "++Syntax.Type.arrow)++O.sp++mtyexpr|With{w_expr;_}whenis_elidable_with_uw_expr->Syntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_tag|With{w_substitutions;w_expr;_}->O.box_hv@@mty_withw_substitutionsw_expr|TypeOf{t_desc;_}->mty_typeoft_desc|Signature_->Syntax.Mod.open_tag++O.txt" ... "++Syntax.Mod.close_tagandmty_in_decl:Paths.Identifier.Signature.t->Odoc_model.Lang.ModuleType.expr->text=funbase->function|(Path_|Signature_|With_|TypeOf_)asm->O.txtSyntax.Type.annotation_separator++O.cut++mtym|Functor_asmwhennotSyntax.Mod.functor_contraction->O.txtSyntax.Type.annotation_separator++O.cut++mtym|Functor(arg,expr)->lettext_arg=matchargwith|Unit->O.txt"()"|Namedarg->letarg_expr=arg.exprinletstop_before=expansion_of_module_type_exprarg_expr=Noneinletname=letopenOdoc_model.Lang.FunctorParameterinletname=Paths.Identifier.namearg.idinmatchUrl.from_identifier~stop_before(arg.id:>Paths.Identifier.t)with|Error_->O.txtname|Okhref->resolvedhref[inline@@Textname]inO.box_hv@@O.txt"("++name++O.txtSyntax.Type.annotation_separator++O.cut++mtyarg.expr++O.txt")"inO.sp++text_arg++mty_in_declbaseexpr(* TODO : Centralize the list juggling for type parameters *)andtype_expr_in_substtdtypath=lettypath=Link.from_fragmenttypathinmatchtd.Lang.TypeDecl.Equation.paramswith|[]->typath|l->Syntax.Type.handle_substitution_paramstypath(format_paramsl)andsubstitution:Odoc_model.Lang.ModuleType.substitution->text=function|ModuleEq(frag_mod,md)->O.box_hv@@O.keyword"module"++O.txt" "++Link.from_fragment(frag_mod:>Paths.Fragment.leaf)++O.txt" ="++O.sp++mdexprmd|ModuleTypeEq(frag_mty,md)->O.box_hv@@O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "++Link.from_fragment(frag_mty:>Paths.Fragment.leaf)++O.txt" ="++O.sp++mtymd|TypeEq(frag_typ,td)->O.box_hv@@O.keyword"type"++O.txt" "++type_expr_in_substtd(frag_typ:>Paths.Fragment.leaf)++fst(format_manifesttd)++format_constraintstd.Odoc_model.Lang.TypeDecl.Equation.constraints|ModuleSubst(frag_mod,mod_path)->O.box_hv@@O.keyword"module"++O.txt" "++Link.from_fragment(frag_mod:>Paths.Fragment.leaf)++O.txt" :="++O.sp++Link.from_path(mod_path:>Paths.Path.t)|ModuleTypeSubst(frag_mty,md)->O.box_hv@@O.keyword"module"++O.txt" "++O.keyword"type"++O.txt" "++Link.from_fragment(frag_mty:>Paths.Fragment.leaf)++O.txt" :="++O.sp++mtymd|TypeSubst(frag_typ,td)->(O.box_hv@@O.keyword"type"++O.txt" "++type_expr_in_substtd(frag_typ:>Paths.Fragment.leaf)++O.txt" :="++O.sp++matchtd.Lang.TypeDecl.Equation.manifestwith|None->assertfalse(* cf loader/cmti *)|Somete->type_exprte)andinclude_(t:Odoc_model.Lang.Include.t)=letdecl_hidden=matcht.declwith|Aliasp->Paths.Path.(is_hidden(p:>t))|ModuleTypemty->umty_hiddenmtyinletstatus=ifdecl_hiddenthen`Inlineelset.statusinletinclude_decl=matcht.declwith|Odoc_model.Lang.Include.Aliasmod_path->Link.from_path(mod_path:>Paths.Path.t)|ModuleTypemt->umtymtinlet_,content=signaturet.expansion.contentinletsummary=O.render(O.keyword"include"++O.txt" "++include_decl++ifSyntax.Mod.include_semicolonthenO.keyword";"elseO.noop)inletcontent={Include.content;status;summary}inletattr=["include"]inletanchor=Noneinletdoc=(* Documentation attached to includes behave differently than other
declarations, which show only the synopsis. We can't only show the
synopsis because no page is generated to render it and we'd loose
the full documentation.
The documentation from the expansion is not used. *)Comment.to_irt.docinItem.Include{attr;anchor;doc;content}endopenModulemodulePage:sigvalcompilation_unit:Lang.Compilation_unit.t->Page.tvalpage:Lang.Page.t->Page.tend=structletpack:Odoc_model.Lang.Compilation_unit.Packed.t->Item.tlist=funt->letopenOdoc_model.Langinletfx=letid=x.Compilation_unit.Packed.idinletmodname=Paths.Identifier.nameidinletmd_def=O.keyword"module"++O.txt" "++O.txtmodname++O.txt" = "++Link.from_path(x.path:>Paths.Path.t)inletcontent=O.documentedSrcmd_definletanchor=Utils.option_of_result@@Url.Anchor.from_identifier(id:>Paths.Identifier.t)inletattr=["modules"]inletdoc=[]inletdecl={Item.anchor;content;attr;doc}inItem.DeclarationdeclinList.mapftletcompilation_unit(t:Odoc_model.Lang.Compilation_unit.t):Page.t=lettitle=Paths.Identifier.namet.idinleturl=Url.Path.from_identifiert.idinletunit_doc,items=matcht.contentwith|Modulesign->signaturesign|Packpacked->([],packpacked)inmake_expansion_pagetitle~header_title:title`Modurl[unit_doc]itemsletpage(t:Odoc_model.Lang.Page.t):Page.t=letname=matcht.namewith`Page(_,name)|`LeafPage(_,name)->nameinlettitle=Odoc_model.Names.PageName.to_stringnameinleturl=Url.Path.from_identifiert.nameinletheader,items=Sectioning.docst.contentin{Page.title;header;items;url}endincludePageend