From c907f49a9bcc4ae69a49e03e01359e37369e2556 Mon Sep 17 00:00:00 2001 From: Thomas Jiang Date: Mon, 7 Oct 2019 17:00:38 -0700 Subject: [PATCH] Remove from_text from full_fidelity_ast Summary: When the parser is rustified, the legacy ast should hopefully disappear along with it. So I am trying to front run some of that work by removing existing references to the legacy by containing them to an implementation detail in lowering in full_fidelity_ast and removing calls that expose the legacy ast in the mli file. That way, when the lowerer is ported and goes straight to the aast, it can just be a drop in for everything. This diff removes `from_text` from the interface and attempts to replace it with a `from_text_to_empty_tast` function that provides the functionality for `hh_single_compile` to take a file and get an untyped tast. Some tests were modified: Tests previously printing out the legacy ast now print out the equivalent aast. Tests that previously had codepaths with trait resolution (`insteadof`) (`use as`) were deleted as those are php features that Hack does not support. Reviewed By: shiqicao Differential Revision: D17695710 fbshipit-source-id: ae7ad41851b88e04e3b4039b5fb1f8fe6d94ad72 --- hphp/hack/src/hh_single_compile.ml | 103 +++++++++-------------------- hphp/hack/src/parser/dune.inc | 1 + hphp/hack/src/parser/full_fidelity_ast.ml | 31 ++++++++- hphp/hack/src/parser/full_fidelity_ast.mli | 16 ++++- hphp/hack/src/providers/ast_provider.ml | 6 +- hphp/hack/src/typing/dune | 1 - hphp/hack/test/rust/rust_ocaml_test.ml | 6 +- 7 files changed, 83 insertions(+), 81 deletions(-) diff --git a/hphp/hack/src/hh_single_compile.ml b/hphp/hack/src/hh_single_compile.ml index fb41c0cf121..13b83abbcf7 100644 --- a/hphp/hack/src/hh_single_compile.ml +++ b/hphp/hack/src/hh_single_compile.ml @@ -296,8 +296,8 @@ let parse_text compiler_options popt fn text = fn in let source_text = SourceText.make fn text in - let { Full_fidelity_ast.ast; Full_fidelity_ast.is_hh_file; _ } = - Full_fidelity_ast.from_text env source_text + let (ast, is_hh_file) = + Full_fidelity_ast.from_text_to_empty_tast env source_text in let () = write_stats_if_enabled ~compiler_options in (ast, is_hh_file) @@ -344,58 +344,19 @@ let log_fail compiler_options filename exc ~stack = ~mode:(mode_to_string compiler_options.mode) ~exc:(Caml.Printexc.to_string exc ^ "\n" ^ stack) -(* Maps an Ast to a Tast where every type is Tany - * Used to produce a Tast for unsafe code without inferring types for it. *) -let ast_to_tast_tany = - let tany = (Typing_reason.Rnone, Typing_defs.make_tany ()) in - let get_expr_annotation (p : Ast_defs.pos) = (p, tany) in - Ast_to_aast.convert_program - get_expr_annotation - Tast.HasUnsafeBlocks - Tast.dummy_saved_env - tany - -(** - * Converts a legacy ast (ast.ml) into a typed ast (tast.ml / aast.ml) - * so that codegen and typing both operate on the same ast structure. - * There are some errors that are not valid hack but are still expected - * to produce valid bytecode. These errors are caught during the conversion - * so as to match legacy behavior. - *) -let convert_to_tast ast = - let (errors, tast) = - let convert () = - let ast = ast_to_tast_tany ast in - if Hhbc_options.enable_pocket_universes !Hhbc_options.compiler_options - then - Pocket_universes.translate ast - else - ast - in - Errors.do_ convert - in - let handle_error _path error acc = - match Errors.get_code error with - (* Ignore these errors to match legacy AST behavior *) - | 2086 - (* Naming.MethodNeedsVisibility *) - - | 2102 - (* Naming.UnsupportedTraitUseAs *) - - | 2103 (* Naming.UnsupportedInsteadOf *) -> - acc - | _ (* Emit fatal parse otherwise *) -> - if acc = None then - let msg = snd (List.hd_exn (Errors.to_list error)) in - Some (Errors.get_pos error, msg) - else - acc - in - let result = Errors.fold_errors ~init:None ~f:handle_error errors in - match result with - | Some error -> Error error - | None -> Ok tast +let handle_conversion_errors errors = + List.filter errors ~f:(fun error -> + match Errors.get_code error with + (* Ignore these errors to match legacy AST behavior *) + | 2086 + (* Naming.MethodNeedsVisibility *) + + | 2102 + (* Naming.UnsupportedTraitUseAs *) + + | 2103 (* Naming.UnsupportedInsteadOf *) -> + false + | _ (* Emit fatal parse otherwise *) -> true) let do_compile filename compiler_options popt fail_or_ast debug_time = let t = Unix.gettimeofday () in @@ -410,24 +371,26 @@ let do_compile filename compiler_options popt fail_or_ast debug_time = in let s = SyntaxError.message e in Emit_program.emit_fatal_program ~ignore_message:false error_t pos s - | `ParseResult (errors, (ast, is_hh_file)) -> - List.iter (Errors.get_error_list errors) (fun e -> + | `ParseResult (errors, (tast, is_hh_file)) -> + let error_list = Errors.get_error_list errors in + let error_list = handle_conversion_errors error_list in + List.iter error_list (fun e -> P.eprintf "%s\n%!" (Errors.to_string (Errors.to_absolute e))); - if Errors.is_empty errors then - match convert_to_tast ast with - | Ok tast -> - Emit_program.from_ast - ~is_hh_file - ~is_evaled:(is_file_path_for_evaled_code filename) - ~for_debugger_eval:compiler_options.for_debugger_eval - ~popt + if List.is_empty error_list then + let tast = + if + Hhbc_options.enable_pocket_universes !Hhbc_options.compiler_options + then + Pocket_universes.translate tast + else tast - | Error (pos, msg) -> - Emit_program.emit_fatal_program - ~ignore_message:false - Hhbc_ast.FatalOp.Parse - pos - msg + in + Emit_program.from_ast + ~is_hh_file + ~is_evaled:(is_file_path_for_evaled_code filename) + ~for_debugger_eval:compiler_options.for_debugger_eval + ~popt + tast else Emit_program.emit_fatal_program ~ignore_message:true diff --git a/hphp/hack/src/parser/dune.inc b/hphp/hack/src/parser/dune.inc index 56aedbc2c23..c463e286c60 100644 --- a/hphp/hack/src/parser/dune.inc +++ b/hphp/hack/src/parser/dune.inc @@ -107,6 +107,7 @@ partial_provider rust_lowerer_ffi rust_parser_ffi + typing_ast utils_lint utils_php_escape)) diff --git a/hphp/hack/src/parser/full_fidelity_ast.ml b/hphp/hack/src/parser/full_fidelity_ast.ml index 7c35ab9d952..efbde08304a 100644 --- a/hphp/hack/src/parser/full_fidelity_ast.ml +++ b/hphp/hack/src/parser/full_fidelity_ast.ml @@ -1966,7 +1966,7 @@ if there already is one, since that one will likely be better than this one. *) | (_, Some TK.HexadecimalLiteral) (* We allow underscores while lexing the integer literals. This gets rid of them before * the literal is created. *) - + | (_, Some TK.BinaryLiteral) -> Int (Str.global_replace underscore "" s) | (_, Some TK.FloatingLiteral) -> Float s @@ -3929,7 +3929,7 @@ if there already is one, since that one will likely be better than this one. *) let rec aux env acc = function | [] (* EOF happens only as the last token in the list. *) - + | [{ syntax = EndOfFile _; _ }] -> List.concat (List.rev acc) (* HaltCompiler stops processing the list in PHP but can be disabled in Hack *) @@ -4475,6 +4475,33 @@ let from_file (env : env) : result = let source_text = SourceText.from_file env.file in from_text env source_text +(** + * Converts a legacy ast (ast.ml) into a typed ast (tast.ml / aast.ml) + * so that codegen and typing both operate on the same ast structure. + * + * There are some errors that are not valid hack but are still expected + * to produce valid bytecode. hh_single_compile is expected to catch + * these errors. + *) +let from_text_to_custom_aast env source_text to_ex fb en hi = + let legacy_ast_result = from_text env source_text in + let tast = + Ast_to_aast.convert_program to_ex fb en hi legacy_ast_result.ast + in + let is_hh_file = legacy_ast_result.is_hh_file in + (tast, is_hh_file) + +let from_text_to_empty_tast env source_text = + let tany = (Typing_reason.Rnone, Typing_defs.make_tany ()) in + let get_expr_annotation (p : Ast_defs.pos) = (p, tany) in + from_text_to_custom_aast + env + source_text + get_expr_annotation + Tast.HasUnsafeBlocks + Tast.dummy_saved_env + tany + (*****************************************************************************( * Backward compatibility matter (should be short-lived) )*****************************************************************************) diff --git a/hphp/hack/src/parser/full_fidelity_ast.mli b/hphp/hack/src/parser/full_fidelity_ast.mli index 9415f9fd7ec..cc8370ac0cd 100644 --- a/hphp/hack/src/parser/full_fidelity_ast.mli +++ b/hphp/hack/src/parser/full_fidelity_ast.mli @@ -62,13 +62,25 @@ val parse_text : Full_fidelity_source_text.t -> FileInfo.mode option * PositionedSyntaxTree.t -val from_text : env -> Full_fidelity_source_text.t -> result - val from_text_rust : env -> Full_fidelity_source_text.t -> rust_result val from_file : env -> result val from_text_with_legacy : env -> string -> Parser_return.t + +val from_text_to_custom_aast : + env -> + Full_fidelity_source_text.t -> + (Ast_defs.pos -> 'ex) -> + 'fb -> + 'en -> + 'hi -> + ('ex, 'fb, 'en, 'hi) Aast.program * bool + +(* Only for hh_single_compile at the moment. *) +val from_text_to_empty_tast : + env -> Full_fidelity_source_text.t -> Tast.program * bool + (** * Here only for backward compatibility. Consider these deprecated. *) diff --git a/hphp/hack/src/providers/ast_provider.ml b/hphp/hack/src/providers/ast_provider.ml index dfe6970d242..293479ee229 100644 --- a/hphp/hack/src/providers/ast_provider.ml +++ b/hphp/hack/src/providers/ast_provider.ml @@ -57,9 +57,11 @@ let parse_file_input let source = ServerCommandTypesUtils.source_tree_of_file_input file_input in - Full_fidelity_ast.from_text parser_env source + Full_fidelity_ast.from_text_with_legacy + parser_env + source.Full_fidelity_source_text.text in - let ast = Ast_to_nast.convert result.Full_fidelity_ast.ast in + let ast = result.Parser_return.ast in let ast = if Relative_path.prefix file_name = Relative_path.Hhi diff --git a/hphp/hack/src/typing/dune b/hphp/hack/src/typing/dune index 09635f3d2c4..7776f2cc279 100644 --- a/hphp/hack/src/typing/dune +++ b/hphp/hack/src/typing/dune @@ -188,7 +188,6 @@ errors naming_attributes nast - parser typing_defs typechecker_options) (preprocess (pps ppx_deriving.std))) diff --git a/hphp/hack/test/rust/rust_ocaml_test.ml b/hphp/hack/test/rust/rust_ocaml_test.ml index 3f6d74b3fb5..2fde80dda16 100644 --- a/hphp/hack/test/rust/rust_ocaml_test.ml +++ b/hphp/hack/test/rust/rust_ocaml_test.ml @@ -537,10 +537,8 @@ module LowererTest_ = struct (Errors.is_hh_fixme := (fun _ _ -> false)); (Errors.get_hh_fixme_pos := (fun _ _ -> None)); (Errors.is_hh_fixme_disallowed := (fun _ _ -> false)); - let result = Lowerer.from_text lower_env source_text in - let (_err, aast) = - Errors.do_ (fun () -> - Ast_to_aast.convert_program i () () () result.Lowerer.ast) + let (aast, _) = + Lowerer.from_text_to_custom_aast lower_env source_text i () () () in aast in -- 2.11.4.GIT