Skip to content
This repository
Newer
Older
100644 274 lines (215 sloc) 8.298 kb
fccc6851 » MLstate
2011-06-21 Initial open-source release
1 (*
2 Copyright © 2011 MLstate
3
4 This file is part of OPA.
5
6 OPA is free software: you can redistribute it and/or modify it under the
7 terms of the GNU Affero General Public License, version 3, as published by
8 the Free Software Foundation.
9
10 OPA is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
13 more details.
14
15 You should have received a copy of the GNU Affero General Public License
16 along with OPA. If not, see <http://www.gnu.org/licenses/>.
17 *)
18
19 (**
20 Getting line number and pos in line from a global char offset in a file.
21
22 @author Rudy Sicard
23 @author David Rajchenbach-Teller
24 @author Mathieu Barbin
25 *)
26
27 (**
28 This implementation works with a cache mechanism.
29 You should first store files, and then you can perform some call to the API.
30
31 Originally, these functionnalities was dispesed and diverging in
32
33 + Trx_runtime
34 + QmlLoc
35 + OpaParser
36
37 This module is there to group once for all, all functionnality related to
38 errors reporting from a source file, with line location, and nice colored citations.
39
40 TODO(proposition):
41 add a support in the citation part to cache what citation have already be done.
42 and a function to reset this cache, to correct the probleme of multiple citation.
43 *)
44
45 (** {6 Alias for common types} *)
46
47 (** Just for the lisibility of the interface *)
48 (** *)
49 type filename = string
50 type content = string
51 type absolute_char_offset = int
52 type line_number = int
53 type column_number = int
54
55 (** {6 Caching mechanisme} *)
56
57 (** [add_file filename content] Add a file to parsed files *)
58 val add_file : filename -> content -> unit
59
60 (** [get_file_content filename] Returns content of the file if is present.
61 @raise Not_found if the file in not in the cache table *)
62 val get_file_content : filename -> content
63
64 (** Get (line number, pos in line) from a filename and an absolute position.
65 @raise Not_found if the file is not in the cache table *)
66 val get_pos : filename -> absolute_char_offset -> line_number * column_number
67
68 (** Given line and column number produces a string of the shape "line XX, column XX" *)
69 val get_pos_string : line_number * column_number -> string
70
71 (** Get (line number, pos in line) for a given file content.
72 WARNING The content will not be cached, so use only for single requests *)
73 val get_pos_no_cache : content -> absolute_char_offset -> line_number * column_number
74
75 (** Get the offset of the current line. This is the identity if no newline are detected after *)
76 val get_line : filename -> absolute_char_offset -> absolute_char_offset * line_number
77
78 (** Get the offset of the next newline. This is the identity if no newline are detected after *)
79 val get_next_line : filename -> absolute_char_offset -> absolute_char_offset * line_number
80
81 (**
82 Get the global begin and end offsets from the line number
83 @raise Not_found if no such line, or if the file is not cached
84 *)
85 val line_position : filename -> line_number -> absolute_char_offset * absolute_char_offset
86
87 (** remove a file from the cached files *)
88 val uncache : filename -> unit
89
90 (** remova all files from the cached files *)
91 val clear : unit -> unit
92
93 (** {6 Position tracking} *)
94
95 (**
96 A segment in a file
97 *)
98 type range = {
99 start : absolute_char_offset ;
100 stop : absolute_char_offset ;
101 }
102
103 (**
104 Several segments in a file.
105 Assert : if you use only the API for building pos (private),
106 you can be sure that there is no overlap between ranges
107 *)
108 type filerange = {
109 filename : filename ;
110 ranges : range HdList.t
111 }
112
113 (**
114 The type of a position in source code.
115
116 + [Builtin] : No position, inserted by the compiler (precise the pass)
117 Any error at [Builtin] is the result of an internal error and should be treated as a failure.
118 + [Files] : This come for at least one file, with at least one range.
119
120 The private cache is used for speeding up some redondant request
121 *)
122 type private_cache
123
124 type pos = private
125 | Builtin of string
126 | Files of filerange HdList.t * private_cache
127
128 (**
129 Build a new pos from nothing. Use to replace the Builtin value,
130 you should at least say what pass insert this position.
131 *)
132 val nopos : string -> pos
133
134 (**
135 Get at least one of filenames present in a pos.
136 returns ["builtin_pass"] if there is no files
137 *)
138 val get_file : pos -> filename
139
140 (**
141 Get one location of the pos.
142 returns ["builtin_pass", 0] if there is no files
143 *)
144 val get_one_loc : pos -> filename * line_number
145
146 (**
147 Get the start of the first filename found in a pos.
148 returns [0] if there is no file in the pos
149 *)
150 val get_first_char : pos -> absolute_char_offset
151
152 (**
153 Build a new pos from a filename and a range.
154 @raise Invalid argument if stop < start
155 *)
156 val make_pos : filename -> absolute_char_offset -> absolute_char_offset -> pos
157
158 (**
159 In some cases, you do not have the global offset,
160 but just the line number. Build a position corresponding
161 to the full line.
162 *)
163 val make_pos_from_line : filename -> line_number -> pos
164
165 (**
166 Merge ranges from filenames.
167 The positions should contain only exactly one range and merging
168 just gives you the position containing the smallest range covering
169 them
170 *)
171 val merge_pos_for_parser : pos -> pos -> pos
172
173 (**
174 Merge ranges from filenames.
175 If there is at least one filename, there no more Builtin are preserved.
176 *)
177 val merge_pos : pos -> pos -> pos
178 val merge_pos_list : pos list -> pos
179
180 (**
181 Return [true] only if there is no filename in the pos. (Builtin)
182 *)
183 val is_empty : pos -> bool
184
185 (**
186 Build a string regrouping the location present in the pos.
187 The syntax is emacs tuareg-mode frienly.
188 There is just one difference, [FilePos] count char index from [0], where
189 emacs count from [1] for global chars. For line number, and column, it
190 is the same convention.
191 *)
192 val to_string : pos -> string
193
194 (**
195 The same function, with a pp interface.
196 @deprecated, use [pp] instead
197 *)
198 val pp_pos : Format.formatter -> pos -> unit
199
200 (**
201 Printer for pos, with a format interface.
202 *)
203 val pp : Format.formatter -> pos -> unit
204
205 (**
206 Print the list of files in a position.
207 *)
208 val pp_files : Format.formatter -> pos -> unit
209
210
211 (** {6 Deprecated API} *)
212
213 (**
214 Used some how by the old qml, will be delated as soon as we can.
215 DO NOT USE IT IN NEW CODE
216 *)
217 val to_old_pos_many : pos -> (int*int) StringMap.t
218 val to_old_pos : (unit -> string * int * int) -> pos -> string *int * int
219
220
221 (** {6 Citations} *)
222
223 (**
224 This is used for printing citation of the source code from a position.
225 It is possible to parametrize the citation with some parameters.
226
227 {[
228 Citation:
229
230 x =
231 y = 5 + "toto"
232 ^^^^^^
233 z = y * 5
234 z + y
235
236 This expression has type string
237 but the context expected an expression of type int
238 ]}
239
240 *)
241
242 (**
243 Parameters are :
244 + [truncate_lines] : by printing the citation, truncate the lines with a length greater than the parameter.
245 by default, it is [Some 80]. Principally, it avoid that the message is not visible. The lines containing
246 the range to highlight are not truncated.
247 + [length_before] : the maximal number of lines to print before the first line contained in the range
248 + [length_after] : the maximal number of lines to print after the first line contained in the range
249 default is [5]
250 + [length_between] : the maximal number of lines to print between to range of the file.
251 default is [5]
252 + [color] choose the color for highlighting the range. Default is [Some `red].
253 + [max_length_citation] eventually truncate the highlighted range if too long. Default is [Some 200].
254 It replace the midle part of the range by ["[...]"].
255 *)
256 type options = {
257 truncate_lines : int option ;
258 lines_before : int ;
259 lines_after : int ;
260 lines_between : int ;
261 color : Ansi.color option ;
262 max_length_citation : int option ;
263 }
264
265 val default_options : options
266
267 (** The function to print a citation *)
268 val citation : ?options:options -> Format.formatter -> pos -> unit
269
270 (** The default citation for using it directly in Format.fprintf *)
271 val pp_citation : Format.formatter -> pos -> unit
272
273 (** print the contents of the private table *)
274 val debug : unit -> unit
Something went wrong with that request. Please try again.