123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501open!ImportopenCommontype(_,_)equality=Eq:('a,'a)equality|Ne:(_,_)equalitymoduleContext=structtype'at=|Class_expr:class_exprt|Class_field:class_fieldt|Class_type:class_typet|Class_type_field:class_type_fieldt|Core_type:core_typet|Expression:expressiont|Module_expr:module_exprt|Module_type:module_typet|Pattern:patternt|Signature_item:signature_itemt|Structure_item:structure_itemt|Ppx_import:type_declarationttypepacked=T:_t->packedletclass_expr=Class_exprletclass_field=Class_fieldletclass_type=Class_typeletclass_type_field=Class_type_fieldletcore_type=Core_typeletexpression=Expressionletmodule_expr=Module_exprletmodule_type=Module_typeletpattern=Patternletsignature_item=Signature_itemletstructure_item=Structure_itemletdesc:typea.at->string=function|Class_expr->"class expression"|Class_field->"class field"|Class_type->"class type"|Class_type_field->"class type field"|Core_type->"core type"|Expression->"expression"|Module_expr->"module expression"|Module_type->"module type"|Pattern->"pattern"|Signature_item->"signature item"|Structure_item->"structure item"|Ppx_import->"type declaration"leteq:typeab.at->bt->(a,b)equality=funab->match(a,b)with|Class_expr,Class_expr->Eq|Class_field,Class_field->Eq|Class_type,Class_type->Eq|Class_type_field,Class_type_field->Eq|Core_type,Core_type->Eq|Expression,Expression->Eq|Module_expr,Module_expr->Eq|Module_type,Module_type->Eq|Pattern,Pattern->Eq|Signature_item,Signature_item->Eq|Structure_item,Structure_item->Eq|Ppx_import,Ppx_import->Eq|_->assert(Poly.(<>)(Ta)(Tb));Neletget_ppx_import_extensiontype_decl=matchtype_declwith|{ptype_manifest=Some{ptyp_desc=Ptyp_extension(name,_);_};_}->letvirtual_payload=Ast_builder.Default.pstr_type~loc:type_decl.ptype_locRecursive[type_decl]inletattr=[]inSome((name,PStr[virtual_payload]),attr)|_->Noneletget_extension:typea.at->a->(extension*attributes)option=funtx->match(t,x)with|Class_expr,{pcl_desc=Pcl_extensione;pcl_attributes=a;_}->Some(e,a)|Class_field,{pcf_desc=Pcf_extensione;pcf_attributes=a;_}->Some(e,a)|Class_type,{pcty_desc=Pcty_extensione;pcty_attributes=a;_}->Some(e,a)|Class_type_field,{pctf_desc=Pctf_extensione;pctf_attributes=a;_}->Some(e,a)|Core_type,{ptyp_desc=Ptyp_extensione;ptyp_attributes=a;_}->Some(e,a)|Expression,{pexp_desc=Pexp_extensione;pexp_attributes=a;_}->Some(e,a)|Module_expr,{pmod_desc=Pmod_extensione;pmod_attributes=a;_}->Some(e,a)|Module_type,{pmty_desc=Pmty_extensione;pmty_attributes=a;_}->Some(e,a)|Pattern,{ppat_desc=Ppat_extensione;ppat_attributes=a;_}->Some(e,a)|Signature_item,{psig_desc=Psig_extension(e,a);_}->Some(e,a)|Structure_item,{pstr_desc=Pstr_extension(e,a);_}->Some(e,a)|Ppx_import,type_decl->get_ppx_import_extensiontype_decl|_->Noneletmerge_attributes_res:typea.at->a->attributes->(a,Location.Error.tNonEmptyList.t)result=funtxattrs->matchtwith|Class_expr->Ok{xwithpcl_attributes=x.pcl_attributes@attrs}|Class_field->Ok{xwithpcf_attributes=x.pcf_attributes@attrs}|Class_type->Ok{xwithpcty_attributes=x.pcty_attributes@attrs}|Class_type_field->Ok{xwithpctf_attributes=x.pctf_attributes@attrs}|Core_type->Ok{xwithptyp_attributes=x.ptyp_attributes@attrs}|Expression->Ok{xwithpexp_attributes=x.pexp_attributes@attrs}|Module_expr->Ok{xwithpmod_attributes=x.pmod_attributes@attrs}|Module_type->Ok{xwithpmty_attributes=x.pmty_attributes@attrs}|Pattern->Ok{xwithppat_attributes=x.ppat_attributes@attrs}|Signature_item->(matchattributes_errorsattrswith[]->Okx|t::q->Error(t,q))|Structure_item->(matchattributes_errorsattrswith[]->Okx|t::q->Error(t,q))|Ppx_import->(matchattributes_errorsattrswith[]->Okx|t::q->Error(t,q))letmerge_attributes:typea.at->a->attributes->a=funtxattrs->merge_attributes_restxattrs|>Result.handle_error~f:(fun(err,_)->Location.Error.raiseerr)endletregistrar=Name.Registrar.create~kind:"extension"~current_file:__FILE__~string_of_context:(fun(Context.Tctx)->Some(Context.descctx))moduleMake(Callback:sigtype'atend)=structtype('a,'b)payload_parser=|Payload_parser:('a,'b,'c)Ast_pattern.t*'bCallback.t->('a,'c)payload_parsertype('context,'payload)t={name:Name.Pattern.t;context:'contextContext.t;payload:(payload,'payload)payload_parser;with_arg:bool;}letdeclare:typea.with_arg:bool->string->aContext.t->(payload,'b,'payload)Ast_pattern.t->'bCallback.t->(a,'payload)t=fun~with_argnamecontextpatternk->(* Check that there is no collisions between ppx_import and core_type
extensions *)(matchcontextwith|Context.Ppx_import->Name.Registrar.check_collisionsregistrar(Context.TCore_type)name|Context.Core_type->Name.Registrar.check_collisionsregistrar(Context.TPpx_import)name|_->());Name.Registrar.register~kind:`Extensionregistrar(Context.Tcontext)name;{name=Name.Pattern.makename;context;payload=Payload_parser(pattern,k);with_arg;}letfindts(ext:extension)=let{txt=name;loc}=fstextinletname,arg=Name.split_pathnameinmatchList.filterts~f:(funt->Name.Pattern.matchest.namename)with|[]->OkNone|_::_::_asl->Error(Location.Error.createf~loc"Multiple match for extensions: %s"(String.concat~sep:", "(List.mapl~f:(funt->Name.Pattern.namet.name))),[])|[t]->if(nott.with_arg)&&Option.is_someargthenError(Location.Error.createf~loc"Extension %s doesn't expect a path argument"name,[])elseletarg=Option.maparg~f:(funs->letshift=String.lengthname+1inletstart=loc.loc_startin{txt=Longident.parses;loc={locwithloc_start={startwithpos_cnum=start.pos_cnum+shift};};})inOk(Some(t,arg))endmoduleExpert=structincludeMake(structtype'at=arg:Longident.tLoc.toption->'aend)letdeclare_with_path_argnamectxpattf=declare~with_arg:truenamectxpattfletdeclarenamectxpattf=declare~with_arg:falsenamectxpatt(fun~arg:_->f)letconvert_rests~locext=letopenResultinfindtsext>>=funr->matchrwith|None->OkNone|Some({payload=Payload_parser(pattern,f);_},arg)->Ast_pattern.parse_respatternloc(sndext)(f~arg)>>|funpayload->Somepayloadletconvertts~locext=convert_rests~locext|>Result.handle_error~f:(fun(err,_)->Location.Error.raiseerr)endmoduleM=Make(structtype'at=ctxt:Expansion_context.Extension.t->arg:Longident.tLoc.toption->'aend)type'aexpander_result=Simpleof'a|Inlineof'alistmoduleFor_context=structtype'at=('a,'aexpander_result)M.tletconvert_rests~ctxtext=letloc=Expansion_context.Extension.extension_point_locctxtinletopenResultinM.findtsext>>=funfound->matchfoundwith|None->OkNone|Some({payload=M.Payload_parser(pattern,f);_},arg)->(Ast_pattern.parse_respatternloc(sndext)(f~ctxt~arg)>>|funpayload->matchpayloadwith|Simplex->Somex|Inline_->failwith"Extension.convert")letconvertts~ctxtext=convert_rests~ctxtext|>Result.handle_error~f:(fun(err,_)->Location.Error.raiseerr)letconvert_inline_rests~ctxtext=letloc=Expansion_context.Extension.extension_point_locctxtinletopenResultinM.findtsext>>=funfound->matchfoundwith|None->OkNone|Some({payload=M.Payload_parser(pattern,f);_},arg)->(Ast_pattern.parse_respatternloc(sndext)(f~ctxt~arg)>>|funpayload->matchpayloadwithSimplex->Some[x]|Inlinel->Somel)letconvert_inlinets~ctxtext=convert_inline_rests~ctxtext|>Result.handle_error~f:(fun(err,_)->Location.Error.raiseerr)endtypet=T:_For_context.t->tletcheck_context_for_inline:typea.func:string->aContext.t->unit=fun~funcctx->matchctxwith|Context.Class_field->()|Context.Class_type_field->()|Context.Signature_item->()|Context.Structure_item->()|context->Printf.ksprintfinvalid_arg"%s: %s can't be inlined"func(Context.desccontext)letrecfilter_by_context:typea.aContext.t->tlist->aFor_context.tlist=funcontextexpanders->matchexpanderswith|[]->[]|Tt::rest->(matchContext.eqcontextt.contextwith|Eq->t::filter_by_contextcontextrest|Ne->filter_by_contextcontextrest)letunhandled_extension_errorctx(name,_)=ifnot(Name.Allowlisted.is_allowlisted~kind:`Extensionname.txt||Name.ignore_checksname.txt)then[Name.Registrar.Error.createfregistrar(Context.Tctx)"Extension `%s' was not translated"name;]else[]letcollect_unhandled_extension_errors=objectinherit[Location.Error.tlist]Ast_traverse.foldassupermethod!extension(name,_)acc=acc@[Location.Error.createf~loc:name.loc"extension not expected here, Ppxlib.Extension needs updating!";]method!core_type_descxacc=matchxwith|Ptyp_extensionext->acc@unhandled_extension_errorCore_typeext|x->super#core_type_descxaccmethod!pattern_descxacc=matchxwith|Ppat_extensionext->acc@unhandled_extension_errorPatternext|x->super#pattern_descxaccmethod!expression_descxacc=matchxwith|Pexp_extensionext->acc@unhandled_extension_errorExpressionext|x->super#expression_descxaccmethod!class_type_descxacc=matchxwith|Pcty_extensionext->acc@unhandled_extension_errorClass_typeext|x->super#class_type_descxaccmethod!class_type_field_descxacc=matchxwith|Pctf_extensionext->acc@unhandled_extension_errorClass_type_fieldext|x->super#class_type_field_descxaccmethod!class_expr_descxacc=matchxwith|Pcl_extensionext->acc@unhandled_extension_errorClass_exprext|x->super#class_expr_descxaccmethod!class_field_descxacc=matchxwith|Pcf_extensionext->acc@unhandled_extension_errorClass_fieldext|x->super#class_field_descxaccmethod!module_type_descxacc=matchxwith|Pmty_extensionext->acc@unhandled_extension_errorModule_typeext|x->super#module_type_descxaccmethod!signature_item_descxacc=matchxwith|Psig_extension(ext,_)->acc@unhandled_extension_errorSignature_itemext|x->super#signature_item_descxaccmethod!module_expr_descxacc=matchxwith|Pmod_extensionext->acc@unhandled_extension_errorModule_exprext|x->super#module_expr_descxaccmethod!structure_item_descxacc=matchxwith|Pstr_extension(ext,_)->acc@unhandled_extension_errorStructure_itemext|x->super#structure_item_descxaccendleterror_list_to_exception=function|[]->()|err::_->Location.Error.raiseerrletcheck_unused=objectinheritAst_traverse.itermethod!extension(name,_)=Location.raise_errorf~loc:name.loc"extension not expected here, Ppxlib.Extension needs updating!"method!core_type_descx=collect_unhandled_extension_errors#core_type_descx[]|>error_list_to_exceptionmethod!pattern_descx=collect_unhandled_extension_errors#pattern_descx[]|>error_list_to_exceptionmethod!expression_descx=collect_unhandled_extension_errors#expression_descx[]|>error_list_to_exceptionmethod!class_type_descx=collect_unhandled_extension_errors#class_type_descx[]|>error_list_to_exceptionmethod!class_type_field_descx=collect_unhandled_extension_errors#class_type_field_descx[]|>error_list_to_exceptionmethod!class_expr_descx=collect_unhandled_extension_errors#class_expr_descx[]|>error_list_to_exceptionmethod!class_field_descx=collect_unhandled_extension_errors#class_field_descx[]|>error_list_to_exceptionmethod!module_type_descx=collect_unhandled_extension_errors#module_type_descx[]|>error_list_to_exceptionmethod!signature_item_descx=collect_unhandled_extension_errors#signature_item_descx[]|>error_list_to_exceptionmethod!module_expr_descx=collect_unhandled_extension_errors#module_expr_descx[]|>error_list_to_exceptionmethod!structure_item_descx=collect_unhandled_extension_errors#structure_item_descx[]|>error_list_to_exceptionendmoduleV3=structtypenonrect=tletdeclarenamecontextpatternk=letpattern=Ast_pattern.map_resultpattern~f:(funx->Simplex)inT(M.declare~with_arg:falsenamecontextpattern(fun~ctxt~arg:_->k~ctxt))letdeclare_inlinenamecontextpatternk=check_context_for_inlinecontext~func:"Extension.declare_inline";letpattern=Ast_pattern.map_resultpattern~f:(funx->Inlinex)inT(M.declare~with_arg:falsenamecontextpattern(fun~ctxt~arg:_->k~ctxt))letdeclare_with_path_argnamecontextpatternk=letpattern=Ast_pattern.map_resultpattern~f:(funx->Simplex)inT(M.declare~with_arg:truenamecontextpatternk)letdeclare_inline_with_path_argnamecontextpatternk=check_context_for_inlinecontext~func:"Extension.declare_inline_with_path_arg";letpattern=Ast_pattern.map_resultpattern~f:(funx->Inlinex)inT(M.declare~with_arg:truenamecontextpatternk)endletdeclarenamecontextpatternf=V3.declarenamecontextpattern(Expansion_context.Extension.with_loc_and_pathf)letdeclare_inlinenamecontextpatternf=V3.declare_inlinenamecontextpattern(Expansion_context.Extension.with_loc_and_pathf)letdeclare_with_path_argnamecontextpatternk=letk'=Expansion_context.Extension.with_loc_and_pathkinletpattern=Ast_pattern.map_resultpattern~f:(funx->Simplex)inT(M.declare~with_arg:truenamecontextpatternk')letdeclare_inline_with_path_argnamecontextpatternk=letk'=Expansion_context.Extension.with_loc_and_pathkincheck_context_for_inlinecontext~func:"Extension.declare_inline_with_path_arg";letpattern=Ast_pattern.map_resultpattern~f:(funx->Inlinex)inT(M.declare~with_arg:truenamecontextpatternk')let__declare_ppx_importnameexpand=(* This pattern is used to unwrap the type declaration from the payload
assembled by [Context.get_ppx_import_extension] *)letpattern=Ast_pattern.(pstr(pstr_typerecursive(__^::nil)^::nil))inV3.declarenameContext.Ppx_importpatternexpandmoduleV2=structtypenonrect=tletdeclare=declareletdeclare_inline=declare_inlineend