1 (***********************************************************************)
5 (* Damien Doligez, projet Moscova, INRIA Rocquencourt *)
7 (* Copyright 2003 Institut National de Recherche en Informatique et *)
8 (* en Automatique. All rights reserved. This file is distributed *)
9 (* under the terms of the Q Public License version 1.0. *)
11 (***********************************************************************)
15 (* Recording and dumping (partial) type information *)
18 We record all types in a list as they are created.
19 This means we can dump type information even if type inference fails,
20 which is extremely important, since type information is most
21 interesting in case of errors.
31 | Ti_expr
of expression
32 | Ti_class
of class_expr
33 | Ti_mod
of module_expr
39 | Ti_expr e
-> e
.exp_loc
40 | Ti_class c
-> c
.cl_loc
41 | Ti_mod m
-> m
.mod_loc
44 let type_info = ref ([] : type_info list
);;
45 let phrases = ref ([] : Location.t list
);;
48 if !Clflags.save_types
&& not
(get_location ti
).Location.loc_ghost
then
49 type_info := ti
:: !type_info
52 let record_phrase loc
=
53 if !Clflags.save_types
then phrases := loc
:: !phrases;
57 the intervals are sorted by order of increasing upper bound
58 same upper bound -> sorted by decreasing lower bound
60 let cmp_loc_inner_first loc1 loc2
=
61 match compare loc1
.loc_end
.pos_cnum loc2
.loc_end
.pos_cnum
with
62 | 0 -> compare loc2
.loc_start
.pos_cnum loc1
.loc_start
.pos_cnum
65 let cmp_ti_inner_first ti1 ti2
=
66 cmp_loc_inner_first (get_location ti1
) (get_location ti2
)
69 let print_position pp pos
=
70 fprintf pp
"%S %d %d %d" pos
.pos_fname pos
.pos_lnum pos
.pos_bol pos
.pos_cnum
;
73 let sort_filter_phrases () =
74 let ph = List.sort
(fun x y
-> cmp_loc_inner_first y x
) !phrases in
75 let rec loop accu cur l
=
79 if cur
.loc_start
.pos_cnum
<= loc
.loc_start
.pos_cnum
80 && cur
.loc_end
.pos_cnum
>= loc
.loc_end
.pos_cnum
82 else loop (loc
:: accu
) loc t
84 phrases := loop [] Location.none
ph;
87 let rec printtyp_reset_maybe loc
=
89 | cur
:: t
when cur
.loc_start
.pos_cnum
<= loc
.loc_start
.pos_cnum
->
92 printtyp_reset_maybe loc
;
97 (* The format of the annotation file is documented in emacs/caml-types.el. *)
99 let print_info pp ti
=
101 | Ti_class _
| Ti_mod _
-> ()
102 | Ti_pat
{pat_loc
= loc
; pat_type
= typ
}
103 | Ti_expr
{exp_loc
= loc
; exp_type
= typ
} ->
104 print_position pp loc
.loc_start
;
106 print_position pp loc
.loc_end
;
107 fprintf pp
"@.type(@. ";
108 printtyp_reset_maybe loc
;
109 Printtyp.mark_loops typ
;
110 Printtyp.type_sch pp typ
;
115 let info = List.fast_sort
cmp_ti_inner_first !type_info in
121 if !Clflags.save_types
then begin
122 let info = get_info () in
123 let pp = formatter_of_out_channel
(open_out filename
) in
124 sort_filter_phrases ();
125 List.iter
(print_info pp) info;