123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149(*
Perform inheritance.
*)openPrintfopenAtd_astmoduleS=Set.Make(String)letload_defsl=lettbl=Atd_predef.make_table()inList.iter(fun((_,(k,pl,_),_)astd)->Hashtbl.addtblk(List.lengthpl,Sometd))l;tblletkeep_last_definedget_namel=letset,l=List.fold_right(funx(set,l)->letk=get_namexinifS.memksetthen(set,l)else(S.addkset,x::l))l(S.empty,[])inlletget_field_name:field->string=function`Field(loc,(k,_,_),_)->k|`Inherit_->assertfalseletget_variant_name:variant->string=function`Variant(loc,(k,_),_)->k|`Inherit_->assertfalseletexpand?(inherit_fields=true)?(inherit_variants=true)tblt0=letrecsubstderefparam(t:type_expr):type_expr=matchtwith`Sum(loc,vl,a)->letvl=List.flatten(List.map(subst_variantparam)vl)inletvl=ifinherit_variantsthenkeep_last_definedget_variant_namevlelsevlin`Sum(loc,vl,a)|`Record(loc,fl,a)->letfl=List.flatten(List.map(subst_fieldparam)fl)inletfl=ifinherit_fieldsthenkeep_last_definedget_field_nameflelseflin`Record(loc,fl,a)|`Tuple(loc,tl,a)->`Tuple(loc,List.map(fun(loc,x,a)->(loc,substfalseparamx,a))tl,a)|`List(loc,t,a)|`Name(loc,(_,"list",[t]),a)->`List(loc,substfalseparamt,a)|`Option(loc,t,a)|`Name(loc,(_,"option",[t]),a)->`Option(loc,substfalseparamt,a)|`Nullable(loc,t,a)|`Name(loc,(_,"nullable",[t]),a)->`Nullable(loc,substfalseparamt,a)|`Shared(loc,t,a)|`Name(loc,(_,"shared",[t]),a)->`Shared(loc,substfalseparamt,a)|`Wrap(loc,t,a)|`Name(loc,(_,"wrap",[t]),a)->`Wrap(loc,substfalseparamt,a)|`Tvar(loc,s)->(tryList.assocsparamwithNot_found->t)|`Name(loc,(loc2,k,args),a)->letexpanded_args=List.map(substfalseparam)argsinifderefthenletk,vars,a,t=trymatchHashtbl.findtblkwithn,Some(_,(k,vars,a),t)->k,vars,a,t|n,None->failwith("Cannot inherit from type "^k)withNot_found->failwith("Missing type definition for "^k)inletparam=List.combinevarsexpanded_argsinsubsttrueparamtelse`Name(loc,(loc2,k,expanded_args),a)andsubst_fieldparam=function`Field(loc,k,t)->[`Field(loc,k,substfalseparamt)]|`Inherit(loc,t)asx->(matchsubsttrueparamtwith`Record(loc,vl,a)->ifinherit_fieldsthenvlelse[x]|_->failwith"Not a record type")andsubst_variantparam=function`Variant(loc,k,opt_t)asx->(matchopt_twithNone->[x]|Somet->[`Variant(loc,k,Some(substfalseparamt))])|`Inherit(loc,t)asx->(matchsubsttrueparamtwith`Sum(loc,vl,a)->ifinherit_variantsthenvlelse[x]|_->failwith"Not a sum type")insubstfalse[]t0letexpand_module_body?inherit_fields?inherit_variants(l:Atd_ast.module_body)=lettd_list=List.map(function`Typetd->td)linlettbl=load_defstd_listinlettd_list=List.map(fun(loc,name,t)->(loc,name,expand?inherit_fields?inherit_variantstblt))td_listinList.map(funtd->`Typetd)td_list