Skip to content

Commit 5e4574d

Browse files
committed
Alternative method for slicing errors in mli_parser
1 parent 1f83f73 commit 5e4574d

File tree

1 file changed

+14
-34
lines changed

1 file changed

+14
-34
lines changed

lib/mli_parser.ml

Lines changed: 14 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ module Code_block = struct
55
metadata : metadata option;
66
delimiter : string option;
77
content : Location.t; (* Location of the content *)
8+
content_txt : string; (* The content itself *)
89
code_block : Location.t; (* Location of the enclosing code block *)
10+
output : t list;
911
}
1012
end
1113

@@ -36,7 +38,7 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
3638
Fortunately the location info give us enough info to be able to extract
3739
the code from the original text, whitespace and all.
3840
*)
39-
let handle_code_block : O.Loc.span -> _ -> Code_block.t =
41+
let rec handle_code_block : O.Loc.span -> _ -> Code_block.t =
4042
let convert_loc (sp : O.Loc.span) =
4143
Location.
4244
{
@@ -46,7 +48,7 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
4648
}
4749
in
4850
fun location
49-
{ O.Ast.meta; delimiter; content = { O.Loc.location = span; _ }; _ } ->
51+
{ O.Ast.meta; delimiter; content = { O.Loc.location = span; value }; output } ->
5052
let metadata =
5153
Option.map
5254
(fun { O.Ast.language; tags } ->
@@ -57,12 +59,14 @@ let extract_code_block_info acc ~(location : Lexing.position) ~docstring =
5759
in
5860
let content = convert_loc span in
5961
let code_block = convert_loc location in
60-
{ metadata; delimiter; content; code_block }
61-
in
62+
let output = Option.map (List.fold_left fold_fn [])
63+
(output :> O.Ast.block_element O.Ast.with_location list option) in
64+
let output = Option.value ~default:[] output in
65+
{ metadata; delimiter; content; content_txt = value; code_block; output }
6266

6367
(* Fold over the results from odoc-parser, recurse where necessary
6468
and extract the code block metadata *)
65-
let rec fold_fn acc (elt : O.Ast.block_element O.Loc.with_location) =
69+
and fold_fn acc (elt : O.Ast.block_element O.Loc.with_location) =
6670
match elt with
6771
| { O.Loc.value = `Code_block c; location } ->
6872
handle_code_block location c :: acc
@@ -137,34 +141,10 @@ let slice file_contents (loc : Location.t) =
137141
Error: expected int, got string
138142
]err}
139143
]} *)
140-
let slice_error (code_block : Code_block.t) file_contents =
141-
let starts = code_block.content.loc_end.pos_cnum in
142-
let ends = code_block.code_block.loc_end.pos_cnum in
143-
let len = ends - starts in
144-
let str = String.sub file_contents starts len in
145-
let no_errors = Fmt.str "]%a}" Fmt.(option string) code_block.delimiter in
146-
if str = no_errors then []
147-
else
148-
let sep = Fmt.str "]%a[\n" Fmt.(option string) code_block.delimiter in
149-
assert (Astring.String.is_prefix ~affix:sep str);
150-
assert (Astring.String.is_suffix ~affix:"]}" str);
151-
let str =
152-
String.sub str (String.length sep)
153-
(String.length str - String.length sep - 2)
154-
in
155-
let location =
156-
{ code_block.content.loc_end with pos_cnum = starts + String.length sep }
157-
in
158-
match extract_code_block_info [] ~location ~docstring:str with
159-
| [ x ] ->
160-
let lines =
161-
x.content |> slice file_contents |> String.split_on_char '\n'
162-
in
163-
let lines =
164-
(* Discard the first and last lines *)
165-
List.tl (List.rev (List.tl (List.rev lines)))
166-
in
167-
List.map output_of_line lines
144+
let slice_error (code_block : Code_block.t) =
145+
match code_block.output with
146+
| [] -> []
147+
| [ x ] -> x.content_txt |> output_of_line |> fun x -> [ x ]
168148
| _ -> assert false
169149

170150
(* Given code block metadata and the original file, this function splices the
@@ -197,7 +177,7 @@ let make_block code_block file_contents =
197177
let contents =
198178
slice file_contents code_block.content |> String.split_on_char '\n'
199179
in
200-
let errors = slice_error code_block file_contents in
180+
let errors = slice_error code_block in
201181
Block.mk ~loc:code_block.code_block ~section:None ~labels ~header
202182
~contents ~legacy_labels:false ~errors ~delim
203183

0 commit comments

Comments
 (0)