123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198(**************************************************************************)(* *)(* OCaml *)(* *)(* Damien Doligez, projet Moscova, INRIA Rocquencourt *)(* *)(* Copyright 2003 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. *)(* *)(**************************************************************************)(* Recording and dumping (partial) type information *)(*
We record all types in a list as they are created.
This means we can dump type information even if type inference fails,
which is extremely important, since type information is most
interesting in case of errors.
*)openAnnotopenLexingopenLocationopenTypedtreeletoutput_intoci=output_stringoc(Int.to_stringi)typeannotation=|Ti_pat:'kpattern_category*'kgeneral_pattern->annotation|Ti_exprofexpression|Ti_classofclass_expr|Ti_modofmodule_expr|An_callofLocation.t*Annot.call|An_identofLocation.t*string*Annot.identletget_locationti=matchtiwith|Ti_pat(_,p)->p.pat_loc|Ti_expre->e.exp_loc|Ti_classc->c.cl_loc|Ti_modm->m.mod_loc|An_call(l,_k)->l|An_ident(l,_s,_k)->lletannotations=ref([]:annotationlist)letphrases=ref([]:Location.tlist)letrecordti=if!Clflags.annotations&¬(get_locationti).Location.loc_ghostthenannotations:=ti::!annotationsletrecord_phraseloc=if!Clflags.annotationsthenphrases:=loc::!phrases(* comparison order:
the intervals are sorted by order of increasing upper bound
same upper bound -> sorted by decreasing lower bound
*)letcmp_loc_inner_firstloc1loc2=matchcompareloc1.loc_end.pos_cnumloc2.loc_end.pos_cnumwith|0->compareloc2.loc_start.pos_cnumloc1.loc_start.pos_cnum|x->xletcmp_ti_inner_firstti1ti2=cmp_loc_inner_first(get_locationti1)(get_locationti2)letprint_positionpppos=ifpos=dummy_posthenoutput_stringpp"--"elsebeginoutput_charpp'\"';output_stringpp(String.escapedpos.pos_fname);output_stringpp"\" ";output_intpppos.pos_lnum;output_charpp' ';output_intpppos.pos_bol;output_charpp' ';output_intpppos.pos_cnum;endletprint_locationpploc=print_positionpploc.loc_start;output_charpp' ';print_positionpploc.loc_endletsort_filter_phrases()=letph=List.sort(funxy->cmp_loc_inner_firstyx)!phrasesinletrecloopaccucurl=matchlwith|[]->accu|loc::t->ifcur.loc_start.pos_cnum<=loc.loc_start.pos_cnum&&cur.loc_end.pos_cnum>=loc.loc_end.pos_cnumthenloopaccucurtelseloop(loc::accu)loctinphrases:=loop[]Location.nonephletrecprinttyp_reset_maybeloc=match!phraseswith|cur::twhencur.loc_start.pos_cnum<=loc.loc_start.pos_cnum->Out_type.reset();phrases:=t;printtyp_reset_maybeloc;|_->()letcall_kind_stringk=matchkwith|Tail->"tail"|Stack->"stack"|Inline->"inline"letprint_ident_annotppstrk=matchkwith|Idefl->output_stringpp"def ";output_stringppstr;output_charpp' ';print_locationppl;output_charpp'\n'|Iref_internall->output_stringpp"int_ref ";output_stringppstr;output_charpp' ';print_locationppl;output_charpp'\n'|Iref_external->output_stringpp"ext_ref ";output_stringppstr;output_charpp'\n'(* The format of the annotation file is documented in emacs/caml-types.el. *)letprint_infoppprev_locti=matchtiwith|Ti_class_|Ti_mod_->prev_loc|Ti_pat(_,{pat_loc=loc;pat_type=typ;pat_env=env})|Ti_expr{exp_loc=loc;exp_type=typ;exp_env=env}->ifloc<>prev_locthenbeginprint_locationpploc;output_charpp'\n'end;output_stringpp"type(\n";printtyp_reset_maybeloc;Format.pp_print_stringFormat.str_formatter" ";Printtyp.wrap_printing_env~error:falseenv(fun()->Printtyp.shared_type_schemeFormat.str_formattertyp);(* (fun () -> Printtyp.shared_type_scheme Format.str_formatter typ); *)Format.pp_print_newlineFormat.str_formatter();lets=Format.flush_str_formatter()inoutput_stringpps;output_stringpp")\n";loc|An_call(loc,k)->ifloc<>prev_locthenbeginprint_locationpploc;output_charpp'\n'end;output_stringpp"call(\n ";output_stringpp(call_kind_stringk);output_stringpp"\n)\n";loc|An_ident(loc,str,k)->ifloc<>prev_locthenbeginprint_locationpploc;output_charpp'\n'end;output_stringpp"ident(\n ";print_ident_annotppstrk;output_stringpp")\n";locletget_info()=letinfo=List.fast_sortcmp_ti_inner_first!annotationsinannotations:=[];infoletdumpfilename=if!Clflags.annotationsthenbeginletdo_dump_temp_filenamepp=letinfo=get_info()insort_filter_phrases();ignore(List.fold_left(print_infopp)Location.noneinfo)inbeginmatchfilenamewith|None->do_dump""stdout|Somefilename->Misc.output_to_file_via_temporary~mode:[Open_text]filenamedo_dumpend;phrases:=[];endelsebeginannotations:=[];end