123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146(*
Perform inheritance.
*)openImportopenAstmoduleS=Set.Make(String)letload_defsl=lettbl=Predef.make_table()inList.iter(fun((_,(k,pl,_),_)astd)->Hashtbl.addtblk(List.lengthpl,Sometd))l;tblletkeep_last_definedget_namel=let_,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(_,(k,_,_),_)->k|`Inherit_->assertfalseletget_variant_name:variant->string=functionVariant(_,(k,_),_)->k|Inherit_->assertfalseletexpand?(inherit_fields=true)?(inherit_variants=true)tblt0=letrecsubstderefparam(t:type_expr):type_expr=matchtwithSum(loc,vl,a)->letvl=List.concat_map(subst_variantparam)vlinletvl=ifinherit_variantsthenkeep_last_definedget_variant_namevlelsevlinSum(loc,vl,a)|Record(loc,fl,a)->letfl=List.concat_map(subst_fieldparam)flinletfl=ifinherit_fieldsthenkeep_last_definedget_field_nameflelseflinRecord(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(_,s)->Option.value(List.assocsparam)~default:t|Name(loc,(loc2,k,args),a)->letexpanded_args=List.map(substfalseparam)argsinifderefthenlet_,vars,_,t=trymatchHashtbl.findtblkwith_,Some(_,(k,vars,a),t)->k,vars,a,t|_,None->failwith("Cannot inherit from type "^k)withNot_found->failwith("Missing type definition for "^k)inletparam=List.combinevarsexpanded_argsinsubsttrueparamtelseName(loc,(loc2,k,expanded_args),a)andsubst_fieldparam=function`Field(loc,k,t)->[`Field(loc,k,substfalseparamt)]|`Inherit(_,t)asx->(matchsubsttrueparamtwithRecord(_,vl,_)->ifinherit_fieldsthenvlelse[x]|_->failwith"Not a record type")andsubst_variantparam=functionVariant(loc,k,opt_t)asx->(matchopt_twithNone->[x]|Somet->[Variant(loc,k,Some(substfalseparamt))])|Inherit(_,t)asx->(matchsubsttrueparamtwithSum(_,vl,_)->ifinherit_variantsthenvlelse[x]|_->failwith"Not a sum type")insubstfalse[]t0letexpand_module_body?inherit_fields?inherit_variants(l:Ast.module_body)=lettd_list=List.map(function(Ast.Typetd)->td)linlettbl=load_defstd_listinlettd_list=List.map(fun(loc,name,t)->(loc,name,expand?inherit_fields?inherit_variantstblt))td_listinList.map(funtd->Ast.Typetd)td_list