Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_deriving_create.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132openPpxlibopenAsttypesopenParsetreeopenAst_helperopenPpx_deriving.Ast_convenienceletderiver="create"letraise_errorf=Ppx_deriving.raise_errorfletattr_defaultcontext=Attribute.declare"deriving.create.default"contextAst_pattern.(single_expr_payload__)(fune->e)letattr_default=(attr_defaultAttribute.Context.label_declaration,attr_defaultAttribute.Context.core_type)letattr_splitcontext=Attribute.declare_flag"deriving.create.split"contextletct_attr_split=attr_splitAttribute.Context.core_typeletlabel_attr_split=attr_splitAttribute.Context.label_declarationletattr_maincontext=Attribute.declare_flag"deriving.create.main"contextletct_attr_main=attr_mainAttribute.Context.core_typeletlabel_attr_main=attr_mainAttribute.Context.label_declarationletget_label_attribute(label_attr,ct_attr)label=matchAttribute.getlabel_attrlabelwith|Some_asv->v|None->Attribute.getct_attrlabel.pld_typeletfind_mainlabels=List.fold_left(fun(main,labels)({pld_type;pld_loc;pld_attributes}aslabel)->ifAttribute.has_flagct_attr_mainpld_type||Attribute.has_flaglabel_attr_mainlabelthenmatchmainwith|Some_->raise_errorf~loc:pld_loc"Duplicate [@deriving.%s.main] annotation"deriver|None->Somelabel,labelselsemain,label::labels)(None,[])labelsletstr_of_type({ptype_loc=loc}astype_decl)=letquoter=Ppx_deriving.create_quoter()inletcreator=matchtype_decl.ptype_kindwith|Ptype_recordlabels->letfields=labels|>List.map(fun{pld_name={txt=name;loc}}->name,evarname)inletmain,labels=find_mainlabelsinletfn=matchmainwith|Some{pld_name={txt=name}}->Exp.fun_Label.nolabelNone(pvarname)(recordfields)|None->Exp.fun_Label.nolabelNone(punit())(recordfields)inList.fold_left(funaccum({pld_name={txt=name};pld_type;pld_attributes}aslabel)->matchget_label_attributeattr_defaultlabelwith|Somedefault->Exp.fun_(Label.optionalname)(Some(Ppx_deriving.quote~quoterdefault))(pvarname)accum|None->letpld_type=Ppx_deriving.remove_pervasives~deriverpld_typeinifAttribute.has_flaglabel_attr_splitlabel||Attribute.has_flagct_attr_splitpld_typethenmatchpld_typewith|[%type:[%t?lhs]*[%t?rhs]list]whenname.[String.lengthname-1]='s'->letname'=String.subname0(String.lengthname-1)inExp.fun_(Label.labelledname')None(pvarname')(Exp.fun_(Label.optionalname)(Some[%expr[]])(pvarname)[%exprlet[%ppvarname]=[%eevarname'],[%eevarname]in[%eaccum]])|_->raise_errorf~loc"[@deriving.%s.split] annotation requires a type of form \
'a * 'b list and label name ending with `s'"deriverelsematchpld_typewith|[%type:[%t?_]list]->Exp.fun_(Label.optionalname)(Some[%expr[]])(pvarname)accum|[%type:[%t?_]option]->Exp.fun_(Label.optionalname)None(pvarname)accum|_->Exp.fun_(Label.labelledname)None(pvarname)accum)fnlabels|_->raise_errorf~loc"%s can be derived only for record types"deriverin[Vb.mk(pvar(Ppx_deriving.mangle_type_decl(`Prefixderiver)type_decl))(Ppx_deriving.sanitize~quotercreator)]letwrap_predef_optiontyp=typletsig_of_type({ptype_loc=loc}astype_decl)=lettyp=Ppx_deriving.core_type_of_type_decltype_declinlettyp=matchtype_decl.ptype_kindwith|Ptype_recordlabels->letmain,labels=find_mainlabelsinlettyp=matchmainwith|Some{pld_name={txt=name};pld_type}->Typ.arrowLabel.nolabelpld_typetyp|None->Typ.arrowLabel.nolabel(tconstr"unit"[])typinList.fold_left(funaccum({pld_name={txt=name;loc};pld_type;pld_attributes}aslabel)->matchget_label_attributeattr_defaultlabelwith|Some_->Typ.arrow(Label.optionalname)(wrap_predef_optionpld_type)accum|None->letpld_type=Ppx_deriving.remove_pervasives~deriverpld_typeinifAttribute.has_flagct_attr_splitpld_type||Attribute.has_flaglabel_attr_splitlabelthenmatchpld_typewith|[%type:[%t?lhs]*[%t?rhs]list]whenname.[String.lengthname-1]='s'->letname'=String.subname0(String.lengthname-1)inTyp.arrow(Label.labelledname')lhs(Typ.arrow(Label.optionalname)(wrap_predef_option[%type:[%trhs]list])accum)|_->raise_errorf~loc"[@deriving.%s.split] annotation requires a type of form \
'a * 'b list and label name ending with `s'"deriverelsematchpld_typewith|[%type:[%t?_]list]->Typ.arrow(Label.optionalname)(wrap_predef_optionpld_type)accum|[%type:[%t?opt]option]->Typ.arrow(Label.optionalname)(wrap_predef_optionopt)accum|_->Typ.arrow(Label.labelledname)pld_typeaccum)typlabels|_->raise_errorf~loc"%s can only be derived for record types"deriverin[Sig.value(Val.mk(mknoloc(Ppx_deriving.mangle_type_decl(`Prefixderiver)type_decl))typ)]letimpl_generator=Deriving.Generator.V2.make_noarg(fun~ctxt:_(_,type_decls)->[Str.valueNonrecursive(List.concat(List.mapstr_of_typetype_decls))])letintf_generator=Deriving.Generator.V2.make_noarg(fun~ctxt:_(_,type_decls)->List.concat(List.mapsig_of_typetype_decls))letderiving:Deriving.t=Deriving.addderiver~str_type_decl:impl_generator~sig_type_decl:intf_generator