Skip to content

Commit 91d01f0

Browse files
committed
refactor: factor out text handling as new modules
1 parent e9baa85 commit 91d01f0

20 files changed

+207
-130
lines changed

src-lsp/LspServer.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,18 @@ struct
5656
let msg = Broadcast.to_jsonrpc notif in
5757
send (RPC.Packet.Notification msg)
5858

59-
let render_lsp_related_info (uri : L.DocumentUri.t) (message : Asai.Diagnostic.loctext) : L.DiagnosticRelatedInformation.t =
59+
let render_lsp_related_info (uri : L.DocumentUri.t) (message : Asai.Loctext.t) : L.DiagnosticRelatedInformation.t =
6060
let range = LspShims.Loc.lsp_range_of_range message.loc in
6161
let location = L.Location.create ~uri ~range in
62-
let message = Asai.Diagnostic.string_of_text message.value in
62+
let message = Asai.Text.to_string message.value in
6363
L.DiagnosticRelatedInformation.create ~location ~message
6464

6565
let render_lsp_diagnostic (uri : L.DocumentUri.t) (diag : diagnostic) : Lsp_Diagnostic.t =
6666
let range = LspShims.Loc.lsp_range_of_range diag.explanation.loc in
6767
let severity = LspShims.Diagnostic.lsp_severity_of_severity @@ diag.severity in
6868
let code = `String (Message.short_code diag.message) in
6969
let source = (State.get ()).source in
70-
let message = Asai.Diagnostic.string_of_text diag.explanation.value in
70+
let message = Asai.Text.to_string diag.explanation.value in
7171
let relatedInformation = Bwd.to_list @@ Bwd.map (render_lsp_related_info uri) diag.extra_remarks in
7272
Lsp_Diagnostic.create
7373
~range

src/Asai.ml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
module Range = Range
2+
module Text = Text
3+
module Loctext = Loctext
24
module Diagnostic = Diagnostic
35
module Reporter = Reporter
46
module StructuredReporter = StructuredReporter

src/Asai.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@
77
(** Locations and ranges. *)
88
module Range = Range
99

10+
(** Texts that preserve pretty-printing structures.
11+
12+
@since 0.3.2 *)
13+
module Text = Text
14+
15+
(** Located texts. "Loctext" is a portmanteau of "locate" and "text".
16+
17+
@since 0.3.2 *)
18+
module Loctext = Loctext
19+
1020
(** The definition of diagnostics and some utility functions. *)
1121
module Diagnostic = Diagnostic
1222

src/Diagnostic.ml

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,6 @@ open Bwd
22

33
include DiagnosticData
44

5-
let text s fmt =
6-
Format.(pp_print_list ~pp_sep:pp_force_newline pp_print_string) fmt @@
7-
String.split_on_char '\n' s
8-
9-
let textf = Format.dprintf
10-
11-
let ktextf = Format.kdprintf
12-
13-
let loctext ?loc s = Range.{ loc; value = text s }
14-
15-
let kloctextf ?loc k = ktextf @@ fun loctext -> k Range.{ loc; value = loctext }
16-
17-
let loctextf ?loc = kloctextf Fun.id ?loc
18-
195
let of_loctext ?(backtrace=Bwd.Emp) ?(extra_remarks=[]) severity message explanation : _ t =
206
{ severity
217
; message
@@ -28,14 +14,14 @@ let of_text ?loc ?backtrace ?extra_remarks severity message text : _ t =
2814
of_loctext ?backtrace ?extra_remarks severity message {loc; value = text}
2915

3016
let make ?loc ?backtrace ?extra_remarks severity message explanation =
31-
of_text ?loc ?backtrace ?extra_remarks severity message @@ text explanation
17+
of_text ?loc ?backtrace ?extra_remarks severity message @@ Text.make explanation
3218

3319
let kmakef ?loc ?backtrace ?extra_remarks k severity message =
34-
ktextf @@ fun text ->
20+
Text.kmakef @@ fun text ->
3521
k @@ of_text ?loc ?backtrace ?extra_remarks severity message text
3622

3723
let makef ?loc ?backtrace ?extra_remarks severity message =
38-
ktextf @@ of_text ?loc ?backtrace ?extra_remarks severity message
24+
Text.kmakef @@ of_text ?loc ?backtrace ?extra_remarks severity message
3925

4026
let map f d = {d with message = f d.message}
4127

@@ -47,3 +33,13 @@ let string_of_text text : string =
4733
Format.pp_print_flush fmt ();
4834
Str.global_replace (Str.regexp "\\([\r\n]+ *\\)+") " " @@
4935
Buffer.contents buf
36+
37+
type text = Text.t
38+
let text = Text.make
39+
let textf = Text.makef
40+
let ktextf = Text.kmakef
41+
42+
type loctext = Loctext.t
43+
let loctext = Loctext.make
44+
let loctextf = Loctext.makef
45+
let kloctextf = Loctext.kmakef

src/Diagnostic.mli

Lines changed: 45 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,9 @@
33
(* @include *)
44
include module type of DiagnosticData
55

6-
(** {1 Constructing Messages} *)
7-
8-
(** [text str] converts the string [str] into a text, converting each ['\n'] into a call to {!val:Format.pp_force_newline}. *)
9-
val text : string -> text
10-
11-
(** [textf format ...] formats a text. It is an alias of {!val:Format.dprintf}. Note that there should not be any literal control characters (e.g., literal newline characters). *)
12-
val textf : ('a, Format.formatter, unit, text) format4 -> 'a
13-
14-
(** [ktextf kont format ...] is [kont (textf format ...)]. It is an alias of {!val:Format.kdprintf}. *)
15-
val ktextf : (text -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a
16-
17-
(** [loctext str] converts the string [str] into a loctext.
18-
19-
@param loc The location of the loctext (usually the code) to highlight. *)
20-
val loctext : ?loc:Range.t -> string -> loctext
21-
22-
(** [loctextf format ...] constructs a loctext. Note that there should not be any literal control characters (e.g., literal newline characters).
23-
24-
@param loc The location of the loctext (usually the code) to highlight.
25-
*)
26-
val loctextf : ?loc:Range.t -> ('a, Format.formatter, unit, loctext) format4 -> 'a
27-
28-
(** [kloctextf kont format ...] is [kont (loctextf format ...)].
29-
30-
@param loc The location of the loctext (usually the code) to highlight.
31-
*)
32-
val kloctextf : ?loc:Range.t -> (loctext -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a
33-
346
(** {1 Constructing Diagnostics} *)
357

36-
(** [of_text severity message text] constructs a diagnostic from a {!type:text}.
8+
(** [of_text severity message text] constructs a diagnostic from a {!type:Text.t}.
379
3810
Example:
3911
{[
@@ -45,9 +17,9 @@ val kloctextf : ?loc:Range.t -> (loctext -> 'b) -> ('a, Format.formatter, unit,
4517
4618
@since 0.2.0
4719
*)
48-
val of_text : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext list -> severity -> 'message -> text -> 'message t
20+
val of_text : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:Loctext.t list -> severity -> 'message -> Text.t -> 'message t
4921

50-
(** [of_loctext severity message loctext] constructs a diagnostic from a {!type:loctext}.
22+
(** [of_loctext severity message loctext] constructs a diagnostic from a {!type:Loctext.t}.
5123
5224
Example:
5325
{[
@@ -57,7 +29,7 @@ val of_text : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext lis
5729
@param backtrace The backtrace (to overwrite the accumulative frames up to this point).
5830
@param extra_remarks Additional remarks that are not part of the backtrace.
5931
*)
60-
val of_loctext : ?backtrace:backtrace -> ?extra_remarks:loctext list -> severity -> 'message -> loctext -> 'message t
32+
val of_loctext : ?backtrace:backtrace -> ?extra_remarks:Loctext.t list -> severity -> 'message -> Loctext.t -> 'message t
6133

6234
(** [make severity message loctext] constructs a diagnostic with the [loctext].
6335
@@ -69,9 +41,9 @@ val of_loctext : ?backtrace:backtrace -> ?extra_remarks:loctext list -> severity
6941
@param backtrace The backtrace (to overwrite the accumulative frames up to this point).
7042
@param extra_remarks Additional remarks that are not part of the backtrace.
7143
*)
72-
val make : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext list -> severity -> 'message -> string -> 'message t
44+
val make : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:Loctext.t list -> severity -> 'message -> string -> 'message t
7345

74-
(** [makef severity message format ...] is [of_loctext severity message (loctextf format ...)]. It formats the message and constructs a diagnostic out of it.
46+
(** [makef severity message format ...] is [of_loctext severity message (Loctext.makef format ...)]. It formats the message and constructs a diagnostic out of it.
7547
7648
Example:
7749
{[
@@ -82,20 +54,55 @@ val make : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext list -
8254
@param backtrace The backtrace (to overwrite the accumulative frames up to this point).
8355
@param extra_remarks Additional remarks that are not part of the backtrace.
8456
*)
85-
val makef : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext list -> severity -> 'message -> ('a, Format.formatter, unit, 'message t) format4 -> 'a
57+
val makef : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:Loctext.t list -> severity -> 'message -> ('a, Format.formatter, unit, 'message t) format4 -> 'a
8658

8759
(** [kmakef kont severity message format ...] is [kont (makef severity message format ...)].
8860
8961
@param loc The location of the text (usually the code) to highlight.
9062
@param backtrace The backtrace (to overwrite the accumulative frames up to this point).
9163
@param extra_remarks Additional remarks that are not part of the backtrace.
9264
*)
93-
val kmakef : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:loctext list -> ('message t -> 'b) -> severity -> 'message -> ('a, Format.formatter, unit, 'b) format4 -> 'a
65+
val kmakef : ?loc:Range.t -> ?backtrace:backtrace -> ?extra_remarks:Loctext.t list -> ('message t -> 'b) -> severity -> 'message -> ('a, Format.formatter, unit, 'b) format4 -> 'a
9466

9567
(** {1 Other Helper Functions} *)
9668

9769
(** A convenience function that maps the message of a diagnostic. This is helpful when using {!val:Reporter.S.adopt}. *)
9870
val map : ('message1 -> 'message2) -> 'message1 t -> 'message2 t
9971

100-
(** A convenience function that converts a {!type:text} into a string by formatting it with the maximum admissible margin and then replacing newlines and indentation with a space character. *)
101-
val string_of_text : text -> string
72+
(** {1 Deprecated Types and Functions} *)
73+
74+
(** An alias of [Text.t] for backward compatibility. *)
75+
type text = Text.t
76+
[@@ocaml.alert deprecated "Use Text.t instead"]
77+
78+
(** An alias of [Loctext.t] for backward compatibility. *)
79+
type loctext = Loctext.t
80+
[@@ocaml.alert deprecated "Use Loctext.t instead"]
81+
82+
(** An alias of [Text.make] for backward compatibility. *)
83+
val text : string -> Text.t
84+
[@@ocaml.alert deprecated "Use Text.make instead"]
85+
86+
(** An alias of [Text.makef] for backward compatibility. *)
87+
val textf : ('a, Format.formatter, unit, Text.t) format4 -> 'a
88+
[@@ocaml.alert deprecated "Use Text.makef instead"]
89+
90+
(** An alias of [Text.kmakef] for backward compatibility. *)
91+
val ktextf : (Text.t -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a
92+
[@@ocaml.alert deprecated "Use Text.kmakef instead"]
93+
94+
(** An alias of [Loctext.make] for backward compatibility. *)
95+
val loctext : ?loc:Range.t -> string -> Loctext.t
96+
[@@ocaml.alert deprecated "Use Loctext.make instead"]
97+
98+
(** An alias of [Loctext.makef] for backward compatibility. *)
99+
val loctextf : ?loc:Range.t -> ('a, Format.formatter, unit, Loctext.t) format4 -> 'a
100+
[@@ocaml.alert deprecated "Use Loctext.makef instead"]
101+
102+
(** An alias of [Loctext.kmakef] for backward compatibility. *)
103+
val kloctextf : ?loc:Range.t -> (Loctext.t -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a
104+
[@@ocaml.alert deprecated "Use Loctext.kmakef instead"]
105+
106+
(** An alias of [Text.to_string] for backward compatibility. *)
107+
val string_of_text : Text.t -> string
108+
[@@ocaml.alert deprecated "Use Text.to_string instead"]

src/DiagnosticData.ml

Lines changed: 3 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,19 @@ type severity =
88
| Error (** A serious error caused by the end user (the user of your proof assistant or compiler) or other external factors (e.g., internet not working). *)
99
| Bug (** A serious error likely caused by a bug in the proof assistant. You would want the end user to report the bug back to you. This is useful for indicating that certain branches in a pattern matching should be "impossible", while printing out debugging information in case the program logic is flawed. *)
1010

11-
(** The type of texts.
12-
13-
When we render a diagnostic, the layout engine of the diagnostic handler should be the one making layout choices. Therefore, we cannot pass already formatted strings. Instead, a text is defined to be a function that takes a formatter and uses it to render the content. A valid text must satisfy the following two conditions:
14-
+ {b All string (and character) literals must be encoded using UTF-8.}
15-
+ {b All string (and character) literals must not contain control characters (such as the newline character [\n]).} It is okay to have break hints (such as [@,] and [@ ]) but not literal control characters. This means you should avoid pre-formatted strings, and if you must use them, use {!val:text} to convert newline characters. Control characters include `U+0000-001F` (C0 controls), `U+007F` (backspace) and `U+0080-009F` (C1 controls). These characters are banned because they would mess up the cursor position.
16-
17-
{i Pro-tip:} to format a text in another text, use [%t]:
18-
{[
19-
let t = textf "@[<2>this is what the master said:@ @[%t@]@]" inner_text
20-
]}
21-
*)
22-
type text = Format.formatter -> unit
23-
24-
(** A loctext is a {!type:text} with location information. "loctext" is a portmanteau of "locate" and "text". *)
25-
type loctext = text Range.located
26-
2711
(** A backtrace is a (backward) list of loctexts. *)
28-
type backtrace = loctext bwd
12+
type backtrace = Loctext.t bwd
2913

3014
(** The type of diagnostics. *)
3115
type 'message t = {
3216
severity : severity;
3317
(** Severity of the diagnostic. *)
3418
message : 'message;
3519
(** The (structured) message. *)
36-
explanation : loctext;
20+
explanation : Loctext.t;
3721
(** The free-form explanation. *)
3822
backtrace : backtrace;
3923
(** The backtrace leading to this diagnostic. *)
40-
extra_remarks : loctext bwd;
24+
extra_remarks : Loctext.t bwd;
4125
(** Additional remarks that are relevant to the main message but not part of the backtrace. It is a backward list so that new remarks can be added to its end easily. *)
4226
}

src/GitHub.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module Make (Message : Reporter.Message) = struct
1313
Format.printf "::%s title=%s::%s@."
1414
(command_of_severity severity)
1515
(Message.short_code msg)
16-
(Diagnostic.string_of_text text)
16+
(Text.to_string text)
1717

1818
let print_with_loc severity msg loc text =
1919
match Range.source loc with
@@ -26,7 +26,7 @@ module Make (Message : Reporter.Message) = struct
2626
(Range.begin_line_num loc)
2727
(Range.end_line_num loc)
2828
(Message.short_code msg)
29-
(Diagnostic.string_of_text text)
29+
(Text.to_string text)
3030

3131
let print Diagnostic.{severity; message; explanation = {loc; value = text}; _} =
3232
match loc with

src/Loctext.ml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
type t = Text.t Range.located
2+
3+
let make ?loc s : t = Range.locate_opt loc @@ Text.make s
4+
5+
let kmakef ?loc k = Text.kmakef @@ fun t -> k @@ Range.locate_opt loc t
6+
7+
let makef ?loc = Text.kmakef @@ Range.locate_opt loc

src/Loctext.mli

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
(** {1 Types} *)
2+
3+
(** A located text *)
4+
type t = Text.t Range.located
5+
6+
(** {1 Builders} *)
7+
8+
(** [make str] converts the string [str] into a located text.
9+
10+
@param loc The location of the text (usually the code) to highlight. *)
11+
val make : ?loc:Range.t -> string -> t
12+
13+
(** [makef format ...] constructs a located text. Note that there should not be any literal control characters (e.g., literal newline characters).
14+
15+
@param loc The location of the text (usually the code) to highlight.
16+
*)
17+
val makef : ?loc:Range.t -> ('a, Format.formatter, unit, t) format4 -> 'a
18+
19+
(** [kmakef kont format ...] is [kont (makef format ...)].
20+
21+
@param loc The location of the text (usually the code) to highlight.
22+
*)
23+
val kmakef : ?loc:Range.t -> (t -> 'b) -> ('a, Format.formatter, unit, 'b) format4 -> 'a

src/Reporter.ml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,12 @@ struct
2727
(match loc with None -> l | Some _ -> loc),
2828
bt <: {loc; value = text}
2929

30-
let trace_loctext (t : Diagnostic.loctext) =
30+
let trace_loctext (t : Loctext.t) =
3131
trace_text ?loc:t.loc t.value
3232

33-
let trace ?loc str = trace_text ?loc @@ Diagnostic.text str
33+
let trace ?loc str = trace_text ?loc @@ Text.make str
3434

35-
let tracef ?loc = Diagnostic.kloctextf trace_loctext ?loc
35+
let tracef ?loc = Loctext.kmakef trace_loctext ?loc
3636

3737
(* Constructing diagnostics *)
3838

0 commit comments

Comments
 (0)