2 * Copyright (c) 2016, Facebook, Inc.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
12 * Usage: hh_parse [OPTIONS] [FILES]
14 * --full-fidelity-json
15 * --full-fidelity-json-parse-tree
16 * --full-fidelity-errors
17 * --full-fidelity-errors-all
18 * --full-fidelity-ast-s-expression
24 * TODO: Parser for things other than scripts:
25 * types, expressions, statements, declarations, etc.
28 module Schema
= Full_fidelity_schema
29 module SyntaxError
= Full_fidelity_syntax_error
31 Full_fidelity_syntax_tree.WithSyntax
(Full_fidelity_positioned_syntax
)
32 module SourceText
= Full_fidelity_source_text
34 Full_fidelity_parser_errors.WithSyntax
(Full_fidelity_positioned_syntax
)
35 open FullFidelityParseArgs
37 (* Prints a single FFP error. *)
38 let print_full_fidelity_error source_text error
=
40 SyntaxError.to_positioned_string
42 (SourceText.offset_to_position source_text
)
44 Printf.printf
"%s\n" text
46 let print_ast_check_errors errors
=
47 let error_list = Errors.get_error_list errors
in
50 let text = Errors.to_string
(User_error.to_absolute e
) in
52 Core_kernel.String.is_substring
54 ~substring
:SyntaxError.this_in_static
55 || Core_kernel.String.is_substring
57 ~substring
:SyntaxError.toplevel_await_use
59 Printf.eprintf
"%s\n%!" text)
62 let handle_existing_file args filename
=
63 let popt = FullFidelityParseArgs.to_parser_options args
in
64 (* Parse with the full fidelity parser *)
65 let file = Relative_path.create
Relative_path.Dummy filename
in
66 let source_text = SourceText.from_file
file in
67 let mode = Full_fidelity_parser.parse_mode
source_text in
69 args
.codegen
|| args
.full_fidelity_errors
|| args
.full_fidelity_errors_all
72 FullFidelityParseArgs.to_parser_env
73 (* When print_errors is true, the leaked tree will be passed to ParserErrors,
74 * which will consume it. *)
75 ~leak_rust_tree
:print_errors
79 let syntax_tree = SyntaxTree.make ~
env source_text in
80 let editable = SyntaxTransforms.editable_from_positioned
syntax_tree in
81 if args
.show_file_name
then Printf.printf
"%s\n" filename
;
82 (if args
.program_text
then
83 let text = Full_fidelity_editable_syntax.text editable in
84 Printf.printf
"%s\n" text);
85 (if args
.pretty_print
then
86 let pretty = Libhackfmt.format_tree
syntax_tree in
87 Printf.printf
"%s\n" pretty);
88 (if args
.generate_hhi
then
89 let hhi = Generate_hhi.go
editable in
90 Printf.printf
"%s\n" hhi);
94 if args
.full_fidelity_errors_all
then
99 let hhvm_compat_mode =
101 ParserErrors.HHVMCompat
103 ParserErrors.NoCompat
106 ParserErrors.make_env
110 ~codegen
:args
.codegen
113 let errors = ParserErrors.parse_errors
error_env in
114 List.iter
(print_full_fidelity_error source_text) errors);
116 let dump_needed = args
.full_fidelity_ast_s_expr
in
118 if dump_needed || print_errors then (
120 Full_fidelity_ast.make_env
121 ~codegen
:args
.codegen
122 ~php5_compat_mode
:args
.php5_compat_mode
123 ~elaborate_namespaces
:args
.elaborate_namespaces
124 ~include_line_comments
:args
.include_line_comments
125 ~keep_errors
:(args
.keep_errors
|| print_errors)
126 ~quick_mode
:args
.quick_mode
128 ~fail_open
:args
.fail_open
133 Errors.do_
(fun () -> Full_fidelity_ast.from_file_with_legacy
env)
135 if print_errors then print_ast_check_errors errors;
138 | e
when print_errors ->
139 let err = Base.Exn.to_string e
in
140 let fn = Relative_path.suffix
file in
141 (* If we've already found a parsing error, it's okay for lowering to fail *)
142 if not
(Errors.currently_has_errors
()) then
144 "Warning, lowering failed for %s\n - error: %s\n"
155 let ast = res
.Parser_return.ast in
156 let str = Nast.show_program
ast in
157 Printf.printf
"%s\n" str
160 (if args
.full_fidelity_json_parse_tree
then
162 SyntaxTree.parse_tree_to_json
163 ~ignore_missing
:args
.ignore_missing_json
166 let str = Hh_json.json_to_string
json ~
pretty:args
.pretty_print_json
in
167 Printf.printf
"%s\n" str);
168 (if args
.full_fidelity_json
then
170 SyntaxTree.to_json ~ignore_missing
:args
.ignore_missing_json
syntax_tree
172 let str = Hh_json.json_to_string
json ~
pretty:args
.pretty_print_json
in
173 Printf.printf
"%s\n" str);
174 (if args
.full_fidelity_text_json
then
175 let json = Full_fidelity_editable_syntax.to_json
editable in
176 let str = Hh_json.json_to_string
json in
177 Printf.printf
"%s\n" str);
178 (if args
.full_fidelity_dot
then
179 let dot = Full_fidelity_editable_syntax.to_dot
editable false in
180 Printf.printf
"%s\n" dot);
181 if args
.full_fidelity_dot_edges
then
182 let dot = Full_fidelity_editable_syntax.to_dot
editable true in
183 Printf.printf
"%s\n" dot
185 let handle_file args filename
=
186 if Path.file_exists
(Path.make filename
) then
187 handle_existing_file args filename
189 Printf.printf
"File %s does not exist.\n" filename
191 let rec main args files
=
193 let schema = Schema.schema_as_json
() in
194 Printf.printf
"%s\n" schema);
198 Unix.handle_unix_error
(handle_file args
) file;
202 let args = parse_args
() in
203 EventLogger.init_fake
();
204 let handle = SharedMem.init ~num_workers
:0 SharedMem.default_config
in
205 ignore
(handle : SharedMem.handle);