123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789(**************************************************************************)(* *)(* OCaml *)(* *)(* Xavier Leroy and Jerome Vouillon, projet Cristal, INRIA Rocquencourt *)(* *)(* Copyright 1996 Institut National de Recherche en Informatique et *)(* en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)(* Basic operations on core types *)openAsttypesopenTypesopenLocal_store(**** Sets, maps and hashtables of types ****)letwrap_reprfty=f(Transient_expr.reprty)letwrap_type_exprftty=f(Transient_expr.type_exprtty)moduleTransientTypeSet=Set.Make(TransientTypeOps)moduleTypeSet=structincludeTransientTypeSetletadd=wrap_repraddletmem=wrap_reprmemletsingleton=wrap_reprsingletonletexistsp=TransientTypeSet.exists(wrap_type_exprp)letelementsset=List.mapTransient_expr.type_expr(TransientTypeSet.elementsset)endmoduleTransientTypeMap=Map.Make(TransientTypeOps)moduleTypeMap=structincludeTransientTypeMapletaddty=wrap_repraddtyletfindty=wrap_reprfindtyletsingletonty=wrap_reprsingletontyletfoldf=TransientTypeMap.fold(wrap_type_exprf)endmoduleTypeHash=structincludeTransientTypeHashletmemhash=wrap_repr(memhash)letaddhash=wrap_repr(addhash)letremovehash=wrap_repr(removehash)letfindhash=wrap_repr(findhash)letfind_opthash=wrap_repr(find_opthash)letiterf=TransientTypeHash.iter(wrap_type_exprf)endmoduleTransientTypePairs=Hashtbl.Make(structtypet=transient_expr*transient_exprletequal(t1,t1')(t2,t2')=(t1==t2)&&(t1'==t2')lethash(t,t')=t.id+93*t'.idend)moduleTypePairs=structmoduleH=TransientTypePairsopenTransient_exprtypet={set:unitH.t;mutableelems:(transient_expr*transient_expr)list;(* elems preserves the (reversed) insertion order of elements *)}letcreaten={elems=[];set=H.createn}letcleart=t.elems<-[];H.cleart.setletrepr2(t1,t2)=(reprt1,reprt2)letaddtp=letp=repr2pinifH.memt.setpthen()elsebeginH.addt.setp();t.elems<-p::t.elemsendletmemtp=H.memt.set(repr2p)letiterft=(* iterate in insertion order, not Hashtbl.iter order *)List.revt.elems|>List.iter(fun(t1,t2)->f(type_exprt1,type_exprt2))end(**** Type level management ****)letgeneric_level=Ident.highest_scopeletlowest_level=Ident.lowest_scope(**** leveled type pool ****)(* This defines a stack of pools of type nodes indexed by the level
we will try to generalize them in [Ctype.with_local_level_gen].
[pool_of_level] returns the pool in which types at level [level]
should be kept, which is the topmost pool whose level is lower or
equal to [level].
[Ctype.with_local_level_gen] shall call [with_new_pool] to create
a new pool at a given level. On return it shall process all nodes
that were added to the pool.
Remark: the only function adding to a pool is [add_to_pool], and
the only function returning the contents of a pool is [with_new_pool],
so that the initial pool can be added to, but never read from. *)typepool={level:int;mutablepool:transient_exprlist;next:pool}(* To avoid an indirection we choose to add a dummy level at the end of
the list. It will never be accessed, as [pool_of_level] is always called
with [level >= 0]. *)letrecdummy={level=max_int;pool=[];next=dummy}letpool_stack=s_table(fun()->{level=0;pool=[];next=dummy})()(* Lookup in the stack is linear, but the depth is the number of nested
generalization points (e.g. lhs of let-definitions), which in ML is known
to be generally low. In most cases we are allocating in the topmost pool.
In [Ctype.with_local_gen], we move non-generalizable type nodes from the
topmost pool to one deeper in the stack, so that for each type node the
accumulated depth of lookups over its life is bounded by the depth of
the stack when it was allocated.
In case this linear search turns out to be costly, we could switch to
binary search, exploiting the fact that the levels of pools in the stack
are expected to grow. *)letrecpool_of_levellevelpool=iflevel>=pool.levelthenpoolelsepool_of_levellevelpool.next(* Create a new pool at given level, and use it locally. *)letwith_new_pool~levelf=letpool={level;pool=[];next=!pool_stack}inletr=Misc.protect_refs[R(pool_stack,pool)]fin(r,pool.pool)letadd_to_pool~levelty=iflevel>=generic_level||level<=lowest_levelthen()elseletpool=pool_of_levellevel!pool_stackinpool.pool<-ty::pool.pool(**** Some type creators ****)letnewty3~level~scopedesc=letty=proto_newty3~level~scopedescinadd_to_pool~levelty;Transient_expr.type_exprtyletnewty2~leveldesc=newty3~level~scope:Ident.lowest_scopedescletnewgentydesc=newty2~level:generic_leveldescletnewgenvar?name()=newgenty(Tvarname)letnewgenstub~scope=newty3~level:generic_level~scope(TvarNone)(**** Check some types ****)letis_Tvarty=matchget_desctywithTvar_->true|_->falseletis_Tunivarty=matchget_desctywithTunivar_->true|_->falseletis_Tconstrty=matchget_desctywithTconstr_->true|_->falseletis_poly_Tpolyty=matchget_desctywithTpoly(_,_::_)->true|_->falselettype_kind_is_abstractdecl=matchdecl.type_kindwithType_abstract_->true|_->falselettype_origindecl=matchdecl.type_kindwith|Type_abstractorigin->origin|Type_variant_|Type_record_|Type_open->Definitionletlabel_is_polylbl=is_poly_Tpolylbl.lbl_argletdummy_method="*dummy method*"(**** Representative of a type ****)letmerge_fixed_explanationfixed1fixed2=matchfixed1,fixed2with|SomeUnivar_asx,_|_,(SomeUnivar_asx)->x|SomeFixed_privateasx,_|_,(SomeFixed_privateasx)->x|SomeReified_asx,_|_,(SomeReified_asx)->x|SomeRigidasx,_|_,(SomeRigidasx)->x|None,None->Noneletfixed_explanationrow=matchrow_fixedrowwith|Some_asx->x|None->letty=row_morerowinmatchget_desctywith|Tvar_|Tnil->None|Tunivar_->Some(Univarty)|Tconstr(p,_,_)->Some(Reifiedp)|_->assertfalseletis_fixedrow=matchrow_fixedrowwith|None->false|Some_->truelethas_fixed_explanationrow=fixed_explanationrow<>Noneletstatic_rowrow=row_closedrow&&List.for_all(fun(_,f)->matchrow_field_reprfwithReither_->false|_->true)(row_fieldsrow)lethash_variants=letaccu=ref0infori=0toString.lengths-1doaccu:=223*!accu+Char.codes.[i]done;(* reduce to 31 bits *)accu:=!acculand(1lsl31-1);(* make it signed for 64 bits architectures *)if!accu>0x3FFFFFFFthen!accu-(1lsl31)else!acculetproxyty=matchget_desctywith|Tvariantrowwhennot(static_rowrow)->row_morerow|Tobject(ty,_)->letrecproxy_objty=matchget_desctywithTfield(_,_,_,ty)->proxy_objty|Tvar_|Tunivar_|Tconstr_->ty|Tnil->ty|_->assertfalseinproxy_objty|_->ty(**** Utilities for fixed row private types ****)letrow_of_typet=matchget_desctwithTobject(t,_)->letrecget_rowt=matchget_desctwithTfield(_,_,_,t)->get_rowt|_->tinget_rowt|Tvariantrow->row_morerow|_->tlethas_constr_rowt=not(is_Tconstrt)&&is_Tconstr(row_of_typet)letis_row_names=letl=String.lengthsin(* PR#10661: when l=4 and s is "#row", this is not a row name
but the valid #-type name of a class named "row". *)l>4&&String.subs(l-4)4="#row"letis_constr_row~allow_identt=matchget_desctwithTconstr(Path.Pidentid,_,_)whenallow_ident->is_row_name(Ident.nameid)|Tconstr(Path.Pdot(_,s),_,_)->is_row_names|_->false(* TODO: where should this really be *)(* Set row_name in Env, cf. GPR#1204/1329 *)letset_static_row_namedeclpath=matchdecl.type_manifestwithNone->()|Somety->matchget_desctywithTvariantrowwhenstatic_rowrow->letrow=set_row_namerow(Some(path,decl.type_params))inset_type_descty(Tvariantrow)|_->()(**********************************)(* Utilities for type traversal *)(**********************************)letfold_rowfinitrow=letresult=List.fold_left(funinit(_,fi)->matchrow_field_reprfiwith|Rpresent(Somety)->finitty|Reither(_,tl,_)->List.fold_leftfinittl|_->init)init(row_fieldsrow)inmatchget_desc(row_morerow)with|Tvar_|Tunivar_|Tsubst_|Tconstr_|Tnil->beginmatchOption.map(fun(_,l)->List.fold_leftfresultl)(row_namerow)with|None->result|Someresult->resultend|_->assertfalseletiter_rowfrow=fold_row(fun()v->fv)()rowletfold_type_exprfinitty=matchget_desctywithTvar_->init|Tarrow(_,ty1,ty2,_)->letresult=finitty1infresultty2|Ttuplel->List.fold_leftfinitl|Tconstr(_,l,_)->List.fold_leftfinitl|Tobject(ty,{contents=Some(_,p)})->letresult=finittyinList.fold_leftfresultp|Tobject(ty,_)->finitty|Tvariantrow->letresult=fold_rowfinitrowinfresult(row_morerow)|Tfield(_,_,ty1,ty2)->letresult=finitty1infresultty2|Tnil->init|Tlink_|Tsubst_->assertfalse|Tunivar_->init|Tpoly(ty,tyl)->letresult=finittyinList.fold_leftfresulttyl|Tpackage(_,fl)->List.fold_left(funresult(_n,ty)->fresultty)initflletiter_type_exprfty=fold_type_expr(fun()v->fv)()tyletreciter_abbrevf=functionMnil->()|Mcons(_,_,ty,ty',rem)->fty;fty';iter_abbrevfrem|Mlinkrem->iter_abbrevf!remletiter_type_expr_cstr_argsf=function|Cstr_tupletl->List.iterftl|Cstr_recordlbls->List.iter(fund->fd.ld_type)lblsletmap_type_expr_cstr_argsf=function|Cstr_tupletl->Cstr_tuple(List.mapftl)|Cstr_recordlbls->Cstr_record(List.map(fund->{dwithld_type=fd.ld_type})lbls)letiter_type_expr_kindf=function|Type_abstract_->()|Type_variant(cstrs,_)->List.iter(funcd->iter_type_expr_cstr_argsfcd.cd_args;Option.iterfcd.cd_res)cstrs|Type_record(lbls,_)->List.iter(fund->fd.ld_type)lbls|Type_open->()(**********************************)(* Utilities for marking *)(**********************************)letrecmark_typemarkty=iftry_mark_nodemarktytheniter_type_expr(mark_typemark)tyletmark_type_paramsmarkty=iter_type_expr(mark_typemark)ty(**********************************)(* (Object-oriented) iterator *)(**********************************)type'atype_iterators={it_signature:'atype_iterators->signature->unit;it_signature_item:'atype_iterators->signature_item->unit;it_value_description:'atype_iterators->value_description->unit;it_type_declaration:'atype_iterators->type_declaration->unit;it_extension_constructor:'atype_iterators->extension_constructor->unit;it_module_declaration:'atype_iterators->module_declaration->unit;it_modtype_declaration:'atype_iterators->modtype_declaration->unit;it_class_declaration:'atype_iterators->class_declaration->unit;it_class_type_declaration:'atype_iterators->class_type_declaration->unit;it_functor_param:'atype_iterators->functor_parameter->unit;it_module_type:'atype_iterators->module_type->unit;it_class_type:'atype_iterators->class_type->unit;it_type_kind:'atype_iterators->type_decl_kind->unit;it_do_type_expr:'atype_iterators->'a;it_type_expr:'atype_iterators->type_expr->unit;it_path:Path.t->unit;}typetype_iterators_full=(type_expr->unit)type_iteratorstypetype_iterators_without_type_expr=(unit->unit)type_iteratorslettype_iterators_without_type_expr=letit_signatureit=List.iter(it.it_signature_itemit)andit_signature_itemit=functionSig_value(_,vd,_)->it.it_value_descriptionitvd|Sig_type(_,td,_,_)->it.it_type_declarationittd|Sig_typext(_,td,_,_)->it.it_extension_constructorittd|Sig_module(_,_,md,_,_)->it.it_module_declarationitmd|Sig_modtype(_,mtd,_)->it.it_modtype_declarationitmtd|Sig_class(_,cd,_,_)->it.it_class_declarationitcd|Sig_class_type(_,ctd,_,_)->it.it_class_type_declarationitctdandit_value_descriptionitvd=it.it_type_expritvd.val_typeandit_type_declarationittd=List.iter(it.it_type_exprit)td.type_params;Option.iter(it.it_type_exprit)td.type_manifest;it.it_type_kindittd.type_kindandit_extension_constructorittd=it.it_pathtd.ext_type_path;List.iter(it.it_type_exprit)td.ext_type_params;iter_type_expr_cstr_args(it.it_type_exprit)td.ext_args;Option.iter(it.it_type_exprit)td.ext_ret_typeandit_module_declarationitmd=it.it_module_typeitmd.md_typeandit_modtype_declarationitmtd=Option.iter(it.it_module_typeit)mtd.mtd_typeandit_class_declarationitcd=List.iter(it.it_type_exprit)cd.cty_params;it.it_class_typeitcd.cty_type;Option.iter(it.it_type_exprit)cd.cty_new;it.it_pathcd.cty_pathandit_class_type_declarationitctd=List.iter(it.it_type_exprit)ctd.clty_params;it.it_class_typeitctd.clty_type;it.it_pathctd.clty_pathandit_functor_paramit=function|Unit->()|Named(_,mt)->it.it_module_typeitmtandit_module_typeit=functionMty_identp|Mty_aliasp->it.it_pathp|Mty_for_hole->()|Mty_signaturesg->it.it_signatureitsg|Mty_functor(p,mt)->it.it_functor_paramitp;it.it_module_typeitmtandit_class_typeit=functionCty_constr(p,tyl,cty)->it.it_pathp;List.iter(it.it_type_exprit)tyl;it.it_class_typeitcty|Cty_signaturecs->it.it_type_expritcs.csig_self;it.it_type_expritcs.csig_self_row;Vars.iter(fun_(_,_,ty)->it.it_type_expritty)cs.csig_vars;Meths.iter(fun_(_,_,ty)->it.it_type_expritty)cs.csig_meths|Cty_arrow(_,ty,cty)->it.it_type_expritty;it.it_class_typeitctyandit_type_kinditkind=iter_type_expr_kind(it.it_type_exprit)kindandit_path_p=()in{it_path;it_type_expr=(fun__->());it_do_type_expr=(fun__->());it_type_kind;it_class_type;it_functor_param;it_module_type;it_signature;it_class_type_declaration;it_class_declaration;it_modtype_declaration;it_module_declaration;it_extension_constructor;it_type_declaration;it_value_description;it_signature_item;}lettype_iteratorsmark=letit_type_expritty=iftry_mark_nodemarktythenit.it_do_type_exprittyandit_do_type_expritty=iter_type_expr(it.it_type_exprit)ty;matchget_desctywithTconstr(p,_,_)|Tobject(_,{contents=Some(p,_)})|Tpackage(p,_)->it.it_pathp|Tvariantrow->Option.iter(fun(p,_)->it.it_pathp)(row_namerow)|_->()in{type_iterators_without_type_exprwithit_type_expr;it_do_type_expr}(**********************************)(* Utilities for copying *)(**********************************)letcopy_rowffixedrowkeepmore=letRow{fields=orig_fields;fixed=orig_fixed;closed;name=orig_name}=row_reprrowinletfields=List.map(fun(l,fi)->l,matchrow_field_reprfiwith|Rpresentoty->rf_present(Option.mapfoty)|Reither(c,tl,m)->letuse_ext_of=ifkeepthenSomefielseNoneinletm=ifis_fixedrowthenfixedelseminlettl=List.mapftlinrf_eithertl?use_ext_of~no_arg:c~matched:m|Rabsent->rf_absent)orig_fieldsinletname=matchorig_namewith|None->None|Some(path,tl)->Some(path,List.mapftl)inletfixed=iffixedthenorig_fixedelseNoneincreate_row~fields~more~fixed~closed~nameletcopy_commuc=ifis_commu_okcthencommu_okelsecommu_var()letreccopy_type_desc?(keep_names=false)f=functionTvar_asty->ifkeep_namesthentyelseTvarNone|Tarrow(p,ty1,ty2,c)->Tarrow(p,fty1,fty2,copy_commuc)|Ttuplel->Ttuple(List.mapfl)|Tconstr(p,l,_)->Tconstr(p,List.mapfl,refMnil)|Tobject(ty,{contents=Some(p,tl)})->Tobject(fty,ref(Some(p,List.mapftl)))|Tobject(ty,_)->Tobject(fty,refNone)|Tvariant_->assertfalse(* too ambiguous *)|Tfield(p,k,ty1,ty2)->Tfield(p,field_kind_internal_reprk,fty1,fty2)(* the kind is kept shared, with indirections removed for performance *)|Tnil->Tnil|Tlinkty->copy_type_descf(get_descty)|Tsubst_->assertfalse|Tunivar_asty->ty(* always keep the name *)|Tpoly(ty,tyl)->lettyl=List.mapftylinTpoly(fty,tyl)|Tpackage(p,fl)->Tpackage(p,List.map(fun(n,ty)->(n,fty))fl)(* TODO: rename to [module Copy_scope] *)moduleFor_copy:sigtypecopy_scopevalredirect_desc:copy_scope->type_expr->type_desc->unitvalwith_scope:(copy_scope->'a)->'aend=structtypecopy_scope={mutablesaved_desc:(transient_expr*type_desc)list;(* Save association of generic nodes with their description. *)}letredirect_desccopy_scopetydesc=letty=Transient_expr.reprtyincopy_scope.saved_desc<-(ty,ty.desc)::copy_scope.saved_desc;Transient_expr.set_desctydesc(* Restore type descriptions. *)letcleanup{saved_desc;_}=List.iter(fun(ty,desc)->Transient_expr.set_desctydesc)saved_descletwith_scopef=letscope={saved_desc=[]}inFun.protect~finally:(fun()->cleanupscope)(fun()->fscope)end(*******************************************)(* Memorization of abbreviation expansion *)(*******************************************)(* Search whether the expansion has been memorized. *)letlte_publicp1p2=(* Private <= Public *)matchp1,p2with|Private,_|_,Public->true|Public,Private->falseletrecfind_expansprivp1=functionMnil->None|Mcons(priv',p2,_ty0,ty,_)whenlte_publicprivpriv'&&Path.samep1p2->Somety|Mcons(_,_,_,_,rem)->find_expansprivp1rem|Mlink{contents=rem}->find_expansprivp1rem(* debug: check for cycles in abbreviation. only works with -principal
let rec check_expans visited ty =
let ty = repr ty in
assert (not (List.memq ty visited));
match ty.desc with
Tconstr (path, args, abbrev) ->
begin match find_expans path !abbrev with
Some ty' -> check_expans (ty :: visited) ty'
| None -> ()
end
| _ -> ()
*)letmemo=s_ref[](* Contains the list of saved abbreviation expansions. *)letcleanup_abbrev()=(* Remove all memorized abbreviation expansions. *)List.iter(funabbr->abbr:=Mnil)!memo;memo:=[]letmemorize_abbrevmemprivpathvv'=(* Memorize the expansion of an abbreviation. *)mem:=Mcons(priv,path,v,v',!mem);(* check_expans [] v; *)memo:=mem::!memoletrecforget_abbrev_recmempath=matchmemwithMnil->mem|Mcons(_,path',_,_,rem)whenPath.samepathpath'->rem|Mcons(priv,path',v,v',rem)->Mcons(priv,path',v,v',forget_abbrev_recrempath)|Mlinkmem'->mem':=forget_abbrev_rec!mem'path;raiseExitletforget_abbrevmempath=trymem:=forget_abbrev_rec!mempathwithExit->()(* debug: check for invalid abbreviations
let rec check_abbrev_rec = function
Mnil -> true
| Mcons (_, ty1, ty2, rem) ->
repr ty1 != repr ty2
| Mlink mem' ->
check_abbrev_rec !mem'
let check_memorized_abbrevs () =
List.for_all (fun mem -> check_abbrev_rec !mem) !memo
*)(* Re-export backtrack *)letsnapshot=snapshotletbacktrack=backtrack~cleanup_abbrev(**********************************)(* Utilities for labels *)(**********************************)letis_optional=functionOptional_->true|_->falseletlabel_name=functionNolabel->""|Labelleds|Optionals->sletprefixed_label_name=functionNolabel->""|Labelleds->"~"^s|Optionals->"?"^sletrecextract_label_auxhdl=function|[]->None|(l',tasp)::ls->iflabel_namel'=lthenSome(l',t,hd<>[],List.rev_appendhdls)elseextract_label_aux(p::hd)llsletextract_labellls=extract_label_aux[]lls(*******************************)(* Operations on class types *)(*******************************)letrecsignature_of_class_type=functionCty_constr(_,_,cty)->signature_of_class_typecty|Cty_signaturesign->sign|Cty_arrow(_,_,cty)->signature_of_class_typectyletrecclass_bodycty=matchctywithCty_constr_->cty(* Only class bodies can be abbreviated *)|Cty_signature_->cty|Cty_arrow(_,_,cty)->class_bodycty(* Fully expand the head of a class type *)letrecscrape_class_type=functionCty_constr(_,_,cty)->scrape_class_typecty|cty->ctyletrecclass_type_arity=functionCty_constr(_,_,cty)->class_type_aritycty|Cty_signature_->0|Cty_arrow(_,_,cty)->1+class_type_arityctyletrecabbreviate_class_typepathparamscty=matchctywithCty_constr(_,_,_)|Cty_signature_->Cty_constr(path,params,cty)|Cty_arrow(l,ty,cty)->Cty_arrow(l,ty,abbreviate_class_typepathparamscty)letself_typecty=(signature_of_class_typecty).csig_selfletself_type_rowcty=(signature_of_class_typecty).csig_self_row(* Return the methods of a class signature *)letmethodssign=Meths.fold(funname_l->name::l)sign.csig_meths[](* Return the virtual methods of a class signature *)letvirtual_methodssign=Meths.fold(funname(_priv,vr,_ty)l->matchvrwith|Virtual->name::l|Concrete->l)sign.csig_meths[](* Return the concrete methods of a class signature *)letconcrete_methodssign=Meths.fold(funname(_priv,vr,_ty)s->matchvrwith|Virtual->s|Concrete->MethSet.addnames)sign.csig_methsMethSet.empty(* Return the public methods of a class signature *)letpublic_methodssign=Meths.fold(funname(priv,_vr,_ty)l->matchprivwith|Mprivate_->l|Mpublic->name::l)sign.csig_meths[](* Return the instance variables of a class signature *)letinstance_varssign=Vars.fold(funname_l->name::l)sign.csig_vars[](* Return the virtual instance variables of a class signature *)letvirtual_instance_varssign=Vars.fold(funname(_mut,vr,_ty)l->matchvrwith|Virtual->name::l|Concrete->l)sign.csig_vars[](* Return the concrete instance variables of a class signature *)letconcrete_instance_varssign=Vars.fold(funname(_mut,vr,_ty)s->matchvrwith|Virtual->s|Concrete->VarSet.addnames)sign.csig_varsVarSet.emptyletmethod_typelabelsign=matchMeths.findlabelsign.csig_methswith|(_,_,ty)->ty|exceptionNot_found->assertfalseletinstance_variable_typelabelsign=matchVars.findlabelsign.csig_varswith|(_,_,ty)->ty|exceptionNot_found->assertfalse(**********)(* Misc *)(**********)(**** Type information getter ****)letcstr_type_pathcstr=matchget_desccstr.cstr_reswith|Tconstr(p,_,_)->p|_->assertfalse