Skip to content

Commit 81210a9

Browse files
committed
fix errors for skipped blocks on mli
1 parent 4bc3bea commit 81210a9

File tree

2 files changed

+64
-7
lines changed

2 files changed

+64
-7
lines changed

lib/mli_parser.ml

Lines changed: 53 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,54 @@ let docstring_code_blocks str =
121121
in
122122
loop [] |> List.rev)
123123

124+
let output_of_line x =
125+
match String.trim x with "..." -> `Ellipsis | _ -> `Output x
126+
127+
let slice file_contents (loc : Location.t) =
128+
let start = loc.loc_start.pos_cnum in
129+
let len = loc.loc_end.pos_cnum - start in
130+
String.sub file_contents start len
131+
132+
(* extract "Error: expected int, got string" from:
133+
{delim@ocaml[
134+
let x = 1 + "a string is not an int"
135+
]delim[
136+
{err@mdx-error[
137+
Error: expected int, got string
138+
]err}
139+
]}
140+
*)
141+
142+
let slice_error (code_block : Code_block.t) file_contents =
143+
let starts = code_block.content.loc_end.pos_cnum in
144+
let ends = code_block.code_block.loc_end.pos_cnum in
145+
let len = ends - starts in
146+
let str = String.sub file_contents starts len in
147+
let no_errors = Fmt.str "]%a}" Fmt.(option string) code_block.delimiter in
148+
if str = no_errors then []
149+
else
150+
let sep = Fmt.str "]%a[\n" Fmt.(option string) code_block.delimiter in
151+
assert (Astring.String.is_prefix ~affix:sep str);
152+
assert (Astring.String.is_suffix ~affix:"]}" str);
153+
let str =
154+
String.sub str (String.length sep)
155+
(String.length str - String.length sep - 2)
156+
in
157+
let location =
158+
{ code_block.content.loc_end with pos_cnum = starts + String.length sep }
159+
in
160+
match extract_code_block_info [] ~location ~docstring:str with
161+
| [ x ] ->
162+
let lines =
163+
x.content |> slice file_contents |> String.split_on_char '\n'
164+
in
165+
let lines =
166+
(* Discard the first and last lines *)
167+
List.tl (List.rev (List.tl (List.rev lines)))
168+
in
169+
List.map output_of_line lines
170+
| _ -> assert false
171+
124172
(* Given code block metadata and the original file, this function splices the
125173
contents of the code block from the original text and creates an Mdx
126174
Block.t, or reports the error (e.g., from invalid tags) *)
@@ -147,15 +195,13 @@ let make_block code_block file_contents =
147195
match handle_header code_block.Code_block.metadata with
148196
| Error _ as e -> e
149197
| Ok (header, labels) ->
150-
let slice (loc : Location.t) =
151-
let start = loc.loc_start.pos_cnum in
152-
let len = loc.loc_end.pos_cnum - start in
153-
String.sub file_contents start len
154-
in
155198
let delim = code_block.delimiter in
156-
let contents = slice code_block.content |> String.split_on_char '\n' in
199+
let contents =
200+
slice file_contents code_block.content |> String.split_on_char '\n'
201+
in
202+
let errors = slice_error code_block file_contents in
157203
Block.mk ~loc:code_block.code_block ~section:None ~labels ~header
158-
~contents ~legacy_labels:false ~errors:[] ~delim
204+
~contents ~legacy_labels:false ~errors ~delim
159205

160206
(* Given the locations of the code blocks within [file_contents], then slice it up into
161207
[Text] and [Block] parts by using the starts and ends of those blocks as

test/bin/mdx-test/expect/simple-mli/test-case.mli

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,14 @@ Error: This expression has type string but an expression was expected of type
6060
int
6161
]err}]}
6262
*)
63+
64+
(**
65+
{@ocaml skip[
66+
let f = 1 + "2"
67+
][
68+
{err@mdx-error[
69+
Line 1, characters 15-18:
70+
Error: This expression has type string but an expression was expected of type
71+
int
72+
]err}]}
73+
*)

0 commit comments

Comments
 (0)