Skip to content

Commit c8e4904

Browse files
committed
Hook in ast converters.
When a ppx is applied: 1 Parsetree is converted to Parsetree0 2 the ppx is run 3 the result is converted to Parsetree
1 parent 37fdb27 commit c8e4904

File tree

3 files changed

+47
-35
lines changed

3 files changed

+47
-35
lines changed

compiler/common/ml_binary.ml

Lines changed: 26 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,29 +24,33 @@
2424

2525
type _ kind = Ml : Parsetree.structure kind | Mli : Parsetree.signature kind
2626

27-
(** [read_ast kind ic] assume [ic] channel is
28-
in the right position *)
29-
let read_ast (type t) (kind : t kind) ic : t =
30-
let magic =
31-
match kind with
32-
| Ml -> Config.ast_impl_magic_number
33-
| Mli -> Config.ast_intf_magic_number
34-
in
35-
let buffer = really_input_string ic (String.length magic) in
36-
assert (buffer = magic);
37-
(* already checked by apply_rewriter *)
38-
Location.set_input_name (input_value ic);
39-
input_value ic
27+
type ast0 = Impl of Parsetree0.structure | Intf of Parsetree0.signature
4028

41-
let write_ast (type t) (kind : t kind) (fname : string) (pt : t) oc =
42-
let magic =
43-
match kind with
44-
| Ml -> Config.ast_impl_magic_number
45-
| Mli -> Config.ast_intf_magic_number
46-
in
47-
output_string oc magic;
48-
output_value oc fname;
49-
output_value oc pt
29+
let magic_of_ast0 : ast0 -> string = function
30+
| Impl _ -> Config.ast_impl_magic_number
31+
| Intf _ -> Config.ast_intf_magic_number
32+
33+
let to_ast0 : type a. a kind -> a -> ast0 =
34+
fun kind ast ->
35+
match kind with
36+
| Ml ->
37+
Impl
38+
(Ast_mapper_to0.default_mapper.structure Ast_mapper_to0.default_mapper ast)
39+
| Mli ->
40+
Intf
41+
(Ast_mapper_to0.default_mapper.signature Ast_mapper_to0.default_mapper ast)
42+
43+
let ast0_to_structure : ast0 -> Parsetree.structure = function
44+
| Impl str0 ->
45+
Ast_mapper_from0.default_mapper.structure Ast_mapper_from0.default_mapper
46+
str0
47+
| Intf _ -> assert false
48+
49+
let ast0_to_signature : ast0 -> Parsetree.signature = function
50+
| Impl _ -> assert false
51+
| Intf sig0 ->
52+
Ast_mapper_from0.default_mapper.signature Ast_mapper_from0.default_mapper
53+
sig0
5054

5155
let magic_of_kind : type a. a kind -> string = function
5256
| Ml -> Config.ast_impl_magic_number

compiler/common/ml_binary.mli

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@
2727
*)
2828
type _ kind = Ml : Parsetree.structure kind | Mli : Parsetree.signature kind
2929

30-
val read_ast : 'a kind -> in_channel -> 'a
31-
32-
val write_ast : 'a kind -> string -> 'a -> out_channel -> unit
30+
type ast0 = Impl of Parsetree0.structure | Intf of Parsetree0.signature
3331

3432
val magic_of_kind : 'a kind -> string
33+
val magic_of_ast0 : ast0 -> string
34+
val to_ast0 : 'a kind -> 'a -> ast0
35+
val ast0_to_structure : ast0 -> Parsetree.structure
36+
val ast0_to_signature : ast0 -> Parsetree.signature

compiler/core/cmd_ppx_apply.ml

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,13 @@
2424
(* Note: some of the functions here should go to Ast_mapper instead,
2525
which would encapsulate the "binary AST" protocol. *)
2626

27-
let write_ast (type a) (kind : a Ml_binary.kind) fn (ast : a) =
27+
let write_ast fn (ast0 : Ml_binary.ast0) =
2828
let oc = open_out_bin fn in
29-
output_string oc (Ml_binary.magic_of_kind kind);
29+
output_string oc (Ml_binary.magic_of_ast0 ast0);
3030
output_value oc (!Location.input_name : string);
31-
output_value oc (ast : a);
31+
(match ast0 with
32+
| Ml_binary.Impl ast -> output_value oc (ast : Parsetree0.structure)
33+
| Ml_binary.Intf ast -> output_value oc (ast : Parsetree0.signature));
3234
close_out oc
3335

3436
let temp_ppx_file () =
@@ -53,25 +55,29 @@ let apply_rewriter kind fn_in ppx =
5355
fn_out
5456

5557
(* This is a fatal error, no need to protect it *)
56-
let read_ast (type a) (kind : a Ml_binary.kind) fn : a =
58+
let read_ast (type a) (kind : a Ml_binary.kind) fn : Ml_binary.ast0 =
5759
let ic = open_in_bin fn in
5860
let magic = Ml_binary.magic_of_kind kind in
5961
let buffer = really_input_string ic (String.length magic) in
6062
assert (buffer = magic);
6163
(* already checked by apply_rewriter *)
6264
Location.set_input_name @@ (input_value ic : string);
63-
let ast = (input_value ic : a) in
65+
let ast0 =
66+
match kind with
67+
| Ml_binary.Ml -> Ml_binary.Impl (input_value ic : Parsetree0.structure)
68+
| Ml_binary.Mli -> Ml_binary.Intf (input_value ic : Parsetree0.signature)
69+
in
6470
close_in ic;
65-
66-
ast
71+
ast0
6772

6873
(** [ppxs] are a stack,
6974
[-ppx1 -ppx2 -ppx3]
7075
are stored as [-ppx3; -ppx2; -ppx1]
7176
[fold_right] happens to process the first one *)
7277
let rewrite kind ppxs ast =
7378
let fn_in = temp_ppx_file () in
74-
write_ast kind fn_in ast;
79+
let ast0 = Ml_binary.to_ast0 kind ast in
80+
write_ast fn_in ast0;
7581
let temp_files =
7682
List.fold_right
7783
(fun ppx fns ->
@@ -93,7 +99,7 @@ let apply_rewriters_str ?(restore = true) ~tool_name ast =
9399
| ppxs ->
94100
ast
95101
|> Ast_mapper.add_ppx_context_str ~tool_name
96-
|> rewrite Ml ppxs
102+
|> rewrite Ml ppxs |> Ml_binary.ast0_to_structure
97103
|> Ast_mapper.drop_ppx_context_str ~restore
98104

99105
let apply_rewriters_sig ?(restore = true) ~tool_name ast =
@@ -102,7 +108,7 @@ let apply_rewriters_sig ?(restore = true) ~tool_name ast =
102108
| ppxs ->
103109
ast
104110
|> Ast_mapper.add_ppx_context_sig ~tool_name
105-
|> rewrite Mli ppxs
111+
|> rewrite Mli ppxs |> Ml_binary.ast0_to_signature
106112
|> Ast_mapper.drop_ppx_context_sig ~restore
107113

108114
let apply_rewriters ?restore ~tool_name (type a) (kind : a Ml_binary.kind)

0 commit comments

Comments
 (0)