Skip to content

Commit aaac9bb

Browse files
committed
Less accurate but more efficient handling of large single-file source locations
1 parent 288b89b commit aaac9bb

File tree

1 file changed

+28
-14
lines changed

1 file changed

+28
-14
lines changed

src/lsp/cobol_preproc/src_overlay.ml

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,18 @@ let leftmost_limit_in ~filename ctx =
9999
| res -> res
100100
end ctx.right_of None
101101

102-
(** Returns a source location that spans between two given limits; returns a
103-
valid pointwise location if the two given limits are physically equal. *)
102+
(** Internal flag to enable or disable the construction by [join_limits ctx (s,
103+
e)] of composed source locations from every registered limits from [s] to
104+
[e]. If [true], a call for which [s, e] is a valid lexical location [l]
105+
will return [l]; this means some information on the source text
106+
manipulations that resulted in some of the constituent tokens may not be
107+
represented by [l] in this case. Setting [simplified_join = false] computes
108+
[l] more accurately, but is also potentielly more expensive. *)
109+
let simplified_join = true
110+
111+
(** [join_limits ctx (s, e)] returns a source location that spans between two
112+
given limits; returns a valid pointwise location if the two given limits are
113+
physically equal. *)
104114
let join_limits: manager -> limit * limit -> srcloc = fun ctx (s, e) ->
105115
let pointwise l = (* pointwise: ensure this is not a virtual limit *)
106116
let pos =
@@ -134,18 +144,22 @@ let join_limits: manager -> limit * limit -> srcloc = fun ctx (s, e) ->
134144
(* Printexc.(print_raw_backtrace Stdlib.stderr @@ get_callstack 10); *)
135145
loc
136146
in
137-
(* first attempt assumes proper token limits: `s` is a left and `e` is a right
138-
of tokens *)
139-
try try_limits (s, e) with Not_found ->
140-
(* try assuming `s` is an end of token *)
141-
try try_limits (Links.find ctx.over_right_gap s, e) with Not_found ->
142-
if s.pos_cnum = 0 (* potential special case with left-position forged by the
143-
parser: retry with leftmost limit if it differs from
144-
s *)
145-
then match leftmost_limit_in ~filename:s.pos_fname ctx with
146-
| Some l when l != s -> try_limits (l, e) (* physical equality is enough *)
147-
| Some _ | None -> join_failure (s, e)
148-
else join_failure (s, e)
147+
if simplified_join && not (Limit.is_virtual s || Limit.is_virtual e) &&
148+
s.pos_fname = e.pos_fname
149+
then Cobol_common.Srcloc.raw (s, e) (* Note: we may loose area-a info here *)
150+
else
151+
(* first attempt assumes proper token limits: `s` is a left and `e` is a
152+
right of tokens *)
153+
try try_limits (s, e) with Not_found ->
154+
(* try assuming `s` is an end of token *)
155+
try try_limits (Links.find ctx.over_right_gap s, e) with Not_found ->
156+
if s.pos_cnum = 0 (* potential special case with left-position forged by
157+
the parser: retry with leftmost limit if it differs
158+
from s *)
159+
then match leftmost_limit_in ~filename:s.pos_fname ctx with
160+
| Some l when l != s -> try_limits (l, e) (* physical equality is enough *)
161+
| Some _ | None -> join_failure (s, e)
162+
else join_failure (s, e)
149163

150164
module New_manager (Id: sig val name: string end) : MANAGER = struct
151165
let ctx = new_manager Id.name

0 commit comments

Comments
 (0)