From af1690e34bec0d82ad25585a2781fe2d37e886e9 Mon Sep 17 00:00:00 2001 From: Katy Voor Date: Tue, 18 Jun 2019 11:43:59 -0700 Subject: [PATCH] Move read from append check to nast_check Summary: Moves the reading from append checks done in nastCheck -> nast_check. Reviewed By: kmeht Differential Revision: D15846485 fbshipit-source-id: a7ddc9b536239d4b89b136d3f2d620e05ac8b03c --- hphp/hack/src/typing/nastCheck.ml | 30 +++++++--------------- hphp/hack/src/typing/nast_check/nast_check.ml | 1 + .../typing/nast_check/read_from_append_check.ml | 21 +++++++++++++++ hphp/hack/src/typing/nast_check_env.ml | 2 ++ hphp/hack/src/typing/nast_visitor.ml | 8 ++++++ 5 files changed, 41 insertions(+), 21 deletions(-) create mode 100644 hphp/hack/src/typing/nast_check/read_from_append_check.ml diff --git a/hphp/hack/src/typing/nastCheck.ml b/hphp/hack/src/typing/nastCheck.ml index 76baca39b0f..83b7aa022c0 100644 --- a/hphp/hack/src/typing/nastCheck.ml +++ b/hphp/hack/src/typing/nastCheck.ml @@ -46,7 +46,6 @@ type env = { class_name: string option; class_kind: Ast.class_kind option; typedef_tparams : Nast.tparam list; - is_array_append_allowed: bool; is_reactive: bool; (* The enclosing function is reactive *) tenv: Env.env; } @@ -352,8 +351,7 @@ let fun_is_reactive user_attributes = List.exists user_attributes ~f:is_some_reactivity_attribute let rec fun_ tenv f named_body = - let env = { is_array_append_allowed = false; - class_name = None; class_kind = None; + let env = { class_name = None; class_kind = None; typedef_tparams = []; tenv = tenv; function_name = None; @@ -495,8 +493,7 @@ and check_happly unchecked_tparams env h = and class_ tenv c = let cname = Some (snd c.c_name) in - let env = { is_array_append_allowed = false; - class_name = cname; + let env = { class_name = cname; class_kind = Some c.c_kind; typedef_tparams = []; is_reactive = false; @@ -716,17 +713,12 @@ and expr_ env _p = function () | Clone e -> expr env e; () | Obj_get (e1, e2, _) -> - let env' = {env with is_array_append_allowed = false} in - expr env' e1; - expr env' e2; + expr env e1; + expr env e2; () - | Array_get ((p, _), None) when not env.is_array_append_allowed -> - Errors.reading_from_append p; - () | Array_get (e, eopt) -> - let env' = {env with is_array_append_allowed = false} in - expr env' e; - maybe expr env' eopt; + expr env e; + maybe expr env eopt; () | Call (_, e, _, el, uel) -> expr env e; @@ -773,11 +765,8 @@ and expr_ env _p = function hint env h; expr env e; () - | Binop (op, e1, e2) -> - let lvalue_env = match op with - | Ast.Eq _ -> { env with is_array_append_allowed = true } - | _ -> env in - expr lvalue_env e1; + | Binop (_, e1, e2) -> + expr env e1; expr env e2; () | Eif (e1, None, e3) -> @@ -841,8 +830,7 @@ and field env (e1, e2) = () let typedef tenv t = - let env = { is_array_append_allowed = false; - class_name = None; class_kind = None; + let env = { class_name = None; class_kind = None; function_name = None; (* Since typedefs cannot have constraints we shouldn't check * if its type params satisfy the constraints of any tapply it diff --git a/hphp/hack/src/typing/nast_check/nast_check.ml b/hphp/hack/src/typing/nast_check/nast_check.ml index 80cfaca8a95..ac02fb4e355 100644 --- a/hphp/hack/src/typing/nast_check/nast_check.ml +++ b/hphp/hack/src/typing/nast_check/nast_check.ml @@ -15,6 +15,7 @@ let visitor = Nast_visitor.iter_with [ Class_tparams_check.handler; Control_context_check.handler; Pocket_universes_check.handler; + Read_from_append_check.handler; ] let program = visitor#go diff --git a/hphp/hack/src/typing/nast_check/read_from_append_check.ml b/hphp/hack/src/typing/nast_check/read_from_append_check.ml new file mode 100644 index 00000000000..a51aec2f1d7 --- /dev/null +++ b/hphp/hack/src/typing/nast_check/read_from_append_check.ml @@ -0,0 +1,21 @@ +(** + * Copyright (c) 2018, Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the "hack" directory of this source tree. + * + *) + +open Nast +open Nast_check_env + +let handler = object + inherit Nast_visitor.handler_base + + method! at_expr env s = + match (snd s) with + | Array_get ((p, _), None) when not env.array_append_allowed -> + Errors.reading_from_append p + | _ -> () +end diff --git a/hphp/hack/src/typing/nast_check_env.ml b/hphp/hack/src/typing/nast_check_env.ml index 6983b808f1b..d0a88169689 100644 --- a/hphp/hack/src/typing/nast_check_env.ml +++ b/hphp/hack/src/typing/nast_check_env.ml @@ -28,6 +28,7 @@ type env = { is_finally: bool; control_context: control_context; rx_is_enabled_allowed: bool; + array_append_allowed: bool; } let is_some_reactivity_attribute { ua_name = (_, name); _ } = @@ -75,6 +76,7 @@ let get_empty_env () = { is_finally = false; control_context = Toplevel; rx_is_enabled_allowed = false; + array_append_allowed = false; } let def_env x = diff --git a/hphp/hack/src/typing/nast_visitor.ml b/hphp/hack/src/typing/nast_visitor.ml index 984e222a8b1..563127fb929 100644 --- a/hphp/hack/src/typing/nast_visitor.ml +++ b/hphp/hack/src/typing/nast_visitor.ml @@ -33,6 +33,14 @@ class virtual iter = object (self) method! on_Switch env = super#on_Switch ({ env with control_context = SwitchContext }) method! on_Efun env = super#on_Efun ({ env with is_finally = false; control_context = Toplevel }) method! on_Lfun env = super#on_Lfun ({ env with is_finally = false; control_context = Toplevel }) + method! on_Obj_get env = super#on_Obj_get ({ env with array_append_allowed = false }) + method! on_Array_get env = super#on_Array_get ({ env with array_append_allowed = false }) + method! on_Binop env op e1 e2= + match op with + | Ast.Eq _ -> + self#on_expr { env with array_append_allowed = true } e1; + self#on_expr env e2 + | _ -> super#on_Binop env op e1 e2 method! on_func_body env fb = match fb.fb_ast with -- 2.11.4.GIT