123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644(*
* Copyright (c) 2014 Leo White <lpw25@cl.cam.ac.uk>
*
* 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.
*)openAsttypesopenTypedtreemoduleOCamlPath=PathopenOdoc_model.PathsopenOdoc_model.LangmoduleEnv=Ident_envtypeenv=Cmi.env={ident_env:Ident_env.t;warnings_tag:stringoption;}letread_core_typeenv ctyp=Cmi.read_type_expr envctyp.ctyp_typeletrecread_patternenvparentdocpat=letsource_loc=None inletopenSignatureinmatchpat.pat_descwith|Tpat_any->[]#ifOCAML_VERSION<(5,2,0)|Tpat_var(id,_)->#else|Tpat_var(id,_,_uid)->#endifletopenValueinletid=Env.find_value_identifierenv.ident_envidinCmi.mark_type_exprpat.pat_type;let type_=Cmi.read_type_exprenvpat.pat_typeinletvalue=Abstractin[Value{id;source_loc;doc;type_;value}]#ifOCAML_VERSION<(5,2,0)|Tpat_alias(pat,id,_)->#elifOCAML_VERSION<(5,4,0)|Tpat_alias(pat,id,_,_)->#else|Tpat_alias(pat,id,_,_,_)->#endifletopenValue inletid=Env.find_value_identifierenv.ident_envidinCmi.mark_type_exprpat.pat_type;lettype_=Cmi.read_type_expr envpat.pat_typeinlet value=Abstract inValue{id;source_loc;doc;type_;value}::read_patternenvparentdocpat|Tpat_constant_->[]|Tpat_tuplepats->#ifOCAML_VERSION>=(5,4,0)letpats=List.mapsndpats(* remove labels *)in#endifList.concat(List.map(read_patternenvparentdoc)pats)#ifOCAML_VERSION<(4,13,0)|Tpat_construct(_,_,pats)->#else|Tpat_construct(_,_,pats,_)->#endifList.concat(List.map(read_patternenvparentdoc)pats)|Tpat_variant(_,None,_)->[]|Tpat_variant(_,Somepat,_)->read_patternenvparentdocpat|Tpat_record(pats,_)->List.concat(List.map(fun(_,_,pat)->read_patternenvparentdocpat)pats)#ifOCAML_VERSION<(5,4,0)|Tpat_arraypats->#else|Tpat_array(_,pats)->#endifList.concat(List.map(read_patternenvparentdoc)pats)|Tpat_or(pat,_,_)->read_pattern envparentdocpat|Tpat_lazypat->read_pattern envparentdocpat#if OCAML_VERSION>=(4,8,0)&&OCAML_VERSION<(4,11,0)|Tpat_exceptionpat->read_patternenvparentdocpat#endifletread_value_bindingenvparentvb=let container =(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag~warnings_tag:env.warnings_tagcontainervb.vb_attributesinread_patternenvparent docvb.vb_patletread_value_bindingsenvparent vbs=letcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletitems=List.fold_left(funacc vb->letopenSignature inletcomments=Doc_attr.standalone_multiple container~warnings_tag:env.warnings_tagvb.vb_attributesinletcomments=List.map(funcom->Commentcom)commentsinletvb=read_value_bindingenvparentvbinList.rev_appendvb(List.rev_appendcommentsacc))[]vbsinList.revitemsletread_type_extensionenvparenttyext=letopen Extension inlettype_path=Env.Path.read_typeenv.ident_envtyext.tyext_pathinletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag~warnings_tag:env.warnings_tagcontainertyext.tyext_attributesinlettype_params=List.map(fun(ctyp,_)->ctyp.ctyp_type)tyext.tyext_paramsinletconstructors =List.map(funext->ext.ext_type)tyext.tyext_constructorsinlettype_params =Cmi.mark_type_extension type_paramsconstructorsinlettype_params=List.map(Cmi.read_type_parameterfalse Types.Variance.null)type_paramsinletprivate_=(tyext.tyext_private=Private)inletconstructors=List.map(funext->Cmi.read_extension_constructorenvparentext.ext_idext.ext_type)tyext.tyext_constructorsin{parent;type_path;doc;type_params;private_;constructors;}(** Make a standalone comment out of a comment attached to an item that isn't
rendered. For example, [constraint] items are read separately and not
associated with their comment. *)letmk_class_comment=function|{Odoc_model.Comment.elements=[];_}->None|doc->Some(ClassSignature.Comment(`Docsdoc))let recread_class_type_fieldenvparentctf=letopenClassSignatureinletopenOdoc_model.Names inletcontainer =(parent:Identifier.ClassSignature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag~warnings_tag:env.warnings_tagcontainerctf.ctf_attributesinmatchctf.ctf_descwith|Tctf_val(name,mutable_,virtual_,typ)->let open InstanceVariableinletid=Identifier.Mk.instance_variable(parent,InstanceVariableName.make_stdname)inletmutable_=(mutable_ =Mutable)inletvirtual_=(virtual_=Virtual)inlettype_=read_core_typeenvtypinSome(InstanceVariable{id;doc;mutable_;virtual_;type_})|Tctf_method(name,private_,virtual_,typ)->letopenMethodinletid=Identifier.Mk.method_(parent,MethodName.make_stdname)inletprivate_=(private_=Private)inletvirtual_=(virtual_ =Virtual)inlettype_=read_core_typeenvtypinSome(Method{id;doc;private_;virtual_;type_})|Tctf_constraint(_,_)->mk_class_commentdoc|Tctf_inheritcltyp->letexpr=read_class_signatureenvparent[]cltyp inSome(Inherit{Inherit.expr;doc})|Tctf_attributeattr->matchDoc_attr.standalonecontainer~warnings_tag:env.warnings_tagattrwith|None->None|Somedoc->Some(Commentdoc)andread_class_signatureenvparentparams cltyp=letopenClassTypeinmatchcltyp.cltyp_descwith|Tcty_constr(p,_,params)->letp=Env.Path.read_class_typeenv.ident_envpinletparams=List.map(read_core_typeenv)params inConstr(p,params)|Tcty_signaturecsig->let openClassSignatureinletself=Cmi.read_self_type csig.csig_self.ctyp_typeinletconstraints=Cmi.read_class_constraintsenvparamsinletitems=List.fold_left(funrestitem->match read_class_type_fieldenvparentitemwith|None ->rest|Someitem->item::rest)[]csig.csig_fieldsinletitems=constraints@List.revitemsinlet items,(doc,doc_post)=Doc_attr.extract_top_comment_classitemsinletitems=matchdoc_postwith|{elements=[];_}->items|_->Comment(`Docsdoc_post)::itemsinSignature{self;items;doc}|Tcty_arrow_->assertfalse#ifOCAML_VERSION>=(4,6,0)|Tcty_open_->assertfalse#endifletrecread_class_typeenvparentparams cty=letopenClassinmatchcty.cltyp_descwith|Tcty_constr_|Tcty_signature _->ClassType(read_class_signatureenvparentparamscty)|Tcty_arrow(lbl,arg,res)->letlbl=Cmi.read_labellblinletarg=read_core_typeenvarginletres=read_class_typeenvparentparams resinArrow(lbl,arg,res)#ifOCAML_VERSION >=(4,8,0)|Tcty_open(_,cty)->read_class_typeenvparent paramscty#elifOCAML_VERSION>=(4,6,0)|Tcty_open(_,_,_,_,cty)->read_class_type envparentparamscty#endifletrecread_class_fieldenvparentcf=letopenClassSignatureinletopenOdoc_model.Namesinletcontainer=(parent:Identifier.ClassSignature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag ~warnings_tag:env.warnings_tagcontainer(cf.cf_attributes)inmatchcf.cf_descwith|Tcf_val({txt=name;_},mutable_,_,kind,_)->letopenInstanceVariableinletid=Identifier.Mk.instance_variable(parent,InstanceVariableName.make_stdname)inletmutable_=(mutable_ =Mutable)inlet virtual_,type_=matchkindwith|Tcfk_virtualtyp->true,read_core_typeenvtyp|Tcfk_concrete(_,expr)->false,Cmi.read_type_exprenvexpr.exp_typeinSome(InstanceVariable{id;doc;mutable_;virtual_;type_})|Tcf_method({txt=name;_},private_,kind)->letopenMethodinletid=Identifier.Mk.method_(parent,MethodName.make_stdname)inletprivate_=(private_=Private)inletvirtual_,type_=matchkindwith|Tcfk_virtualtyp->true,read_core_type env typ|Tcfk_concrete(_,expr)->(* Types of concrete methods in class implementation begin
with the object as first (implicit) argument, so we must keep only the type after the first arrow. *)lettype_=match Cmi.read_type_exprenvexpr.exp_typewith|Arrow(_,_,t)->t|t->tinfalse,type_inSome(Method{id;doc;private_;virtual_;type_})|Tcf_constraint(_,_)->mk_class_commentdoc|Tcf_inherit(_,cl,_,_,_)->letexpr=read_class_structureenvparent[]clinSome(Inherit {Inherit.expr;doc})|Tcf_initializer_->mk_class_commentdoc|Tcf_attributeattr->match Doc_attr.standalonecontainer~warnings_tag:env.warnings_tagattrwith|None->None|Somedoc->Some(Comment doc)andread_class_structureenvparentparamscl=letopenClassTypeinmatchcl.cl_descwith|Tcl_ident_|Tcl_apply_->Cmi.read_class_signatureenvparentparamscl.cl_type|Tcl_structurecstr->letopenClassSignatureinlet self=Cmi.read_self_type cstr.cstr_self.pat_typeinletconstraints=Cmi.read_class_constraints env paramsinletitems =List.fold_left(funrestitem->matchread_class_fieldenvparentitemwith|None->rest|Someitem->item::rest)[]cstr.cstr_fieldsinlet items=constraints@List.revitemsinletitems,(doc,doc_post)=Doc_attr.extract_top_comment_classitemsinletitems=matchdoc_postwith|{elements=[];_}->items|_->Comment(`Docsdoc_post)::itemsinSignature{self;items;doc}|Tcl_fun_->assertfalse|Tcl_let(_,_,_,cl)->read_class_structureenvparentparamscl|Tcl_constraint(cl,None,_,_,_)->read_class_structureenvparentparamscl|Tcl_constraint(_,Somecltyp,_,_,_)->read_class_signatureenvparent paramscltyp#ifOCAML_VERSION>=(4,8,0)|Tcl_open(_,cl)->read_class_structureenvparentparamscl#elifOCAML_VERSION >=(4,6,0)|Tcl_open(_,_,_,_,cl)->read_class_structureenvparentparamscl#endifletrecread_class_exprenvparentparamscl=letopenClassinmatch cl.cl_descwith|Tcl_ident_|Tcl_apply_->Cmi.read_class_type envparentparamscl.cl_type|Tcl_structure_->ClassType(read_class_structureenvparentparamscl)|Tcl_fun(lbl,arg,_,res,_)->letlbl=Cmi.read_labellblinletarg=Cmi.read_type_exprenvarg.pat_typeinletres=read_class_exprenvparentparamsresinArrow(lbl,arg,res)|Tcl_let(_,_,_,cl)->read_class_exprenvparentparamscl|Tcl_constraint(cl,None,_,_,_)->read_class_expr envparentparamscl|Tcl_constraint(_,Some cltyp,_,_,_)->read_class_typeenvparentparamscltyp#ifOCAML_VERSION>=(4,8,0)|Tcl_open(_,cl)->read_class_exprenvparentparamscl#elifOCAML_VERSION>=(4,6,0)|Tcl_open(_,_,_,_,cl)->read_class_exprenvparentparamscl#endifletread_class_declarationenvparentcld=letopenClassinletid=Env.find_class_identifierenv.ident_envcld.ci_id_classinletsource_loc=Noneinletcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag~warnings_tag:env.warnings_tag containercld.ci_attributesinCmi.mark_class_declarationcld.ci_decl;letvirtual_ =(cld.ci_virt=Virtual)inletclparams=List.map(fun(ctyp,_)->ctyp.ctyp_type)cld.ci_paramsinletparams=List.map(Cmi.read_type_parameterfalseTypes.Variance.null)clparamsinlettype_=read_class_exprenv(id:>Identifier.ClassSignature.t)clparamscld.ci_exprin{id;source_loc;doc;virtual_;params;type_;expansion=None}letread_class_declarationsenvparentclds=letcontainer=(parent :Identifier.Signature.t:>Identifier.LabelParent.t)inletopenSignatureinList.fold_leftbeginfun(acc,recursive)cld->letcomments=Doc_attr.standalone_multiplecontainer~warnings_tag:env.warnings_tagcld.ci_attributesinletcomments=List.map(funcom->Commentcom)commentsinletcld=read_class_declarationenvparentcldin((Class(recursive,cld))::(List.rev_appendcommentsacc),And)end([],Ordinary)clds|>fst|>List.revletrecread_module_exprenvparentlabel_parentmexpr=letopenModuleTypeinletopenOdoc_model.Namesinmatch mexpr.mod_descwith|Tmod_ident_->Cmi.read_module_type envparent(Odoc_model.Compat.module_typemexpr.mod_type)|Tmod_structurestr->let sg,()=read_structureOdoc_model.Semantics.Expect_noneenvparentstrinSignaturesg#ifOCAML_VERSION>=(4,10,0)|Tmod_functor(parameter,res)->letf_parameter,env=matchparameterwith|Unit->FunctorParameter.Unit,env|Named(id_opt,_,arg)->letid,env=matchid_optwith|None->Identifier.Mk.parameter(parent,Odoc_model.Names.ModuleName.make_std"_"),env|Someid->lete'=Env.add_parameterparentid(ModuleName.of_identid)env.ident_env inEnv.find_parameter_identifier e'id,{envwithident_env=e'}inletarg=Cmti.read_module_type env(id:>Identifier.Signature.t)label_parentarginNamed{id;expr=arg},envinlet res=read_module_exprenv(Identifier.Mk.result parent)label_parent resinFunctor(f_parameter,res)#else|Tmod_functor(id,_,arg,res)->letnew_env=Env.add_parameterparent id(ModuleName.of_identid)env.ident_envinletnew_env={envwith ident_env=new_env}inletf_parameter=match argwith|None->FunctorParameter.Unit|Somearg->letid=Env.find_parameter_identifiernew_env.ident_envidinletarg=Cmti.read_module_typeenv(id:>Identifier.Signature.t)label_parent arginNamed {FunctorParameter.id;expr=arg;}inletres=read_module_expr new_env(Identifier.Mk.resultparent)label_parentresinFunctor(f_parameter,res)#endif|Tmod_apply_->Cmi.read_module_typeenvparent(Odoc_model.Compat.module_type mexpr.mod_type)#ifOCAML_VERSION>=(5,1,0)|Tmod_apply_unit_->Cmi.read_module_typeenvparent(Odoc_model.Compat.module_typemexpr.mod_type)#endif|Tmod_constraint(_,_,Tmodtype_explicitmty,_)->Cmti.read_module_typeenvparentlabel_parentmty|Tmod_constraint(mexpr,_,Tmodtype_implicit,_)->read_module_exprenvparentlabel_parentmexpr|Tmod_unpack(_,mty)->Cmi.read_module_typeenvparent(Odoc_model.Compat.module_typemty)andunwrap_module_expr_desc=function|Tmod_constraint(mexpr,_,Tmodtype_implicit,_)->unwrap_module_expr_descmexpr.mod_desc|desc->desc(** Like [read_module_expr] but handle the canonicaltag in the top-comment. *)andread_module_expr_maybe_canonicalenvparentcontainer~canonicalmexpr=letopenModuleTypeinmatch(canonical,mexpr.mod_desc)with|None,Tmod_structure str->letsg,canonical=read_structure Odoc_model.Semantics.Expect_canonical envparentstrin(Signaturesg,canonical)|_->(read_module_exprenvparentcontainermexpr,canonical)andread_module_binding envparentmb=letopenModulein#ifOCAML_VERSION>=(4,10,0)matchmb.mb_idwith|None->None|Someid->letmid=Env.find_module_identifierenv.ident_env idin#elseletmid=Env.find_module_identifierenv.ident_envmb.mb_id in#endifletid=(mid :>Identifier.Module.t)inletsource_loc=Noneinletcontainer=(parent :Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc,canonical=Doc_attr.attached~warnings_tag:env.warnings_tagOdoc_model.Semantics.Expect_canonicalcontainermb.mb_attributesinlet type_,canonical=matchunwrap_module_expr_descmb.mb_expr.mod_descwith|Tmod_ident(p,_)->(Alias(Env.Path.read_moduleenv.ident_envp,None),canonical)|_->letid=(id:>Identifier.Signature.t)inletexpr,canonical=read_module_expr_maybe_canonicalenvidcontainer~canonical mb.mb_exprin(ModuleTypeexpr,canonical)inletcanonical=matchcanonicalwith|None->None|Somes->Some(Doc_attr.conv_canonical_modules)inlet hidden=#ifOCAML_VERSION>=(4,10,0)matchcanonical,mid.iv with|None,(`Module(_,n)|`Parameter(_,n)|`Root(_,n))->Odoc_model.Names.ModuleName.is_hiddenn|Some_,_->false#elsematchcanonical,mid.ivwith|None,(`Module(_,n)|`Parameter (_,n)|`Root(_,n))->Odoc_model.Names.ModuleName.is_hiddenn|Some_,_->false#endifinSome{id;source_loc;doc;type_;canonical;hidden;}andread_module_bindingsenvparentmbs=letcontainer =(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletopenSignatureinList.fold_left(fun(acc,recursive)mb->letcomments=Doc_attr.standalone_multiplecontainer~warnings_tag:env.warnings_tag mb.mb_attributesinletcomments=List.map(funcom->Commentcom)commentsinmatchread_module_bindingenvparentmbwith|Somemb->((Module(recursive,mb))::(List.rev_appendcommentsacc),And)|None->(acc,recursive))([],Rec)mbs|>fst|>List.revandread_structure_itemenvparentitem=letopenSignatureinmatchitem.str_descwith|Tstr_eval_->[]|Tstr_value(_,vbs)->read_value_bindingsenvparentvbs|Tstr_primitivevd->[Cmti.read_value_descriptionenvparentvd]#ifOCAML_VERSION<(4,3,0)|Tstr_type(decls)->let rec_flag=Ordinaryin#else|Tstr_type(rec_flag,decls)->letrec_flag =match rec_flagwith|Recursive->Ordinary|Nonrecursive->Nonrecin#endifCmti.read_type_declarationsenvparentrec_flagdecls|Tstr_typexttyext ->[TypExt (read_type_extensionenvparenttyext)]|Tstr_exceptionext->letext=#ifOCAML_VERSION>=(4,8,0)Cmi.read_exceptionenvparentext.tyexn_constructor.ext_idext.tyexn_constructor.ext_type#elseCmi.read_exceptionenvparentext.ext_idext.ext_type#endifin[Exceptionext]|Tstr_modulemb->beginmatch read_module_bindingenvparentmbwith|Somemb->[Module(Ordinary,mb)]|None->[]end|Tstr_recmodulembs->read_module_bindings envparentmbs|Tstr_modtypemtd->[ModuleType(Cmti.read_module_type_declarationenvparentmtd)]|Tstr_open o->[Open(read_openenvparent o)]|Tstr_include incl->read_includeenvparentincl|Tstr_classcls->letcls=List.map#ifOCAML_VERSION<(4,3,0)(* NOTE(@ostera): remember the virtual flag was removed post 4.02 *)(fun(cl,_,_)->cl)#else(fun(cl,_)->cl)#endifclsinread_class_declarationsenvparentcls|Tstr_class_typecltyps->letcltyps=List.map(fun(_,_,clty)->clty)cltypsinCmti.read_class_type_declarationsenvparentcltyps|Tstr_attributeattr->letcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inmatchDoc_attr.standalonecontainer ~warnings_tag:env.warnings_tagattr with|None ->[]|Somedoc->[Commentdoc]andread_includeenvparentincl=letopenInclude inletloc=Doc_attr.read_locationincl.incl_locinletcontainer =(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc,status=Doc_attr.attached~warnings_tag:env.warnings_tagOdoc_model.Semantics.Expect_statuscontainerincl.incl_attributesinletdecl_modty=matchunwrap_module_expr_descincl.incl_mod.mod_descwith|Tmod_ident(p,_)->letp=Env.Path.read_moduleenv.ident_envpinSome(ModuleType.U.TypeOf(ModuleType.StructInclude p,p))|_->letmty=read_module_expr envparent containerincl.incl_modinumty_of_mtymtyinletcontent,shadowed=Cmi.read_signature_noenvenvparent(Odoc_model.Compat.signatureincl.incl_type)inletexpansion={content;shadowed;}inmatchdecl_modtywith|Somem->letdecl=ModuleTypemin[Include{parent;doc;decl;expansion;status;strengthened=None;loc}]|_->content.itemsand read_open envparento=letcontainer=(parent:Identifier.Signature.t:>Identifier.LabelParent.t)inletdoc=Doc_attr.attached_no_tag~warnings_tag:env.warnings_tagcontainero.open_attributesin#ifOCAML_VERSION >=(4,8,0)letsignature=o.open_bound_itemsin#elseletsignature=[]in#endifletexpansion,_=Cmi.read_signature_noenv envparent(Odoc_model.Compat.signaturesignature)inOpen.{expansion;doc}andread_structure:'tags.'tagsOdoc_model.Semantics.handle_internal_tags->_->_->_->_*'tags=funinternal_tagsenvparentstr->lete'=Env.add_structure_tree_itemsparentstrenv.ident_envinletenv={envwithident_env=e'}inletitems,(doc,doc_post),tags=letclassifyitem=matchitem.str_descwith|Tstr_open_->Some`Open|Tstr_attributeattr->Some(`Attributeattr)|_->NoneinDoc_attr.extract_top_commentinternal_tags~warnings_tag:env.warnings_tag~classifyparentstr.str_itemsinletitems=List.fold_left(funitemsitem->List.rev_append(read_structure_itemenvparentitem)items)[]items|>List.revinmatchdoc_postwith|{elements=[];_}->({Signature.items;compiled=false;removed=[];doc},tags)|_->({Signature.items=Comment(`Docsdoc_post)::items;compiled=false;removed=[];doc},tags)letread_implementationrootname~warnings_tagimpl=letid=Identifier.Mk.root(root,Odoc_model.Names.ModuleName.make_stdname)inletsg,canonical=read_structureOdoc_model.Semantics.Expect_canonical{ident_env=Env.empty();warnings_tag}idimplinletcanonical=matchcanonicalwith|None->None|Somes->Some(Doc_attr.conv_canonical_modules)in(id,sg,canonical)let_=Cmti.read_module_expr:=read_module_expr