1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288(*$ open Ppxlib_cinaps_helpers $*)open!ImportopenCommonopenWith_errorsmoduleE=ExtensionmoduleEC=Extension.ContextmoduleA=AttributemoduleAC=Attribute.ContextmoduleRule=structmoduleAttr_replace=structmoduleAttribute_list=structtype('a,_)t=|[]:('a,unit)t|(::):('a,'b)Attribute.t*('a,'c)t->('a,'b*'c)tletrecto_packed_list:typeal.(a,l)t->Attribute.packedlist=function|[]->[]|x::xs->Tx::to_packed_listxsendmoduleParsed_payload_list=structtype_t=[]:unitt|(::):'aoption*'bt->('a*'b)tendtype('a,'list)unpacked={name:string;attributes:('a,'list)Attribute_list.t;expand:ctxt:Expansion_context.Base.t->'a->'listParsed_payload_list.t->'a;}type'at=T:('a,_)unpacked->'atletname(Tt)=t.nameendmoduleAttr_group_inline=structtype('a,'b,'c)unpacked={attribute:('b,'c)Attribute.t;expect:bool;expand:ctxt:Expansion_context.Deriver.t->Asttypes.rec_flag->'blist->'coptionlist->'alist;}type('a,'b)t=T:('a,'b,_)unpacked->('a,'b)tletattr_name(Tt)=Attribute.namet.attributeletsplit_normal_and_expectl=List.partitionl~f:(fun(Tt)->nott.expect)endmoduleAttr_inline=structtype('a,'b,'c)unpacked={attribute:('b,'c)Attribute.t;expect:bool;expand:ctxt:Expansion_context.Deriver.t->'b->'c->'alist;}type('a,'b)t=T:('a,'b,_)unpacked->('a,'b)tletattr_name(Tt)=Attribute.namet.attributeletsplit_normal_and_expectl=List.partitionl~f:(fun(Tt)->nott.expect)endmoduleAttr_floating_inline=structtype('a,'b)unpacked={attribute:('a,'b)Attribute.Floating.t;expand:ctxt:Expansion_context.Deriver.t->'b->'alist;}type'at=T:('a,_)unpacked->'atletattr_name(Tt)=Attribute.Floating.namet.attributeendmoduleSpecial_function=structtypet={name:string;ident:Longident.t;expand:Parsetree.expression->Parsetree.expressionoption;}endmoduleConstant_kind=structtypet=Float|IntegerendmoduleConstant=structtypet={suffix:char;kind:Constant_kind.t;expand:Location.t->string->Parsetree.expression;}endmoduleField=structtype'at=|Extension:Extension.tt|Special_function:Special_function.tt|Constant:Constant.tt|Attr_replace:'aEC.t->'aAttr_replace.tt|Attr_str_type_decl:(structure_item,type_declaration)Attr_group_inline.tt|Attr_sig_type_decl:(signature_item,type_declaration)Attr_group_inline.tt|Attr_str_module_type_decl:(structure_item,module_type_declaration)Attr_inline.tt|Attr_sig_module_type_decl:(signature_item,module_type_declaration)Attr_inline.tt|Attr_str_module_binding:(structure_item,module_binding)Attr_inline.tt|Attr_sig_module_declaration:(signature_item,module_declaration)Attr_inline.tt|Attr_str_type_ext:(structure_item,type_extension)Attr_inline.tt|Attr_sig_type_ext:(signature_item,type_extension)Attr_inline.tt|Attr_str_exception:(structure_item,type_exception)Attr_inline.tt|Attr_sig_exception:(signature_item,type_exception)Attr_inline.tt|Attr_str_class_type_decl:(structure_item,class_type_declaration)Attr_group_inline.tt|Attr_sig_class_type_decl:(signature_item,class_type_declaration)Attr_group_inline.tt|Attr_str_floating:structure_itemAttr_floating_inline.tt|Attr_sig_floating:signature_itemAttr_floating_inline.tttype(_,_)equality=Eq:('a,'a)equality|Ne:(_,_)equalityleteq:typeab.at->bt->(a,b)equality=funab->match(a,b)with|Extension,Extension->Eq|Special_function,Special_function->Eq|Constant,Constant->Eq|Attr_replacea,Attr_replaceb->(matchEC.eqabwithEq->Eq|Ne->Ne)|Attr_str_type_decl,Attr_str_type_decl->Eq|Attr_sig_type_decl,Attr_sig_type_decl->Eq|Attr_str_type_ext,Attr_str_type_ext->Eq|Attr_sig_type_ext,Attr_sig_type_ext->Eq|Attr_str_exception,Attr_str_exception->Eq|Attr_sig_exception,Attr_sig_exception->Eq|Attr_str_module_type_decl,Attr_str_module_type_decl->Eq|Attr_str_module_binding,Attr_str_module_binding->Eq|Attr_sig_module_declaration,Attr_sig_module_declaration->Eq|Attr_sig_module_type_decl,Attr_sig_module_type_decl->Eq|Attr_str_class_type_decl,Attr_str_class_type_decl->Eq|Attr_sig_class_type_decl,Attr_sig_class_type_decl->Eq|Attr_str_floating,Attr_str_floating->Eq|Attr_sig_floating,Attr_sig_floating->Eq|_->Neendtypet=T:'aField.t*'a->ttype('a,'b,'c)attr_group_inline=('b,'c)Attribute.t->(ctxt:Expansion_context.Deriver.t->Asttypes.rec_flag->'blist->'coptionlist->'alist)->ttype('a,'b,'c)attr_inline=('b,'c)Attribute.t->(ctxt:Expansion_context.Deriver.t->'b->'c->'alist)->ttype('item,'parsed_payload)attr_floating_inline=('item,'parsed_payload)Attribute.Floating.t->(ctxt:Expansion_context.Deriver.t->'parsed_payload->'itemlist)->tletrecfilter:typea.aField.t->tlist->alist=funfieldl->matchlwith|[]->[]|T(field',x)::l->(matchField.eqfieldfield'with|Field.Eq->x::filterfieldl|Field.Ne->filterfieldl)letextensionext=T(Extension,ext)letspecial_functionidf=T(Special_function,{name=id;ident=Longident.parseid;expand=f})letspecial_function'identf=T(Special_function,{name=Longident.nameident;ident;expand=f})letconstantkindsuffixexpand=T(Constant,{suffix;kind;expand})letattr_replacenamekindattributeexpand=T(Attr_replacekind,T{name;attributes=[attribute];expand=(fun~ctxtitempayload->matchpayloadwith|[None]->assertfalse|[Somepayload]->expand~ctxtitempayload);})moduleAttr_multiple_replace=structmoduleAttribute_list=Attr_replace.Attribute_listmoduleParsed_payload_list=Attr_replace.Parsed_payload_listletattr_multiple_replacenamekindattributesexpand=T(Attr_replacekind,T{name;attributes;expand})endletattr_str_type_declattributeexpand=T(Attr_str_type_decl,T{attribute;expand;expect=false})letattr_sig_type_declattributeexpand=T(Attr_sig_type_decl,T{attribute;expand;expect=false})letattr_str_module_type_declattributeexpand=T(Attr_str_module_type_decl,T{attribute;expand;expect=false})letattr_sig_module_type_declattributeexpand=T(Attr_sig_module_type_decl,T{attribute;expand;expect=false})letattr_str_module_bindingattributeexpand=T(Attr_str_module_binding,T{attribute;expand;expect=false})letattr_sig_module_declarationattributeexpand=T(Attr_sig_module_declaration,T{attribute;expand;expect=false})letattr_str_type_extattributeexpand=T(Attr_str_type_ext,T{attribute;expand;expect=false})letattr_sig_type_extattributeexpand=T(Attr_sig_type_ext,T{attribute;expand;expect=false})letattr_str_exceptionattributeexpand=T(Attr_str_exception,T{attribute;expand;expect=false})letattr_sig_exceptionattributeexpand=T(Attr_sig_exception,T{attribute;expand;expect=false})letattr_str_class_type_declattributeexpand=T(Attr_str_class_type_decl,T{attribute;expand;expect=false})letattr_sig_class_type_declattributeexpand=T(Attr_sig_class_type_decl,T{attribute;expand;expect=false})letattr_str_type_decl_expectattributeexpand=T(Attr_str_type_decl,T{attribute;expand;expect=true})letattr_sig_type_decl_expectattributeexpand=T(Attr_sig_type_decl,T{attribute;expand;expect=true})letattr_str_module_type_decl_expectattributeexpand=T(Attr_str_module_type_decl,T{attribute;expand;expect=true})letattr_str_module_binding_expectattributeexpand=T(Attr_str_module_binding,T{attribute;expand;expect=true})letattr_sig_module_declaration_expectattributeexpand=T(Attr_sig_module_declaration,T{attribute;expand;expect=true})letattr_sig_module_type_decl_expectattributeexpand=T(Attr_sig_module_type_decl,T{attribute;expand;expect=true})letattr_str_type_ext_expectattributeexpand=T(Attr_str_type_ext,T{attribute;expand;expect=true})letattr_sig_type_ext_expectattributeexpand=T(Attr_sig_type_ext,T{attribute;expand;expect=true})letattr_str_exception_expectattributeexpand=T(Attr_str_exception,T{attribute;expand;expect=true})letattr_sig_exception_expectattributeexpand=T(Attr_sig_exception,T{attribute;expand;expect=true})letattr_str_class_type_decl_expectattributeexpand=T(Attr_str_class_type_decl,T{attribute;expand;expect=true})letattr_sig_class_type_decl_expectattributeexpand=T(Attr_sig_class_type_decl,T{attribute;expand;expect=true})letattr_str_floating_expect_and_expandattributeexpand=T(Attr_str_floating,T{attribute;expand})letattr_sig_floating_expect_and_expandattributeexpand=T(Attr_sig_floating,T{attribute;expand})endmoduleGenerated_code_hook=structtype'asingle_or_many=Singleof'a|Manyof'alisttypet={f:'a.'aExtension.Context.t->Location.t->'asingle_or_many->unit;}letnop={f=(fun___->())}letreplacetcontextlocx=t.fcontextlocxletinsert_aftertcontext(loc:Location.t)x=matchxwith|Many[]->()|_->t.fcontext{locwithloc_start=loc.loc_end}xend(* Used to insert error extensions *)letwrap_extension:typea.loc:Location.t->aEC.t->a->extension->a=fun~loctoriginal_nodeextension->(* Prefixing constructors with the module path is necessary for OCaml < 4.07,
see https://github.com/ocaml/ocaml/issues/6852 *)matchtwith|EC.Class_expr->Ast_builder.Default.pcl_extension~locextension|EC.Class_field->Ast_builder.Default.pcf_extension~locextension|EC.Class_type->Ast_builder.Default.pcty_extension~locextension|EC.Class_type_field->Ast_builder.Default.pctf_extension~locextension|EC.Core_type->Ast_builder.Default.ptyp_extension~locextension|EC.Expression->Ast_builder.Default.pexp_extension~locextension|EC.Module_expr->Ast_builder.Default.pmod_extension~locextension|EC.Module_type->Ast_builder.Default.pmty_extension~locextension|EC.Pattern->Ast_builder.Default.ppat_extension~locextension|EC.Signature_item->Ast_builder.Default.psig_extension~locextension[]|EC.Structure_item->Ast_builder.Default.pstr_extension~locextension[]|EC.Ppx_import->(* Insert the error in the type decl manifest *)letptype_manifest=Some(Ast_builder.Default.ptyp_extension~locextension)in{original_nodewithptype_manifest}letexn_to_extensionexn=leterror=exn_to_loc_errorexninletloc=Location.Error.get_locationerrorinletextension=Location.Error.to_extensionerrorin(extension,loc)letexn_to_error_extensioncontextoriginal_nodeexn=letextension,loc=exn_to_extensionexninwrap_extension~loccontextoriginal_nodeextensionletexn_to_striexn=letextension,loc=exn_to_extensionexninAst_builder.Default.pstr_extension~locextension[]letexn_to_sigiexn=letextension,loc=exn_to_extensionexninAst_builder.Default.psig_extension~locextension[]lethandle_attr_replace_oncecontextattrsitembase_ctxt:'aoptiont=letresult=List.find_mapattrs~f:(fun(Rule.Attr_replace.Ta)->letrecget_attr_payloads:typel.('a,l)Rule.Attr_replace.Attribute_list.t->(bool*lRule.Attr_replace.Parsed_payload_list.t)t=function|[]->return(false,Rule.Attr_replace.Parsed_payload_list.[])|x::xs->(ifAttribute.Context.equalcontext(Attribute.contextx)thenAttribute.get_resxitem|>of_result~default:NoneelsereturnNone)>>=funp->get_attr_payloadsxs>>|fun(any_attrs,ps)->(Option.is_somep||any_attrs,Rule.Attr_replace.Parsed_payload_list.(p::ps))inlet(any_attrs,payloads),errors=get_attr_payloadsa.attributesinifany_attrsthenSome((payloads,errors)>>=funpayloads->Attribute.remove_seen_rescontext(Rule.Attr_replace.Attribute_list.to_packed_lista.attributes)item|>of_result~default:item>>|funitem->a.expand~ctxt:base_ctxtitempayloads)elseNone)inmatchresultwith|Some(item,errors)->(Someitem,errors)|None->(None,[])letrechandle_attr_replace_strattrsitembase_ctxt=(matchitem.pstr_descwith|Pstr_extension_->handle_attr_replace_onceAC.Pstr_extensionattrsitembase_ctxt|Pstr_eval_->handle_attr_replace_onceAC.Pstr_evalattrsitembase_ctxt|_->returnNone)>>=function|Someitem->handle_attr_replace_strattrsitembase_ctxt|None->returnitemletrechandle_attr_replace_sigattrsitembase_ctxt=(matchitem.psig_descwith|Psig_extension_->handle_attr_replace_onceAC.Psig_extensionattrsitembase_ctxt|_->returnNone)>>=function|Someitem->handle_attr_replace_sigattrsitembase_ctxt|None->returnitemletrecmap_node_recattr_contextattr_rulesext_contexttssuper_calllocbase_ctxtx~embed_errors=letctxt=Expansion_context.Extension.make~extension_point_loc:loc~base:base_ctxt()inhandle_attr_replace_onceattr_contextattr_rulesxbase_ctxt>>=function|Somex->map_node_recattr_contextattr_rulesext_contexttssuper_calllocbase_ctxtx~embed_errors|None->(matchEC.get_extensionext_contextxwith|None->super_callbase_ctxtx|Some(ext,attrs)->((tryE.For_context.convert_rests~ctxtext|>With_errors.of_result~default:Nonewithexnwhenembed_errors->With_errors.return(Some(exn_to_error_extensionext_contextxexn)))>>=funconverted->matchconvertedwith|None->super_callbase_ctxtx|Somex->EC.merge_attributes_resext_contextxattrs|>With_errors.of_result~default:x>>=funx->map_node_recattr_contextattr_rulesext_contexttssuper_calllocbase_ctxtx~embed_errors))letmap_context:typea.aEC.t->aAC.t=function|EC.Class_expr->AC.Class_expr|EC.Class_field->AC.Class_field|EC.Class_type->AC.Class_type|EC.Class_type_field->AC.Class_type_field|EC.Core_type->AC.Core_type|EC.Expression->AC.Expression|EC.Module_expr->AC.Module_expr|EC.Module_type->AC.Module_type|EC.Pattern->AC.Pattern|EC.Signature_item|EC.Structure_item->assertfalse(* These can't happen because all the items get handled together in structure and
signature processing *)|EC.Ppx_import->AC.Type_declarationletmap_nodeattr_rulesext_contexttssuper_calllocbase_ctxtx~hook~embed_errors=letattr_context=map_contextext_contextinletctxt=Expansion_context.Extension.make~extension_point_loc:loc~base:base_ctxt()inhandle_attr_replace_onceattr_contextattr_rulesxbase_ctxt>>=function|Somex->map_node_recattr_contextattr_rulesext_contexttssuper_calllocbase_ctxtx~embed_errors|None->(matchEC.get_extensionext_contextxwith|None->super_callbase_ctxtx|Some(ext,attrs)->((tryE.For_context.convert_rests~ctxtext|>With_errors.of_result~default:Nonewithexnwhenembed_errors->With_errors.return(Some(exn_to_error_extensionext_contextxexn)))>>=funconverted->matchconvertedwith|None->super_callbase_ctxtx|Somex->map_node_recattr_contextattr_rulesext_contexttssuper_calllocbase_ctxt(EC.merge_attributesext_contextxattrs)~embed_errors>>|fungenerated_code->Generated_code_hook.replacehookext_contextloc(Singlegenerated_code);generated_code))letrecmap_nodesattr_rulesext_contexttssuper_callget_locbase_ctxtl~hook~embed_errors~in_generated_code=letattr_context=map_contextext_contextinmatchlwith|[]->return[]|x::l->(handle_attr_replace_onceattr_contextattr_rulesxbase_ctxt>>=function|Somex->map_nodesattr_rulesext_contexttssuper_callget_locbase_ctxt(x::l)~hook~embed_errors~in_generated_code|None->(matchEC.get_extensionext_contextxwith|None->(* These two lets force the evaluation order, so that errors are reported in
the same order as they appear in the source file. *)super_callbase_ctxtx>>=funx->map_nodesattr_rulesext_contexttssuper_callget_locbase_ctxtl~hook~embed_errors~in_generated_code>>|funl->x::l|Some(ext,attrs)->(letextension_point_loc=get_locxinletctxt=Expansion_context.Extension.make~extension_point_loc~base:base_ctxt()in(tryE.For_context.convert_inline_rests~ctxtext|>With_errors.of_result~default:Nonewithexnwhenembed_errors->With_errors.return(Some[exn_to_error_extensionext_contextxexn]))>>=function|None->super_callbase_ctxtx>>=funx->map_nodesattr_rulesext_contexttssuper_callget_locbase_ctxtl~hook~embed_errors~in_generated_code>>|funl->x::l|Someconverted->((),attributes_errorsattrs)>>=fun()->map_nodesattr_rulesext_contexttssuper_callget_locbase_ctxtconverted~hook~embed_errors~in_generated_code:true>>=fungenerated_code->ifnotin_generated_codethenGenerated_code_hook.replacehookext_contextextension_point_loc(Manygenerated_code);map_nodesattr_rulesext_contexttssuper_callget_locbase_ctxtl~hook~embed_errors~in_generated_code>>|funcode->generated_code@code)))letmap_nodes=map_nodes~in_generated_code:falselettable_of_special_functionsspecial_functions=matchList.mapspecial_functions~f:(fun{Rule.Special_function.ident;expand;_}->(ident,expand))(* We expect the lookup to fail most of the time, by making the table big (and
sparse), we make it more likely to fail quickly *)|>Hashtbl.of_alist~size:(max1024(List.lengthspecial_functions*2))with|Oktable->table|Errorident->Printf.ksprintfinvalid_arg"Context_free.V1.map_top_down: %s present twice in list of special \
functions"(List.find_map_exnspecial_functions~f:(funr->ifPoly.equalr.identidentthenSomer.nameelseNone))(* [get_group attr l] returns the list of the attributes for each
node in [l].
If [l] is empty or if none of the nodes in [l] have an attribute attached,
[get_group] returns [None].
If [l] is not empty and at least one of the nodes in [l] has an attribue
attached, [get_group] returns the equivalent of
[Some (List.map ~f:(Attribute.get attr) l)]. *)letrecget_groupattrl=matchlwith|[]->returnNone|x::l->(get_groupattrl>>=fungroup->Attribute.get_resattrx|>of_result~default:None>>|funattr2->match(attr2,group)with|None,None->None|None,Somevals->Some(None::vals)|Somevalue,None->Some(Somevalue::List.mapl~f:(fun_->None))|Somevalue,Somevals->Some(Somevalue::vals))(* Same as [List.rev] then [List.concat] but expecting the input to be of length <= 2 *)letrev_concat=function|[]->[]|[x]->x|[x;y]->y@x|l->List.concat(List.revl)letsort_attr_replacel=List.sortl~cmp:(funab->String.compare(Rule.Attr_replace.namea)(Rule.Attr_replace.nameb))letsort_attr_group_inlinel=List.sortl~cmp:(funab->String.compare(Rule.Attr_group_inline.attr_namea)(Rule.Attr_group_inline.attr_nameb))letsort_attr_inlinel=List.sortl~cmp:(funab->String.compare(Rule.Attr_inline.attr_namea)(Rule.Attr_inline.attr_nameb))letsort_attr_floating_inlinel=List.sortl~cmp:(funab->String.compare(Rule.Attr_floating_inline.attr_namea)(Rule.Attr_floating_inline.attr_nameb))letcontext_free_attribute_modification~loc=Error(Location.Error.createf~loc"A context-free rule deleted or added attribues of a str/sig item",[])(* Returns the code generated by attribute handlers. We don't remove these attributes, as
another pass might interpret them later. For instance both ppx_deriving and
ppxlib_deriving interprets [@@deriving] attributes.
This complexity is horrible, but in practice we don't care as [attrs] is always a list
of one element; it only has [@@deriving].
*)lethandle_attr_group_inlineattrsrf~items~expanded_items~loc~base_ctxt~embed_errors~convert_exn=List.fold_leftattrs~init:(return[])~f:(funacc(Rule.Attr_group_inline.Tgroup)->acc>>=funacc->get_groupgroup.attributeitems>>=fung1->get_groupgroup.attributeexpanded_items>>=fung2->match(g1,g2)with|None,None->returnacc|None,Some_|Some_,None->context_free_attribute_modification~loc|>of_result~default:acc|Somevalues,Some_->(letctxt=Expansion_context.Deriver.make~derived_item_loc:loc~inline:group.expect~base:base_ctxt()intryletexpect_items=group.expand~ctxtrfexpanded_itemsvaluesinreturn(expect_items::acc)withexnwhenembed_errors->leterror_item=[convert_exnexn]inreturn(error_item::acc)))lethandle_attr_inlineattrs~convert_exn~item~expanded_item~loc~base_ctxt~embed_errors=List.fold_leftattrs~init:(return[])~f:(funacc(Rule.Attr_inline.Ta)->acc>>=funacc->Attribute.get_resa.attributeitem|>of_result~default:None>>=fung1->Attribute.get_resa.attributeexpanded_item|>of_result~default:None>>=fung2->match(g1,g2)with|None,None->returnacc|None,Some_|Some_,None->context_free_attribute_modification~loc|>of_result~default:acc|Somevalue,Some_->(letctxt=Expansion_context.Deriver.make~derived_item_loc:loc~inline:a.expect~base:base_ctxt()intryletexpect_items=a.expand~ctxtexpanded_itemvalueinreturn(expect_items::acc)withexnwhenembed_errors->leterror_item=[convert_exnexn]inreturn(error_item::acc)))lethandle_attr_floating_inlineattrs~item~loc~base_ctxt~embed_errors~convert_exn=List.fold_leftattrs~init:(return[])~f:(funacc(Rule.Attr_floating_inline.Ta)->acc>>=funacc->Attribute.Floating.convert_attr_resa.attributeitem|>of_result~default:None>>=function|None->returnacc|Somevalue->(letctxt=Expansion_context.Deriver.make~derived_item_loc:loc~inline:true~base:base_ctxt()intryletexpect_items=a.expand~ctxtvalueinreturn(expect_items::acc)withexnwhenembed_errors->leterror_item=[convert_exnexn]inreturn(error_item::acc)))moduleExpect_mismatch_handler=structtypet={f:'a.'aAttribute.Floating.Context.t->Location.t->'alist->unit;}letnop={f=(fun___->())}end(** Apply any code-path attributes to the context. *)letwith_contextbase_ctxte=Attribute.get_resAst_traverse.enter_valuee|>of_result~default:None>>=funoption->matchoptionwith|None->return(base_ctxt,e)|Some{loc;txt}->Attribute.remove_seen_resExpression[TAst_traverse.enter_value]e|>of_result~default:e>>|fune->(Expansion_context.Base.enter_value~loctxtbase_ctxt,e)classmap_top_down?(expect_mismatch_handler=Expect_mismatch_handler.nop)?(generated_code_hook=Generated_code_hook.nop)?(embed_errors=false)rules=lethook=generated_code_hookinletspecial_functions=Rule.filterSpecial_functionrules|>table_of_special_functionsinletconstants=Rule.filterConstantrules|>List.map~f:(fun(c:Rule.Constant.t)->((c.suffix,c.kind),c.expand))|>Hashtbl.of_alist_exninletextensions=Rule.filterExtensionrulesinletclass_expr=E.filter_by_contextEC.class_exprextensionsandclass_field=E.filter_by_contextEC.class_fieldextensionsandclass_type=E.filter_by_contextEC.class_typeextensionsandclass_type_field=E.filter_by_contextEC.class_type_fieldextensionsandcore_type=E.filter_by_contextEC.core_typeextensionsandexpression=E.filter_by_contextEC.expressionextensionsandmodule_expr=E.filter_by_contextEC.module_exprextensionsandmodule_type=E.filter_by_contextEC.module_typeextensionsandpattern=E.filter_by_contextEC.patternextensionsandsignature_item=E.filter_by_contextEC.signature_itemextensionsandstructure_item=E.filter_by_contextEC.structure_itemextensionsandppx_import=E.filter_by_contextEC.Ppx_importextensionsinletattr_replace_class_expr=Rule.filter(Attr_replaceEC.class_expr)rules|>sort_attr_replaceandattr_replace_class_field=Rule.filter(Attr_replaceEC.class_field)rules|>sort_attr_replaceandattr_replace_class_type=Rule.filter(Attr_replaceEC.class_type)rules|>sort_attr_replaceandattr_replace_class_type_field=Rule.filter(Attr_replaceEC.class_type_field)rules|>sort_attr_replaceandattr_replace_core_type=Rule.filter(Attr_replaceEC.core_type)rules|>sort_attr_replaceandattr_replace_expression=Rule.filter(Attr_replaceEC.expression)rules|>sort_attr_replaceandattr_replace_module_expr=Rule.filter(Attr_replaceEC.module_expr)rules|>sort_attr_replaceandattr_replace_module_type=Rule.filter(Attr_replaceEC.module_type)rules|>sort_attr_replaceandattr_replace_pattern=Rule.filter(Attr_replaceEC.pattern)rules|>sort_attr_replaceandattr_replace_signature_item=Rule.filter(Attr_replaceEC.signature_item)rules|>sort_attr_replaceandattr_replace_structure_item=Rule.filter(Attr_replaceEC.structure_item)rules|>sort_attr_replace(* Intentionally ignoring [EC.Ppx_import] *)inletattr_str_type_decls,attr_str_type_decls_expect=Rule.filterAttr_str_type_declrules|>sort_attr_group_inline|>Rule.Attr_group_inline.split_normal_and_expectinletattr_sig_type_decls,attr_sig_type_decls_expect=Rule.filterAttr_sig_type_declrules|>sort_attr_group_inline|>Rule.Attr_group_inline.split_normal_and_expectinletattr_str_module_type_decls,attr_str_module_type_decls_expect=Rule.filterAttr_str_module_type_declrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_sig_module_type_decls,attr_sig_module_type_decls_expect=Rule.filterAttr_sig_module_type_declrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_str_module_binding,attr_str_module_binding_expect=Rule.filterAttr_str_module_bindingrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_sig_module_declaration,attr_sig_module_declaration_expect=Rule.filterAttr_sig_module_declarationrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_str_type_exts,attr_str_type_exts_expect=Rule.filterAttr_str_type_extrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_sig_type_exts,attr_sig_type_exts_expect=Rule.filterAttr_sig_type_extrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_str_exceptions,attr_str_exceptions_expect=Rule.filterAttr_str_exceptionrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_sig_exceptions,attr_sig_exceptions_expect=Rule.filterAttr_sig_exceptionrules|>sort_attr_inline|>Rule.Attr_inline.split_normal_and_expectinletattr_str_class_decls,attr_str_class_decls_expect=Rule.filterAttr_str_class_type_declrules|>sort_attr_group_inline|>Rule.Attr_group_inline.split_normal_and_expectinletattr_sig_class_decls,attr_sig_class_decls_expect=Rule.filterAttr_sig_class_type_declrules|>sort_attr_group_inline|>Rule.Attr_group_inline.split_normal_and_expectinletattr_str_floating_expect_and_expand=Rule.filterAttr_str_floatingrules|>sort_attr_floating_inlineinletattr_sig_floating_expect_and_expand=Rule.filterAttr_sig_floatingrules|>sort_attr_floating_inlineinletmap_node=map_node~hook~embed_errorsinletmap_nodes=map_nodes~hook~embed_errorsinlethandle_attr_group_inline=handle_attr_group_inline~embed_errorsinlethandle_attr_inline=handle_attr_inline~embed_errorsinlethandle_attr_floating_inline=handle_attr_floating_inline~embed_errorsinobject(self)inheritAst_traverse.map_with_expansion_context_and_errorsassuper(* No point recursing into every location *)method!location_x=returnxmethod!core_typebase_ctxtx=map_nodeattr_replace_core_typeEC.core_typecore_typesuper#core_typex.ptyp_locbase_ctxtxmethod!patternbase_ctxtx=map_nodeattr_replace_patternEC.patternpatternsuper#patternx.ppat_locbase_ctxtxmethod!expressionbase_ctxte=with_contextbase_ctxte>>=fun(base_ctxt,e)->letexpanded=map_nodeattr_replace_expressionEC.expressionexpression(fun_e->returne)e.pexp_locbase_ctxteinexpanded>>=fune->letexpand_constantkindchartext=matchHashtbl.find_optconstants(char,kind)with|None->super#expressionbase_ctxte|Someexpand->self#expressionbase_ctxt(expande.pexp_loctext)inmatche.pexp_descwith|Pexp_apply(({pexp_desc=Pexp_identid;_}asfunc),args)->(matchHashtbl.find_optspecial_functionsid.txtwith|None->self#pexp_apply_without_traversing_functionbase_ctxtefuncargs|Somepattern->(letgenerated_code=tryreturn(patterne)withexnwhenembed_errors->return(Some(exn_to_error_extensionEC.expressioneexn))ingenerated_code>>=funexpr->matchexprwith|None->self#pexp_apply_without_traversing_functionbase_ctxtefuncargs|Somee->self#expressionbase_ctxte))|Pexp_identid->(matchHashtbl.find_optspecial_functionsid.txtwith|None->super#expressionbase_ctxte|Somepattern->(letgenerated_code=tryreturn(patterne)withexnwhenembed_errors->return(Some(exn_to_error_extensionEC.expressioneexn))ingenerated_code>>=funexpr->matchexprwith|None->super#expressionbase_ctxte|Somee->self#expressionbase_ctxte))|Pexp_constant(Pconst_integer(s,Somec))->(tryexpand_constantIntegercswithexnwhenembed_errors->return(exn_to_error_extensionEC.expressioneexn))|Pexp_constant(Pconst_float(s,Somec))->(tryexpand_constantFloatcswithexnwhenembed_errors->return(exn_to_error_extensionEC.expressioneexn))|_->super#expressionbase_ctxte(* Pre-conditions:
- e.pexp_desc = Pexp_apply(func, args)
- func.pexp_desc = Pexp_ident _
*)methodprivatepexp_apply_without_traversing_functionbase_ctxtefuncargs=let{pexp_desc=_;pexp_loc;pexp_attributes;pexp_loc_stack}=einletfunc=with_contextbase_ctxtfunc>>=fun(base_ctxt,func)->letrechandle_attr_replace_fixreplaceditem=handle_attr_replace_onceAC.expressionattr_replace_expressionitembase_ctxt>>=function|Someitem->handle_attr_replace_fixtrueitem|None->return(replaced,item)inhandle_attr_replace_fixfalsefunc>>=fun(replaced,func)->matchreplacedwith(* If the attribute replacement changed the func then we should traverse it after
all. This might cause some weirdness if the attribute replacement doesn't
actually change the name of the function, because the special_function handling
code will get called again on the ident, but that feels mostly unavoidable. *)|true->super#expressionbase_ctxtfunc|false->let{pexp_desc;pexp_loc;pexp_attributes;pexp_loc_stack}=funcinself#attributesbase_ctxtpexp_attributes>>|funpexp_attributes->{pexp_desc;pexp_loc(* location doesn't need to be traversed *);pexp_attributes;pexp_loc_stack;}infunc>>=funfunc->letargs=List.mapargs~f:(fun(lab,exp)->self#expressionbase_ctxtexp>>|funexp->(lab,exp))|>combine_errorsinargs>>=funargs->self#attributesbase_ctxtpexp_attributes>>|funpexp_attributes->{pexp_loc;pexp_attributes;pexp_desc=Pexp_apply(func,args);pexp_loc_stack;}method!class_typebase_ctxtx=map_nodeattr_replace_class_typeEC.class_typeclass_typesuper#class_typex.pcty_locbase_ctxtxmethod!class_type_fieldbase_ctxtx=map_nodeattr_replace_class_type_fieldEC.class_type_fieldclass_type_fieldsuper#class_type_fieldx.pctf_locbase_ctxtxmethod!class_exprbase_ctxtx=map_nodeattr_replace_class_exprEC.class_exprclass_exprsuper#class_exprx.pcl_locbase_ctxtxmethod!class_fieldbase_ctxtx=map_nodeattr_replace_class_fieldEC.class_fieldclass_fieldsuper#class_fieldx.pcf_locbase_ctxtxmethod!module_typebase_ctxtx=map_nodeattr_replace_module_typeEC.module_typemodule_typesuper#module_typex.pmty_locbase_ctxtxmethod!module_exprbase_ctxtx=((* Make sure code-path attribute is applied before expanding. *)Attribute.get_resAst_traverse.enter_modulex|>of_result~default:None>>=function|None->return(base_ctxt,x)|Some{loc;txt}->Attribute.remove_seen_resModule_expr[TAst_traverse.enter_module]x|>of_result~default:x>>|funx->(Expansion_context.Base.enter_module~loctxtbase_ctxt,x))>>=fun(base_ctxt,x)->map_nodeattr_replace_module_exprEC.module_exprmodule_exprsuper#module_exprx.pmod_locbase_ctxtxmethod!structure_itembase_ctxtx=map_nodeattr_replace_structure_itemEC.structure_itemstructure_itemsuper#structure_itemx.pstr_locbase_ctxtxmethod!signature_itembase_ctxtx=map_nodeattr_replace_signature_itemEC.signature_itemsignature_itemsuper#signature_itemx.psig_locbase_ctxtxmethod!class_structurebase_ctxt{pcstr_self;pcstr_fields}=self#patternbase_ctxtpcstr_self>>=funpcstr_self->map_nodesattr_replace_class_fieldEC.class_fieldclass_fieldsuper#class_field(funx->x.pcf_loc)base_ctxtpcstr_fields>>|funpcstr_fields->{pcstr_self;pcstr_fields}method!type_declarationbase_ctxtx=map_node[]EC.Ppx_importppx_importsuper#type_declarationx.ptype_locbase_ctxtxmethod!class_signaturebase_ctxt{pcsig_self;pcsig_fields}=self#core_typebase_ctxtpcsig_self>>=funpcsig_self->map_nodesattr_replace_class_type_fieldEC.class_type_fieldclass_type_fieldsuper#class_type_field(funx->x.pctf_loc)base_ctxtpcsig_fields>>|funpcsig_fields->{pcsig_self;pcsig_fields}(* TODO: try to factorize #structure and #signature without meta-programming *)(*$*)method!structurebase_ctxtst=letconvert_exn=exn_to_striinletrecwith_extra_itemsitem~extra_items~expect_items~rest~in_generated_code=loop(rev_concatextra_items)~in_generated_code:true>>=funextra_items->ifnotin_generated_codethenGenerated_code_hook.insert_afterhookStructure_itemitem.pstr_loc(Manyextra_items);letoriginal_rest=restinlooprest~in_generated_code>>=funrest->(matchexpect_itemswith|[]->return()|_->letexpected=rev_concatexpect_itemsinletpos=item.pstr_loc.loc_endinCode_matcher.match_structure_resoriginal_rest~pos~expected~mismatch_handler:(funlocrepl->expect_mismatch_handler.fStructure_itemlocrepl)|>of_result~default:())>>|fun()->item::(extra_items@rest)andloopst~in_generated_code=matchstwith|[]->return[]|item::rest->(handle_attr_replace_strattr_replace_structure_itemitembase_ctxt>>=funitem->letloc=item.pstr_locinmatchitem.pstr_descwith|Pstr_extension(ext,attrs)->(letextension_point_loc=item.pstr_locinletctxt=Expansion_context.Extension.make~extension_point_loc~base:base_ctxt()inE.For_context.convert_inline_resstructure_item~ctxtext|>of_result~default:None>>=function|None->super#structure_itembase_ctxtitem>>=funitem->self#structurebase_ctxtrest>>|funrest->item::rest|Someitems->((),attributes_errorsattrs)>>=fun()->(* assert_no_attributes attrs; *)loopitems~in_generated_code:true>>=funitems->ifnotin_generated_codethenGenerated_code_hook.replacehookStructure_itemitem.pstr_loc(Manyitems);looprest~in_generated_code>>|funrest->items@rest)|Pstr_attributeat->handle_attr_floating_inlineattr_str_floating_expect_and_expand~item:at~loc~base_ctxt~convert_exn>>=funexpect_items_unexpanded->List.mapexpect_items_unexpanded~f:(self#structurebase_ctxt)|>combine_errors>>=funexpect_items_expanded->(* Shouldn't matter if we use [rev_concat] or [List.concat] here, there
should be only one (outer) list among [expect_items_expanded] unless
a single floating attribute is somehow registered twice. *)(matchrev_concatexpect_items_expandedwith|[]->return()|expected->Code_matcher.match_structure_resrest~pos:item.pstr_loc.loc_end~expected~mismatch_handler:(expect_mismatch_handler.fStructure_item)|>of_result~default:())>>=fun()->super#structure_itembase_ctxtitem>>=funexpanded_item->looprest~in_generated_code>>|funexpanded_rest->expanded_item::expanded_rest|_->(super#structure_itembase_ctxtitem>>=funexpanded_item->match(item.pstr_desc,expanded_item.pstr_desc)with|Pstr_type(rf,tds),Pstr_type(exp_rf,exp_tds)->(* No context-free rule can rewrite rec flags atm, this
assert acts as a failsafe in case it ever changes *)assert(Poly.(rf=exp_rf));handle_attr_group_inlineattr_str_type_declsrf~items:tds~expanded_items:exp_tds~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_group_inlineattr_str_type_decls_expectrf~items:tds~expanded_items:exp_tds~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Pstr_modtypemtd,Pstr_modtypeexp_mtd->handle_attr_inlineattr_str_module_type_decls~item:mtd~expanded_item:exp_mtd~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_str_module_type_decls_expect~item:mtd~expanded_item:exp_mtd~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Pstr_typextte,Pstr_typextexp_te->handle_attr_inlineattr_str_type_exts~item:te~expanded_item:exp_te~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_str_type_exts_expect~item:te~expanded_item:exp_te~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Pstr_exceptionec,Pstr_exceptionexp_ec->handle_attr_inlineattr_str_exceptions~item:ec~expanded_item:exp_ec~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_str_exceptions_expect~item:ec~expanded_item:exp_ec~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Pstr_modulemb,Pstr_moduleexp_mb->handle_attr_inlineattr_str_module_binding~item:mb~expanded_item:exp_mb~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_str_module_binding_expect~item:mb~expanded_item:exp_mb~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Pstr_class_typecds,Pstr_class_typeexp_cds->handle_attr_group_inlineattr_str_class_declsNonrecursive~items:cds~expanded_items:exp_cds~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_group_inlineattr_str_class_decls_expectNonrecursive~items:cds~expanded_items:exp_cds~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|_,_->self#structurebase_ctxtrest>>|funrest->expanded_item::rest))inloopst~in_generated_code:falsemethod!signaturebase_ctxtsg=letconvert_exn=exn_to_sigiinletrecwith_extra_itemsitem~extra_items~expect_items~rest~in_generated_code=loop(rev_concatextra_items)~in_generated_code:true>>=funextra_items->ifnotin_generated_codethenGenerated_code_hook.insert_afterhookSignature_itemitem.psig_loc(Manyextra_items);letoriginal_rest=restinlooprest~in_generated_code>>=funrest->(matchexpect_itemswith|[]->return()|_->letexpected=rev_concatexpect_itemsinletpos=item.psig_loc.loc_endinCode_matcher.match_signature_resoriginal_rest~pos~expected~mismatch_handler:(funlocrepl->expect_mismatch_handler.fSignature_itemlocrepl)|>of_result~default:())>>|fun()->item::(extra_items@rest)andloopsg~in_generated_code=matchsgwith|[]->return[]|item::rest->(handle_attr_replace_sigattr_replace_signature_itemitembase_ctxt>>=funitem->letloc=item.psig_locinmatchitem.psig_descwith|Psig_extension(ext,attrs)->(letextension_point_loc=item.psig_locinletctxt=Expansion_context.Extension.make~extension_point_loc~base:base_ctxt()inE.For_context.convert_inline_ressignature_item~ctxtext|>of_result~default:None>>=function|None->super#signature_itembase_ctxtitem>>=funitem->self#signaturebase_ctxtrest>>|funrest->item::rest|Someitems->((),attributes_errorsattrs)>>=fun()->(* assert_no_attributes attrs; *)loopitems~in_generated_code:true>>=funitems->ifnotin_generated_codethenGenerated_code_hook.replacehookSignature_itemitem.psig_loc(Manyitems);looprest~in_generated_code>>|funrest->items@rest)|Psig_attributeat->handle_attr_floating_inlineattr_sig_floating_expect_and_expand~item:at~loc~base_ctxt~convert_exn>>=funexpect_items_unexpanded->List.mapexpect_items_unexpanded~f:(self#signaturebase_ctxt)|>combine_errors>>=funexpect_items_expanded->(* Shouldn't matter if we use [rev_concat] or [List.concat] here, there
should be only one (outer) list among [expect_items_expanded] unless
a single floating attribute is somehow registered twice. *)(matchrev_concatexpect_items_expandedwith|[]->return()|expected->Code_matcher.match_signature_resrest~pos:item.psig_loc.loc_end~expected~mismatch_handler:(expect_mismatch_handler.fSignature_item)|>of_result~default:())>>=fun()->super#signature_itembase_ctxtitem>>=funexpanded_item->looprest~in_generated_code>>|funexpanded_rest->expanded_item::expanded_rest|_->(super#signature_itembase_ctxtitem>>=funexpanded_item->match(item.psig_desc,expanded_item.psig_desc)with|Psig_type(rf,tds),Psig_type(exp_rf,exp_tds)->(* No context-free rule can rewrite rec flags atm, this
assert acts as a failsafe in case it ever changes *)assert(Poly.(rf=exp_rf));handle_attr_group_inlineattr_sig_type_declsrf~items:tds~expanded_items:exp_tds~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_group_inlineattr_sig_type_decls_expectrf~items:tds~expanded_items:exp_tds~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Psig_modtypemtd,Psig_modtypeexp_mtd->handle_attr_inlineattr_sig_module_type_decls~item:mtd~expanded_item:exp_mtd~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_sig_module_type_decls_expect~item:mtd~expanded_item:exp_mtd~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Psig_typextte,Psig_typextexp_te->handle_attr_inlineattr_sig_type_exts~item:te~expanded_item:exp_te~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_sig_type_exts_expect~item:te~expanded_item:exp_te~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Psig_exceptionec,Psig_exceptionexp_ec->handle_attr_inlineattr_sig_exceptions~item:ec~expanded_item:exp_ec~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_sig_exceptions_expect~item:ec~expanded_item:exp_ec~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Psig_modulemd,Psig_moduleexp_md->handle_attr_inlineattr_sig_module_declaration~item:md~expanded_item:exp_md~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_inlineattr_sig_module_declaration_expect~item:md~expanded_item:exp_md~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|Psig_class_typecds,Psig_class_typeexp_cds->handle_attr_group_inlineattr_sig_class_declsNonrecursive~items:cds~expanded_items:exp_cds~loc~base_ctxt~convert_exn>>=funextra_items->handle_attr_group_inlineattr_sig_class_decls_expectNonrecursive~items:cds~expanded_items:exp_cds~loc~base_ctxt~convert_exn>>=funexpect_items->with_extra_itemsexpanded_item~extra_items~expect_items~rest~in_generated_code|_,_->self#signaturebase_ctxtrest>>|funrest->expanded_item::rest))inloopsg~in_generated_code:falseend