Skip to content

Commit 67eaab2

Browse files
authored
Cmts.preserve: improve API (#1763)
* Cmts: use a shallow copy instead of remove flag The `remove` field is only used within `preserve`. Instead of setting it, we can first do a copy of the structure and use it there. * Cmts.preserve: operate on original value
1 parent 6620833 commit 67eaab2

File tree

3 files changed

+47
-43
lines changed

3 files changed

+47
-43
lines changed

lib/Cmts.ml

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,16 @@ type t =
2121
; mutable cmts_after: Cmt.t Multimap.M(Location).t
2222
; mutable cmts_within: Cmt.t Multimap.M(Location).t
2323
; source: Source.t
24-
; mutable remaining: Set.M(Location).t
25-
; remove: bool }
24+
; mutable remaining: Set.M(Location).t }
25+
26+
let copy {debug; cmts_before; cmts_after; cmts_within; source; remaining} =
27+
{debug; cmts_before; cmts_after; cmts_within; source; remaining}
28+
29+
let restore src ~into =
30+
into.cmts_before <- src.cmts_before ;
31+
into.cmts_after <- src.cmts_after ;
32+
into.cmts_within <- src.cmts_within ;
33+
into.remaining <- src.remaining
2634

2735
let update_remaining t ~f = t.remaining <- f t.remaining
2836

@@ -199,26 +207,24 @@ let rec place t loc_tree ?prev_loc locs cmts =
199207

200208
(** Relocate comments, for Ast transformations such as sugaring. *)
201209
let relocate (t : t) ~src ~before ~after =
202-
if t.remove then (
203-
if t.debug then
204-
Caml.Format.eprintf "relocate %a to %a and %a@\n%!" Location.fmt src
205-
Location.fmt before Location.fmt after ;
206-
let merge_and_sort x y =
207-
List.rev_append x y
208-
|> List.sort
209-
~compare:(Comparable.lift Location.compare_start ~f:Cmt.loc)
210-
in
211-
update_cmts t `Before
212-
~f:(Multimap.update_multi ~src ~dst:before ~f:merge_and_sort) ;
213-
update_cmts t `After
214-
~f:(Multimap.update_multi ~src ~dst:after ~f:merge_and_sort) ;
215-
update_cmts t `Within
216-
~f:(Multimap.update_multi ~src ~dst:after ~f:merge_and_sort) ;
217-
if t.debug then
218-
update_remaining t ~f:(fun s ->
219-
let s = Set.remove s src in
220-
let s = Set.add s after in
221-
Set.add s before ) )
210+
if t.debug then
211+
Caml.Format.eprintf "relocate %a to %a and %a@\n%!" Location.fmt src
212+
Location.fmt before Location.fmt after ;
213+
let merge_and_sort x y =
214+
List.rev_append x y
215+
|> List.sort ~compare:(Comparable.lift Location.compare_start ~f:Cmt.loc)
216+
in
217+
update_cmts t `Before
218+
~f:(Multimap.update_multi ~src ~dst:before ~f:merge_and_sort) ;
219+
update_cmts t `After
220+
~f:(Multimap.update_multi ~src ~dst:after ~f:merge_and_sort) ;
221+
update_cmts t `Within
222+
~f:(Multimap.update_multi ~src ~dst:after ~f:merge_and_sort) ;
223+
if t.debug then
224+
update_remaining t ~f:(fun s ->
225+
let s = Set.remove s src in
226+
let s = Set.add s after in
227+
Set.add s before )
222228

223229
let relocate_cmts_before (t : t) ~src ~sep ~dst =
224230
let f map =
@@ -281,8 +287,7 @@ let init fragment ~debug source asts comments_n_docstrings =
281287
; cmts_after= Map.empty (module Location)
282288
; cmts_within= Map.empty (module Location)
283289
; source
284-
; remaining= Set.empty (module Location)
285-
; remove= true }
290+
; remaining= Set.empty (module Location) }
286291
in
287292
let comments = Normalize.dedup_cmts fragment asts comments_n_docstrings in
288293
if not (List.is_empty comments) then (
@@ -311,21 +316,23 @@ let init fragment ~debug source asts comments_n_docstrings =
311316
Format.eprintf "@\n%a@\n@\n%!" dump loc_tree ) ) ;
312317
t
313318

314-
let preserve fmt_x t =
315-
let buf = Buffer.create 128 in
316-
let fs = Format.formatter_of_buffer buf in
317-
Fmt.eval fs (fmt_x {t with remove= false}) ;
318-
Format.pp_print_flush fs () ;
319-
Buffer.contents buf
319+
let preserve f t =
320+
let original = copy t in
321+
let finally () = restore original ~into:t in
322+
Exn.protect ~finally ~f:(fun () ->
323+
let buf = Buffer.create 128 in
324+
let fs = Format.formatter_of_buffer buf in
325+
Fmt.eval fs (f ()) ;
326+
Format.pp_print_flush fs () ;
327+
Buffer.contents buf )
320328

321329
let pop_if_debug t loc =
322-
if t.debug && t.remove then
323-
update_remaining t ~f:(fun s -> Set.remove s loc)
330+
if t.debug then update_remaining t ~f:(fun s -> Set.remove s loc)
324331

325332
let find_cmts t pos loc =
326333
pop_if_debug t loc ;
327334
let r = find_at_position t loc pos in
328-
if t.remove then update_cmts t pos ~f:(fun m -> Map.remove m loc) ;
335+
update_cmts t pos ~f:(fun m -> Map.remove m loc) ;
329336
r
330337

331338
let break_comment_group source margin {Cmt.loc= a; _} {Cmt.loc= b; _} =

lib/Cmts.mli

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,6 @@ val diff :
126126
Conf.t -> Cmt.t list -> Cmt.t list -> (string, string) Either.t Sequence.t
127127
(** Difference between two lists of comments. *)
128128

129-
val preserve : (t -> Fmt.t) -> t -> string
130-
(** [preserve fmt_x x] formats like [fmt_x x] but returns a string and does
131-
not consume comments from the internal state. *)
129+
val preserve : (unit -> Fmt.t) -> t -> string
130+
(** [preserve f t] formats like [f ()] but returns a string and does not
131+
consume comments from [t]. *)

lib/Fmt_ast.ml

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,8 +1366,7 @@ and fmt_label_arg ?(box = true) ?epi ?parens ?eol c
13661366
| _ -> fmt_label lbl ":@," $ fmt_expression c ~box ?epi ?parens xarg
13671367

13681368
and expression_width c xe =
1369-
String.length
1370-
(Cmts.preserve (fun cmts -> fmt_expression {c with cmts} xe) c.cmts)
1369+
String.length (Cmts.preserve (fun () -> fmt_expression c xe) c.cmts)
13711370

13721371
and fmt_args_grouped ?epi:(global_epi = noop) c ctx args =
13731372
let fmt_arg c ~first:_ ~last (lbl, arg) =
@@ -1396,8 +1395,8 @@ and fmt_args_grouped ?epi:(global_epi = noop) c ctx args =
13961395
let xexp = sub_exp ~ctx x in
13971396
let output =
13981397
Cmts.preserve
1399-
(fun cmts ->
1400-
let cmts = Cmts.drop_before cmts x.pexp_loc in
1398+
(fun () ->
1399+
let cmts = Cmts.drop_before c.cmts x.pexp_loc in
14011400
fmt_arg ~first:false ~last:false {c with cmts} (lbl, x) )
14021401
c.cmts
14031402
in
@@ -2973,9 +2972,7 @@ and fmt_cases c ctx cs =
29732972
if Option.is_some pc_guard then None
29742973
else
29752974
let xpat = sub_pat ~ctx pc_lhs in
2976-
let fmted =
2977-
Cmts.preserve (fun cmts -> fmt_pattern {c with cmts} xpat) c.cmts
2978-
in
2975+
let fmted = Cmts.preserve (fun () -> fmt_pattern c xpat) c.cmts in
29792976
let len = String.length fmted in
29802977
if len * 3 >= c.conf.margin || String.contains fmted '\n' then None
29812978
else Some len

0 commit comments

Comments
 (0)