Source file location_aux.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
open Std
type t
= Location.t
= { loc_start: Lexing.position; loc_end: Lexing.position; loc_ghost: bool }
let compare (l1: t) (l2: t) =
match Lexing.compare_pos l1.loc_start l2.loc_start with
| (-1 | 1) as r -> r
| 0 -> Lexing.compare_pos l1.loc_end l2.loc_end
| _ -> assert false
let compare_pos pos loc =
if Lexing.compare_pos pos loc.Location.loc_start < 0 then
-1
else if Lexing.compare_pos pos loc.Location.loc_end > 0 then
1
else
0
let included ~into:parent_loc child_loc =
Lexing.compare_pos child_loc.loc_start parent_loc.loc_start >= 0 &&
Lexing.compare_pos parent_loc.loc_end child_loc.loc_end >= 0
let overlap_with_range (start, stop) loc =
let a = Lexing.compare_pos start loc.loc_end
and b = Lexing.compare_pos stop loc.loc_start in
a <= 0 && b >= 0 || a >= 0 && b <= 0
let union l1 l2 =
if l1 = Location.none then l2
else if l2 = Location.none then l1
else {
Location.
loc_start = Lexing.min_pos l1.Location.loc_start l2.Location.loc_start;
loc_end = Lexing.max_pos l1.Location.loc_end l2.Location.loc_end;
loc_ghost = l1.Location.loc_ghost && l2.Location.loc_ghost;
}
let extend l1 l2 =
if l1 = Location.none then l2
else if l2 = Location.none then l1
else {
Location.
loc_start = Lexing.min_pos l1.Location.loc_start l2.Location.loc_start;
loc_end = Lexing.max_pos l1.Location.loc_end l2.Location.loc_end;
loc_ghost = l1.Location.loc_ghost;
}
(** Filter valid errors, log invalid ones *)
let prepare_errors exns =
List.filter_map exns
~f:(fun exn ->
match Location.error_of_exn exn with
| None ->
Logger.log ~section:"Mreader" ~title:"errors"
"Location.error_of_exn (%a) = None"
(fun () -> Printexc.to_string) exn;
None
| Some `Already_displayed -> None
| Some (`Ok err) -> Some err
)
let print () {Location. loc_start; loc_end; loc_ghost} =
let l1, c1 = Lexing.split_pos loc_start in
let l2, c2 = Lexing.split_pos loc_end in
sprintf "%d:%d-%d:%d%s"
l1 c1 l2 c2 (if loc_ghost then "{ghost}" else "")
let print_loc f () {Location. txt; loc} =
sprintf "%a@%a" f txt print loc
let is_relaxed_location = function
| { Location. txt = "merlin.relaxed-location" | "merlin.loc"; _ } -> true
| _ -> false