Skip to content

Commit d339056

Browse files
Merge pull request #342 from Leonidas-from-XIV/add-warning-for-double-semicolons
Add warning for phrases that are missing trailing ;;
2 parents 3942bad + d2a00b6 commit d339056

File tree

28 files changed

+151
-68
lines changed

28 files changed

+151
-68
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88

99
#### Deprecated
1010

11+
- Add a deprecation warning for toplevel blocks that are not terminated with `;;` (#342, @Leonidas-from-XIV)
12+
1113
#### Fixed
1214

1315
- Fix accidental redirect of stderr to stdout (#343, @Leonidas-from-XIV)

lib/deprecated.ml

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,31 @@ let warn ?replacement s ~since =
2323
Format.eprintf
2424
"Warning: %s is deprecated since %s and will be removed in 2.0.0. %s\n%!" s
2525
since replacement
26+
27+
module Missing_double_semicolon = struct
28+
let missing_semicolon = ref false
29+
30+
let check_toplevel : Toplevel.t -> unit =
31+
fun toplevel ->
32+
match List.rev toplevel.command with
33+
| cmd :: _ ->
34+
let ends_with_semi =
35+
cmd |> Astring.String.trim |> Astring.String.is_suffix ~affix:";;"
36+
in
37+
if not ends_with_semi then missing_semicolon := true
38+
| [] -> ()
39+
40+
let check_block block = List.iter check_toplevel block
41+
42+
let report ~filename =
43+
if !missing_semicolon then
44+
Format.eprintf
45+
"Warning: OCaml toplevel block without trailing ;; detected in file \
46+
'%s'.\n\
47+
Non-semicolon terminated phrases are deprecated.\n\
48+
MDX 2.0 will accept them as input but will output them with ;; \
49+
appended.\n\
50+
In MDX 3.0 support for toplevel blocks without ;; will be removed \
51+
completely.\n"
52+
filename
53+
end

lib/deprecated.mli

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,9 @@
1616

1717
val warn : ?replacement:string -> string -> since:string -> unit
1818
(** Emits a warning on the standard error. *)
19+
20+
module Missing_double_semicolon : sig
21+
val check_block : Toplevel.t list -> unit
22+
23+
val report : filename:string -> unit
24+
end

lib/test/mdx_test.ml

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ let run_exn ~non_deterministic ~silent_eval ~record_backtrace ~syntax ~silent
287287

288288
let test_block ~ppf ~temp_file t =
289289
let print_block () = Block.pp ?syntax ppf t in
290-
if Block.is_active ?section t then
290+
if Block.is_active ?section t then (
291291
match Block.value t with
292292
| Raw _ -> print_block ()
293293
| Include { file_included; file_kind = Fk_ocaml { part_included } } ->
@@ -317,30 +317,31 @@ let run_exn ~non_deterministic ~silent_eval ~record_backtrace ~syntax ~silent
317317
~det:(fun () ->
318318
run_cram_tests ?syntax t ?root ppf temp_file pad tests)
319319
| Toplevel { non_det; env } ->
320-
let tests =
320+
let phrases =
321321
let syntax = Util.Option.value syntax ~default:Normal in
322322
Toplevel.of_lines ~syntax ~loc:t.loc t.contents
323323
in
324+
Deprecated.Missing_double_semicolon.check_block phrases;
324325
with_non_det non_deterministic non_det ~command:print_block
325326
~output:(fun () ->
326327
assert (syntax <> Some Cram);
327328
print_block ();
328329
List.iter
329-
(fun (test : Toplevel.t) ->
330+
(fun (phrase : Toplevel.t) ->
330331
match
331332
Mdx_top.in_env env (fun () ->
332-
eval_test ~block:t ?root c test.command)
333+
eval_test ~block:t ?root c phrase.command)
333334
with
334335
| Ok _ -> ()
335336
| Error e ->
336337
let output = List.map (fun l -> `Output l) e in
337-
if Output.equal test.output output then ()
338-
else err_eval ~cmd:test.command e)
339-
tests)
338+
if Output.equal phrase.output output then ()
339+
else err_eval ~cmd:phrase.command e)
340+
phrases)
340341
~det:(fun () ->
341342
assert (syntax <> Some Cram);
342343
Mdx_top.in_env env (fun () ->
343-
run_toplevel_tests ?syntax ?root c ppf tests t))
344+
run_toplevel_tests ?syntax ?root c ppf phrases t)))
344345
else print_block ()
345346
in
346347
let gen_corrected file_contents items =
@@ -364,6 +365,7 @@ let run_exn ~non_deterministic ~silent_eval ~record_backtrace ~syntax ~silent
364365
try test_block ~ppf ~temp_file t
365366
with Failure msg -> raise (Test_block_failure (t, msg))))
366367
items;
368+
Deprecated.Missing_double_semicolon.report ~filename:file;
367369
Format.pp_print_flush ppf ();
368370
Buffer.contents buf
369371
in

test/bin/mdx-pp/expect/spaces/test-case.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,15 @@ let x =
1414
1515
# let x = 1
1616
17-
in x
17+
in x;;
1818
- : int = 1
1919
2020
21-
# 3
21+
# 3;;
2222
- : int = 3
2323
2424
25-
# Printf.printf "foo\n\nbar\n"
25+
# Printf.printf "foo\n\nbar\n";;
2626
foo
2727
2828
bar

test/bin/mdx-pp/expect/spaces/test_case.ml.expected

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,8 @@ let x =
99
#15 "test-case.md"
1010
let x = 1
1111

12-
in x
12+
in x;;
1313
#21 "test-case.md"
14-
3
14+
3;;
1515
#25 "test-case.md"
16-
Printf.printf "foo\n\nbar\n"
17-
;;
16+
Printf.printf "foo\n\nbar\n";;

test/bin/mdx-test/expect/code/test-case.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ let () = Printf.printf "n: %d\n%!" (f 42)
1111
Yo!
1212

1313
```ocaml
14-
# let x = 3
14+
# let x = 3;;
1515
val x : int = 3
16-
# type t = int
16+
# type t = int;;
1717
type t = int
1818
```
1919

@@ -22,12 +22,12 @@ class istack = object end
2222
```
2323

2424
```ocaml
25-
# module type Foo = sig type t end
25+
# module type Foo = sig type t end;;
2626
module type Foo = sig type t end
2727
```
2828

2929

3030
```ocaml skip
31-
# Pipe.f ()
31+
# Pipe.f ();;
3232
- : unit
3333
```

test/bin/mdx-test/expect/ellipsis/test-case.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ $ for i in `seq 1 10`; do echo $i; done
1010
```
1111

1212
```ocaml
13-
# for i = 1 to 10 do Printf.printf "%d\n%!" i; done
13+
# for i = 1 to 10 do Printf.printf "%d\n%!" i; done;;
1414
1
1515
2
1616
...
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
Testing empty line output
22

33
```ocaml
4-
# print_newline ()
4+
# print_newline ();;
55
- : unit = ()
6-
# print_endline ""
6+
# print_endline "";;
77
- : unit = ()
88
```

test/bin/mdx-test/expect/empty-lines/test-case.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ This shell block contains an empty line within a padded block:
88
This toplevel block contains an empty line within a padded block:
99

1010
```ocaml
11-
# print_newline
11+
# print_newline;;
1212
1313
```

0 commit comments

Comments
 (0)