Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file common.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277open!ImportopenAst_builder.DefaultmoduleBuffer=Stdlib.BuffermoduleFormat=Stdlib.Formatletlidentx=Longident.Lidentxletcore_type_of_type_declarationtd=letloc=td.ptype_name.locinptyp_constr~loc(Located.maplidenttd.ptype_name)(List.maptd.ptype_params~f:fst)letstrip_gen_symbol_suffix=letchopn~or_morestringposf=lettarget=!pos-ninwhile!pos>0&&(or_more||!pos>target)&&fstring.[!pos-1]dopos:=!pos-1done;!pos<=targetinfunstring->letpos=ref(String.lengthstring)inifchop1~or_more:falsestringpos(Char.equal'_')&&chop3~or_more:truestringpos(function|'0'..'9'->true|_->false)&&chop2~or_more:falsestringpos(Char.equal'_')thenString.prefixstring!poselsestringletgen_symbol=letcnt=ref0infun?(prefix="_x")()->cnt:=!cnt+1;letprefix=strip_gen_symbol_suffixprefixinPrintf.sprintf"%s__%03i_"prefix!cntletname_type_params_in_td_res(td:type_declaration):(type_declaration,_)result=letopenResultinletprefix_stringi=(* a, b, ..., y, z, aa, bb, ... *)String.make((i/26)+1)(Char.chr(Char.code'a'+(imod26)))inletname_parami(tp,variance)=(matchtp.ptyp_descwith|Ptyp_any->Ok(Ptyp_var(gen_symbol~prefix:(prefix_stringi)()))|Ptyp_var_asv->Okv|_->Error(Location.Error.createf~loc:tp.ptyp_loc"not a type parameter"))>>|funptyp_desc->({tpwithptyp_desc},variance)inletptype_params,errors=td.ptype_params|>List.mapi~f:name_param|>List.partition_map(function|Oko->Either.Lefto|Errore->Either.Righte)inmatcherrorswith[]->Ok{tdwithptype_params}|t::q->Error(t,q)letname_type_params_in_td(td:type_declaration):type_declaration=matchname_type_params_in_td_restdwith|Okres->res|Error(err,_)->Location.Error.raiseerrletcombinator_type_of_type_declarationtd~f=lettd=name_type_params_in_tdtdinletresult_type=f~loc:td.ptype_name.loc(core_type_of_type_declarationtd)inList.fold_righttd.ptype_params~init:result_type~f:(fun(tp,_variance)acc->letloc=tp.ptyp_locinptyp_arrow~locNolabel(f~loctp)acc)letstring_of_core_typect=letbuf=Buffer.create128inletppf=Format.formatter_of_bufferbufinPprintast.core_typeppfct;Format.pp_print_flushppf();Buffer.contentsbufletget_type_param_name_res(ty,_)=letloc=ty.ptyp_locinmatchty.ptyp_descwith|Ptyp_varname->Ok(Located.mk~locname)|_->Error(Location.Error.createf~loc"not a type parameter",[])letget_type_param_namet=matchget_type_param_name_restwith|Oke->e|Error(err,_)->Location.Error.raiseerrexceptionType_is_recursiveclasstype_is_recursiverec_flagtds=object(self)inheritAst_traverse0.iterassupervaltype_names:stringlist=List.maptds~f:(funtd->td.ptype_name.txt)methodreturn_true()=raise_notraceType_is_recursivemethod!core_typectype=matchctype.ptyp_descwith|Ptyp_arrow_->()|Ptyp_constr({txt=Longident.Lidentid;_},_)whenList.mem~set:type_namesid->self#return_true()|_->super#core_typectypemethod!constructor_declarationcd=(* Don't recurse through cd.pcd_res *)matchcd.pcd_argswith|Pcstr_tupleargs->List.iterargs~f:self#core_type|Pcstr_recordfields->List.iterfields~f:self#label_declarationmethod!attributes_=(* Don't recurse through attributes *)()methodgo()=matchrec_flagwith|Nonrecursive->Nonrecursive|Recursive->(matchList.itertds~f:self#type_declarationwith|exceptionType_is_recursive->Recursive|()->Nonrecursive)endletreally_recursiverec_flagtds=(newtype_is_recursiverec_flagtds)#go()letreclastxl=matchlwith[]->x|x::l->lastxlletloc_of_name_and_payloadnamepayload=matchpayloadwith|PStr[]->name.loc|PStr(x::l)->{x.pstr_locwithloc_end=(lastxl).pstr_loc.loc_end}|PSig[]->name.loc|PSig(x::l)->{x.psig_locwithloc_end=(lastxl).psig_loc.loc_end}|PTypt->t.ptyp_loc|PPat(x,None)->x.ppat_loc|PPat(x,Somee)->{x.ppat_locwithloc_end=e.pexp_loc.loc_end}letloc_of_payload{attr_name;attr_payload;attr_loc=_}=loc_of_name_and_payloadattr_nameattr_payloadletloc_of_attribute{attr_name;attr_payload;attr_loc=_}=(* TODO: fix this in the compiler, and move the logic to omp when converting
from older asts. *)(* "ocaml.doc" attributes are generated with [Location.none], which is not helpful for
error messages. *)ifPoly.(=)attr_name.locLocation.nonethenloc_of_name_and_payloadattr_nameattr_payloadelse{attr_name.locwithloc_end=(loc_of_name_and_payloadattr_nameattr_payload).loc_end;}letloc_of_extension(name,payload)=ifPoly.(=)name.locLocation.nonethenloc_of_name_and_payloadnamepayloadelse{name.locwithloc_end=(loc_of_name_and_payloadnamepayload).loc_end}letcurry_applicationsexpr=letopenAst_builder_generated.Minmatchexpr.pexp_descwith|Pexp_apply(f,orig_forward_args)->letloc=expr.pexp_locinletrecloop=function|[]->f|last_arg::rev_front_args->pexp_apply~loc(looprev_front_args)[last_arg]inloop(List.revorig_forward_args)|_->exprletattributes_errors=List.filter_map~f:(function|{attr_name=name;attr_loc=_;attr_payload=_}whenName.ignore_checksname.Location.txt->None|attr->letloc=loc_of_attributeattrinSome(Location.Error.createf~loc"Attributes not allowed here"))letcollect_attributes_errors=objectinherit[Location.Error.tlist]Ast_traverse0.foldmethod!attributeaacc=attributes_errors[a]@accendletassert_no_attributesl=matchattributes_errorslwith|[]->()|err::_->Location.Error.raiseerrletassert_no_attributes_in=objectinheritAst_traverse0.itermethod!attributea=assert_no_attributes[a]endletattribute_of_warninglocs={attr_name={loc;txt="ocaml.ppwarning"};attr_payload=PStr[pstr_eval~loc(estring~locs)[]];attr_loc=loc;}letis_polymorphic_variant=letreccheck=function|{ptyp_desc=Ptyp_variant_;_}->`Definitely|{ptyp_desc=Ptyp_alias(typ,_);_}->checktyp|{ptyp_desc=Ptyp_constr_;_}->`Maybe|_->`Surely_not(* Type vars go here even though they could be polymorphic
variants, however we don't handle it if they get substituted
by a polymorphic variant that is then included. *)infuntd~sig_->matchtd.ptype_kindwith|Ptype_variant_|Ptype_record_|Ptype_open->`Surely_not|Ptype_abstract->(matchtd.ptype_manifestwith|None->ifsig_then`Maybeelse`Surely_not|Sometyp->checktyp)letmk_named_sig~loc~sg_name~handle_polymorphic_variant=function|[td]whenString.equaltd.ptype_name.txt"t"&&List.is_emptytd.ptype_cstrs->if(nothandle_polymorphic_variant)&&Poly.(=)(is_polymorphic_varianttd~sig_:true)`DefinitelythenNoneelseletarity=List.lengthtd.ptype_paramsinifarity>=4thenNoneelseletmty=ifarity=0thensg_nameelsePrintf.sprintf"%s%d"sg_namearityinlettd=name_type_params_in_tdtdinletfor_subst=Ast_helper.Type.mk~loctd.ptype_name~params:td.ptype_params~manifest:(ptyp_constr~loc(Located.map_lidenttd.ptype_name)(List.map~f:fsttd.ptype_params))inSome(include_infos~loc(pmty_with~loc(pmty_ident~loc(Located.lidentmty~loc))[Pwith_typesubst(Located.lident~loc"t",for_subst)]))|_->Noneletexn_to_loc_errorexn=matchLocation.Error.of_exnexnwithSomeerror->error|None->raiseexnmoduleWith_errors=structtype'at='a*Location.Error.tlistletreturne=(e,[])let(>>=)(x,errors1)f=lety,errors2=fxin(y,errors1@errors2)let(>>|)(x,errors)f=(fx,errors)letof_resultresult~default=matchresultwith|Okx->(x,[])|Errorerrors->(default,NonEmptyList.to_listerrors)letcombine_errorslist=(List.maplist~f:fst,List.concat_maplist~f:snd)end