Skip to content

Commit a84bbeb

Browse files
committed
Add flag -raise-embedded-errors to Driver, which raises the first embedded ocaml.error in the processed AST.
Signed-off-by: Jay Mody <[email protected]>
1 parent 3a79108 commit a84bbeb

File tree

6 files changed

+70
-2
lines changed

6 files changed

+70
-2
lines changed

Diff for: ast/location_error.ml

+30
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,33 @@ let get_location error =
4040

4141
let of_exn = Astlib.Location.Error.of_exn
4242
let raise error = raise (Astlib.Location.Error error)
43+
44+
let of_extension (extension : Ast.extension) =
45+
let open Parsetree in
46+
let parse_msg = function
47+
| {
48+
pstr_desc =
49+
Pstr_eval
50+
({ pexp_desc = Pexp_constant (Pconst_string (msg, _, _)); _ }, []);
51+
_;
52+
} ->
53+
msg
54+
| _ -> "ppxlib: failed to extract message in ocaml.error"
55+
in
56+
let parse_sub_msg = function
57+
| {
58+
pstr_desc =
59+
Pstr_extension
60+
(({ txt = "error" | "ocaml.error"; loc }, PStr [ msg ]), []);
61+
_;
62+
} ->
63+
(loc, parse_msg msg)
64+
| { pstr_loc = loc; _ } ->
65+
(loc, "ppxlib: failed to parse ocaml.error sub messages")
66+
in
67+
match extension with
68+
| { txt = "error" | "ocaml.error"; loc }, PStr (main :: sub) ->
69+
let main = parse_msg main in
70+
let sub = List.map parse_sub_msg sub in
71+
Some (make ~loc main ~sub)
72+
| _ -> None

Diff for: ast/location_error.mli

+1
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ val to_extension : t -> Import.Parsetree.extension
1111
val raise : t -> 'a
1212
val update_loc : t -> Location.t -> t
1313
val get_location : t -> Location.t
14+
val of_extension : Import.Parsetree.extension -> t option

Diff for: src/driver.ml

+21-2
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,25 @@ let styler = ref None
2525
let output_metadata_filename = ref None
2626
let corrected_suffix = ref ".ppx-corrected"
2727
let keywords = ref None
28+
let raise_embedded_errors_flag = ref false
2829

2930
let ghost =
3031
object
3132
inherit Ast_traverse.map
3233
method! location loc = { loc with loc_ghost = true }
3334
end
3435

36+
let raise_embedded_errors =
37+
object
38+
inherit Ast_traverse.map as super
39+
40+
method! extension extension =
41+
if !raise_embedded_errors_flag then
42+
extension |> Location.Error.of_extension
43+
|> Option.iter ~f:Location.Error.raise;
44+
super#extension extension
45+
end
46+
3547
let chop_prefix ~prefix x =
3648
if String.is_prefix ~prefix x then
3749
Some (String.drop_prefix x (String.length prefix))
@@ -696,7 +708,9 @@ let map_structure_gen st ~tool_name ~hook ~expect_mismatch_handler ~input_name
696708
~dropped_so_far:Attribute.dropped_so_far_structure ~hook
697709
~expect_mismatch_handler ~input_name ~embed_errors
698710
in
699-
st |> lint lint_errors |> cookies_and_check |> with_errors (List.rev errors)
711+
st |> lint lint_errors |> cookies_and_check
712+
|> with_errors (List.rev errors)
713+
|> raise_embedded_errors#structure
700714

701715
let map_structure st =
702716
match
@@ -772,7 +786,9 @@ let map_signature_gen sg ~tool_name ~hook ~expect_mismatch_handler ~input_name
772786
~dropped_so_far:Attribute.dropped_so_far_signature ~hook
773787
~expect_mismatch_handler ~input_name ~embed_errors
774788
in
775-
sg |> lint lint_errors |> cookies_and_check |> with_errors (List.rev errors)
789+
sg |> lint lint_errors |> cookies_and_check
790+
|> with_errors (List.rev errors)
791+
|> raise_embedded_errors#signature
776792

777793
let map_signature sg =
778794
match
@@ -1320,6 +1336,9 @@ let shared_args =
13201336
applied before all impl and intf." );
13211337
("-cookie", Arg.String set_cookie, "NAME=EXPR Set the cookie NAME to EXPR");
13221338
("--cookie", Arg.String set_cookie, " Same as -cookie");
1339+
( "-raise-embedded-errors",
1340+
Arg.Set raise_embedded_errors_flag,
1341+
" Raise the first embedded error found in the processed AST" );
13231342
]
13241343

13251344
let () =

Diff for: src/location.mli

+4
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ module Error : sig
8787

8888
val get_location : t -> location
8989
(** Find out where the error is located. *)
90+
91+
val of_extension : extension -> t option
92+
(** Convert an extension point to an error. Extension points must have the
93+
exact form as created by [to_extension]. *)
9094
end
9195
with type location := t
9296

Diff for: test/driver/run_as_ppx_rewriter/run.t

+2
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ The only possible usage is [extra_args] <infile> <outfile>...
6363
-no-merge Do not merge context free transformations (better for debugging rewriters). As a result, the context-free transformations are not all applied before all impl and intf.
6464
-cookie NAME=EXPR Set the cookie NAME to EXPR
6565
--cookie Same as -cookie
66+
-raise-embedded-errors Raise the first embedded error found in the processed AST
6667
-help Display this list of options
6768
--help Display this list of options
6869
[2]
@@ -84,5 +85,6 @@ The only exception is consulting help
8485
-no-merge Do not merge context free transformations (better for debugging rewriters). As a result, the context-free transformations are not all applied before all impl and intf.
8586
-cookie NAME=EXPR Set the cookie NAME to EXPR
8687
--cookie Same as -cookie
88+
-raise-embedded-errors Raise the first embedded error found in the processed AST
8789
-help Display this list of options
8890
--help Display this list of options

Diff for: test/error_embedding/run.t

+12
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,15 @@ Error nodes are generated when dependent derivers are not applied.
7575
let _ = "derived_string"
7676
let _ = "derived_string"
7777
end[@@ocaml.doc "@inline"][@@merlin.hide ]
78+
79+
Flag `-raise-embedded-errors` raises the first embedded error in the AST.
80+
81+
$ echo "let () = ()" > embedded_error.ml
82+
$ echo "module _ = struct [%%ocaml.error \"error 1\"] end" >> embedded_error.ml
83+
$ echo "[%%ocaml.error \"error 2\"]" >> embedded_error.ml
84+
$ ./extender.exe embedded_error.ml -raise-embedded-errors
85+
File "embedded_error.ml", line 2, characters 21-32:
86+
2 | module _ = struct [%%ocaml.error "error 1"] end
87+
^^^^^^^^^^^
88+
Error: error 1
89+
[1]

0 commit comments

Comments
 (0)