Skip to content

Commit 9cf40a2

Browse files
committed
remove Pparse -- prepare deeper integration in front-end
1 parent 8834a45 commit 9cf40a2

File tree

5 files changed

+237
-164
lines changed

5 files changed

+237
-164
lines changed

jscomp/core/js_implementation.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ let after_parsing_sig ppf outputprefix ast =
103103

104104
let interface ppf fname outputprefix =
105105
Compmisc.init_path false;
106-
Pparse.parse_interface ~tool_name:Js_config.tool_name ppf fname
106+
Pparse_driver.parse_interface ~tool_name:Js_config.tool_name ppf fname
107107
|> Ppx_entry.rewrite_signature
108108
|> print_if_pipe ppf Clflags.dump_parsetree Printast.interface
109109
|> print_if_pipe ppf Clflags.dump_source Pprintast.signature
@@ -201,7 +201,7 @@ let after_parsing_impl ppf outputprefix (ast : Parsetree.structure) =
201201
end
202202
let implementation ppf fname outputprefix =
203203
Compmisc.init_path false;
204-
Pparse.parse_implementation ~tool_name:Js_config.tool_name ppf fname
204+
Pparse_driver.parse_implementation ~tool_name:Js_config.tool_name ppf fname
205205
|> Ppx_entry.rewrite_implementation
206206
|> print_if_pipe ppf Clflags.dump_parsetree Printast.implementation
207207
|> print_if_pipe ppf Clflags.dump_source Pprintast.structure

jscomp/core/pparse_driver.ml

Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
2+
3+
type error =
4+
| CannotRun of string
5+
| WrongMagic of string
6+
7+
exception Error of error
8+
9+
(* Optionally preprocess a source file *)
10+
11+
let call_external_preprocessor sourcefile pp =
12+
let tmpfile = Filename.temp_file "ocamlpp" "" in
13+
let comm = Printf.sprintf "%s %s > %s"
14+
pp (Filename.quote sourcefile) tmpfile
15+
in
16+
if Ccomp.command comm <> 0 then begin
17+
Misc.remove_file tmpfile;
18+
raise (Error (CannotRun comm));
19+
end;
20+
tmpfile
21+
22+
let preprocess sourcefile =
23+
match !Clflags.preprocessor with
24+
None -> sourcefile
25+
| Some pp ->
26+
call_external_preprocessor sourcefile pp
27+
28+
29+
let remove_preprocessed inputfile =
30+
match !Clflags.preprocessor with
31+
None -> ()
32+
| Some _ -> Misc.remove_file inputfile
33+
34+
type 'a ast_kind =
35+
| Structure : Parsetree.structure ast_kind
36+
| Signature : Parsetree.signature ast_kind
37+
38+
let magic_of_kind : type a . a ast_kind -> string = function
39+
| Structure -> Config.ast_impl_magic_number
40+
| Signature -> Config.ast_intf_magic_number
41+
42+
(* Note: some of the functions here should go to Ast_mapper instead,
43+
which would encapsulate the "binary AST" protocol. *)
44+
45+
let write_ast (type a) (kind : a ast_kind) fn (ast : a) =
46+
let oc = open_out_bin fn in
47+
output_string oc (magic_of_kind kind);
48+
output_value oc (!Location.input_name : string);
49+
output_value oc (ast : a);
50+
close_out oc
51+
52+
let apply_rewriter kind fn_in ppx =
53+
let magic = magic_of_kind kind in
54+
let fn_out = Filename.temp_file "camlppx" "" in
55+
let comm =
56+
Printf.sprintf "%s %s %s" ppx (Filename.quote fn_in) (Filename.quote fn_out)
57+
in
58+
let ok = Ccomp.command comm = 0 in
59+
Misc.remove_file fn_in;
60+
if not ok then begin
61+
Misc.remove_file fn_out;
62+
raise (Error (CannotRun comm));
63+
end;
64+
if not (Sys.file_exists fn_out) then
65+
raise (Error (WrongMagic comm));
66+
(* check magic before passing to the next ppx *)
67+
let ic = open_in_bin fn_out in
68+
let buffer =
69+
try really_input_string ic (String.length magic) with End_of_file -> "" in
70+
close_in ic;
71+
if buffer <> magic then begin
72+
Misc.remove_file fn_out;
73+
raise (Error (WrongMagic comm));
74+
end;
75+
fn_out
76+
77+
let read_ast (type a) (kind : a ast_kind) fn : a =
78+
let ic = open_in_bin fn in
79+
try
80+
let magic = magic_of_kind kind in
81+
let buffer = really_input_string ic (String.length magic) in
82+
assert(buffer = magic); (* already checked by apply_rewriter *)
83+
Location.set_input_name @@ (input_value ic : string);
84+
let ast = (input_value ic : a) in
85+
close_in ic;
86+
Misc.remove_file fn;
87+
ast
88+
with exn ->
89+
close_in ic;
90+
Misc.remove_file fn;
91+
raise exn
92+
93+
let rewrite kind ppxs ast =
94+
let fn = Filename.temp_file "camlppx" "" in
95+
write_ast kind fn ast;
96+
let fn = List.fold_left (apply_rewriter kind) fn (List.rev ppxs) in
97+
read_ast kind fn
98+
99+
let apply_rewriters_str ?(restore = true) ~tool_name ast =
100+
match !Clflags.all_ppx with
101+
| [] -> ast
102+
| ppxs ->
103+
ast
104+
|> Ast_mapper.add_ppx_context_str ~tool_name
105+
|> rewrite Structure ppxs
106+
|> Ast_mapper.drop_ppx_context_str ~restore
107+
108+
let apply_rewriters_sig ?(restore = true) ~tool_name ast =
109+
match !Clflags.all_ppx with
110+
| [] -> ast
111+
| ppxs ->
112+
ast
113+
|> Ast_mapper.add_ppx_context_sig ~tool_name
114+
|> rewrite Signature ppxs
115+
|> Ast_mapper.drop_ppx_context_sig ~restore
116+
117+
let apply_rewriters ?restore ~tool_name
118+
(type a) (kind : a ast_kind) (ast : a) : a =
119+
match kind with
120+
| Structure ->
121+
apply_rewriters_str ?restore ~tool_name ast
122+
| Signature ->
123+
apply_rewriters_sig ?restore ~tool_name ast
124+
125+
(* Parse a file or get a dumped syntax tree from it *)
126+
127+
exception Outdated_version
128+
129+
let open_and_check_magic inputfile ast_magic =
130+
let ic = open_in_bin inputfile in
131+
let is_ast_file =
132+
try
133+
let buffer = really_input_string ic (String.length ast_magic) in
134+
if buffer = ast_magic then true
135+
else if String.sub buffer 0 9 = String.sub ast_magic 0 9 then
136+
raise Outdated_version
137+
else false
138+
with
139+
Outdated_version ->
140+
Misc.fatal_error "OCaml and preprocessor have incompatible versions"
141+
| _ -> false
142+
in
143+
(ic, is_ast_file)
144+
145+
let parse (type a) (kind : a ast_kind) lexbuf : a =
146+
match kind with
147+
| Structure -> Parse.implementation lexbuf
148+
| Signature -> Parse.interface lexbuf
149+
150+
let file_aux ppf ~tool_name inputfile (type a) (parse_fun : _ -> a)
151+
(kind : a ast_kind) =
152+
let ast_magic = magic_of_kind kind in
153+
let (ic, is_ast_file) = open_and_check_magic inputfile ast_magic in
154+
let ast =
155+
try
156+
if is_ast_file then begin
157+
if !Clflags.fast then
158+
(* FIXME make this a proper warning *)
159+
Format.fprintf ppf "@[Warning: %s@]@."
160+
"option -unsafe used with a preprocessor returning a syntax tree";
161+
Location.set_input_name (input_value ic : string);
162+
(input_value ic : a)
163+
end else begin
164+
seek_in ic 0;
165+
let lexbuf = Lexing.from_channel ic in
166+
Location.init lexbuf inputfile;
167+
parse_fun lexbuf
168+
end
169+
with x -> close_in ic; raise x
170+
in
171+
close_in ic;
172+
apply_rewriters ~restore:false ~tool_name kind ast
173+
174+
175+
let report_error ppf = function
176+
| CannotRun cmd ->
177+
Format.fprintf ppf "Error while running external preprocessor@.\
178+
Command line: %s@." cmd
179+
| WrongMagic cmd ->
180+
Format.fprintf ppf "External preprocessor does not produce a valid file@.\
181+
Command line: %s@." cmd
182+
183+
let () =
184+
Location.register_error_of_exn
185+
(function
186+
| Error err -> Some (Location.error_of_printer_file report_error err)
187+
| _ -> None
188+
)
189+
190+
let parse_file ~tool_name kind ppf sourcefile =
191+
Location.set_input_name sourcefile;
192+
let inputfile = preprocess sourcefile in
193+
let ast =
194+
try file_aux ppf ~tool_name inputfile (parse kind) kind
195+
with exn ->
196+
remove_preprocessed inputfile;
197+
raise exn
198+
in
199+
remove_preprocessed inputfile;
200+
ast
201+
202+
203+
204+
let parse_implementation ppf ~tool_name sourcefile =
205+
parse_file ~tool_name
206+
Structure ppf sourcefile
207+
let parse_interface ppf ~tool_name sourcefile =
208+
parse_file ~tool_name
209+
Signature ppf sourcefile

jscomp/core/pparse_driver.mli

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
2+
3+
val parse_implementation:
4+
Format.formatter ->
5+
tool_name:string ->
6+
string -> Parsetree.structure
7+
8+
9+
val parse_interface:
10+
Format.formatter ->
11+
tool_name:string ->
12+
string -> Parsetree.signature

jscomp/ext/literals.mli

Lines changed: 0 additions & 149 deletions
This file was deleted.

0 commit comments

Comments
 (0)