Add SetModule and fd_module defs
[hiphop-php.git] / hphp / hack / src / naming / nast.ml
blob1cb478b1551222ba0c0ccfd84741b01e43354855
1 (*
2 * Copyright (c) 2015, Facebook, Inc.
3 * All rights reserved.
5 * This source code is licensed under the MIT license found in the
6 * LICENSE file in the "hack" directory of this source tree.
8 *)
10 open Hh_prelude
11 open Aast
12 module SN = Naming_special_names
14 let show_tprim =
15 Naming_special_names.Typehints.(
16 function
17 | Tnull -> null
18 | Tvoid -> void
19 | Tint -> int
20 | Tbool -> bool
21 | Tfloat -> float
22 | Tstring -> string
23 | Tnum -> num
24 | Tresource -> resource
25 | Tarraykey -> arraykey
26 | Tnoreturn -> noreturn)
28 type program = (unit, unit) Aast.program [@@deriving show]
30 type def = (unit, unit) Aast.def
32 type expr = (unit, unit) Aast.expr [@@deriving eq, show]
34 type expr_ = (unit, unit) Aast.expr_
36 type stmt = (unit, unit) Aast.stmt
38 type block = (unit, unit) Aast.block
40 type user_attribute = (unit, unit) Aast.user_attribute [@@deriving eq, show]
42 type class_id_ = (unit, unit) Aast.class_id_ [@@deriving eq]
44 type class_ = (unit, unit) Aast.class_
46 type class_var = (unit, unit) Aast.class_var
48 type method_ = (unit, unit) Aast.method_
50 type file_attribute = (unit, unit) Aast.file_attribute
52 type fun_ = (unit, unit) Aast.fun_
54 type fun_def = (unit, unit) Aast.fun_def
56 type func_body = (unit, unit) Aast.func_body
58 type fun_param = (unit, unit) Aast.fun_param
60 type typedef = (unit, unit) Aast.typedef
62 type tparam = (unit, unit) Aast.tparam
64 type gconst = (unit, unit) Aast.gconst
66 type class_const = (unit, unit) Aast.class_const
68 type class_id = (unit, unit) Aast.class_id
70 type catch = (unit, unit) Aast.catch
72 type case = (unit, unit) Aast.case
74 type default_case = (unit, unit) Aast.default_case
76 type gen_case = (unit, unit) Aast.gen_case
78 type field = (unit, unit) Aast.field
80 type afield = (unit, unit) Aast.afield
82 type xhp_attribute = (unit, unit) Aast.xhp_attribute
84 type expression_tree = (unit, unit) Aast.expression_tree
86 type targ = unit Aast.targ
88 type sid = Aast.sid [@@deriving show]
90 type shape_field_name = Ast_defs.shape_field_name
92 type hint = Aast.hint
94 type class_hint = Aast.class_hint
96 type trait_hint = Aast.trait_hint
98 type xhp_attr_hint = Aast.xhp_attr_hint
100 type type_hint = unit Aast.type_hint
102 type module_def = (unit, unit) Aast.module_def
104 module ShapeMap = Ast_defs.ShapeMap
106 let class_id_to_str = function
107 | CIparent -> SN.Classes.cParent
108 | CIself -> SN.Classes.cSelf
109 | CIstatic -> SN.Classes.cStatic
110 | CIexpr (_, _, This) -> SN.SpecialIdents.this
111 | CIexpr (_, _, Lvar (_, x)) -> "$" ^ Local_id.to_string x
112 | CIexpr _ -> assert false
113 | CI (_, x) -> x
115 let is_kvc_kind name =
116 String.equal name SN.Collections.cMap
117 || String.equal name SN.Collections.cImmMap
118 || String.equal name SN.Collections.cDict
120 let get_kvc_kind name =
121 match name with
122 | x when String.equal x SN.Collections.cMap -> Map
123 | x when String.equal x SN.Collections.cImmMap -> ImmMap
124 | x when String.equal x SN.Collections.cDict -> Dict
125 | _ ->
126 Errors.internal_error Pos.none ("Invalid KeyValueCollection name: " ^ name);
129 let kvc_kind_to_name kind =
130 match kind with
131 | Map -> SN.Collections.cMap
132 | ImmMap -> SN.Collections.cImmMap
133 | Dict -> SN.Collections.cDict
135 let is_vc_kind name =
136 String.equal name SN.Collections.cVector
137 || String.equal name SN.Collections.cImmVector
138 || String.equal name SN.Collections.cSet
139 || String.equal name SN.Collections.cImmSet
140 || String.equal name SN.Collections.cKeyset
141 || String.equal name SN.Collections.cVec
143 let get_vc_kind name =
144 match name with
145 | x when String.equal x SN.Collections.cVector -> Vector
146 | x when String.equal x SN.Collections.cImmVector -> ImmVector
147 | x when String.equal x SN.Collections.cVec -> Vec
148 | x when String.equal x SN.Collections.cSet -> Set
149 | x when String.equal x SN.Collections.cImmSet -> ImmSet
150 | x when String.equal x SN.Collections.cKeyset -> Keyset
151 | _ ->
152 Errors.internal_error Pos.none ("Invalid ValueCollection name: " ^ name);
155 let vc_kind_to_name kind =
156 match kind with
157 | Vector -> SN.Collections.cVector
158 | ImmVector -> SN.Collections.cImmVector
159 | Vec -> SN.Collections.cVec
160 | Set -> SN.Collections.cSet
161 | ImmSet -> SN.Collections.cImmSet
162 | Keyset -> SN.Collections.cKeyset
164 (* XHP attribute helpers *)
165 let map_xhp_attr (f : pstring -> pstring) (g : expr -> expr) = function
166 | Xhp_simple { xs_name = id; xs_type; xs_expr = e } ->
167 Xhp_simple { xs_name = f id; xs_type; xs_expr = g e }
168 | Xhp_spread e -> Xhp_spread (g e)
170 let get_xhp_attr_expr = function
171 | Xhp_simple { xs_expr = e; _ }
172 | Xhp_spread e ->
175 let get_simple_xhp_attrs =
176 List.filter_map ~f:(function
177 | Xhp_simple { xs_name = id; xs_expr = e; _ } -> Some (id, e)
178 | Xhp_spread _ -> None)
180 (* Given a Nast.program, give me the list of entities it defines *)
181 let get_defs (ast : program) =
182 (* fold_right traverses the file from top to bottom, and as such gives nicer
183 * error messages than fold_left. E.g. in the case where a function is
184 * declared twice in the same file, the error will say that the declaration
185 * with the larger line number is a duplicate. *)
186 let to_id (a, b) = (a, b, None) in
187 (* TODO(hgoldstein): Just have this return four values, not five *)
188 let rec get_defs ast acc =
189 List.fold_right
191 ~init:acc
192 ~f:(fun def ((funs, classes, typedefs, constants, modules) as acc) ->
193 Aast.(
194 match def with
195 | Fun f ->
196 ( FileInfo.pos_full (to_id f.fd_fun.f_name) :: funs,
197 classes,
198 typedefs,
199 constants,
200 modules )
201 | Class c ->
202 ( funs,
203 FileInfo.pos_full (to_id c.c_name) :: classes,
204 typedefs,
205 constants,
206 modules )
207 | Typedef t ->
208 ( funs,
209 classes,
210 FileInfo.pos_full (to_id t.t_name) :: typedefs,
211 constants,
212 modules )
213 | Constant cst ->
214 ( funs,
215 classes,
216 typedefs,
217 FileInfo.pos_full (to_id cst.cst_name) :: constants,
218 modules )
219 | Module md ->
220 ( funs,
221 classes,
222 typedefs,
223 constants,
224 FileInfo.pos_full (to_id md.md_name) :: modules )
225 | Namespace (_, defs) -> get_defs defs acc
226 | NamespaceUse _
227 | SetNamespaceEnv _
228 | SetModule _ ->
230 (* toplevel statements are ignored *)
231 | FileAttributes _
232 | Stmt _ ->
233 acc))
235 get_defs ast ([], [], [], [], [])
237 type ignore_attribute_env = { ignored_attributes: string list }
239 (** Some utility functions **)
241 let ast_deregister_attributes_mapper =
242 object (self)
243 inherit [_] Aast.endo as super
245 method on_'ex _ (ex : unit) = ex
247 method on_'en _ (en : unit) = en
249 method ignored_attr env l =
250 List.exists l ~f:(fun attr ->
251 List.mem env.ignored_attributes (snd attr.ua_name) ~equal:String.equal)
253 (* Filter all functions and classes with the user attributes banned *)
254 method! on_program env toplevels =
255 let toplevels =
256 List.filter toplevels ~f:(fun toplevel ->
257 match toplevel with
258 | Fun f when self#ignored_attr env f.fd_fun.f_user_attributes ->
259 false
260 | Class c when self#ignored_attr env c.c_user_attributes -> false
261 | _ -> true)
263 super#on_program env toplevels
265 method! on_class_ env this =
266 (* Filter out class elements which are methods with wrong attributes *)
267 let methods =
268 List.filter this.c_methods ~f:(fun m ->
269 not @@ self#ignored_attr env m.m_user_attributes)
271 let cvars =
272 List.filter this.c_vars ~f:(fun cv ->
273 not @@ self#ignored_attr env cv.cv_user_attributes)
275 let this = { this with c_methods = methods; c_vars = cvars } in
276 super#on_class_ env this
279 let deregister_ignored_attributes (ast : program) =
280 let env =
282 (* For now, only ignore the __PHPStdLib *)
283 ignored_attributes = [Naming_special_names.UserAttributes.uaPHPStdLib];
286 ast_deregister_attributes_mapper#on_program env ast
288 let ast_no_pos_or_docblock_mapper =
289 object
290 inherit [_] Aast.endo as super
292 method! on_pos _ _pos = Pos.none
294 method on_'ex _ (ex : unit) = ex
296 method on_'en _ (en : unit) = en
298 method! on_fun_ env f = super#on_fun_ env { f with f_doc_comment = None }
300 method! on_class_ env c =
301 super#on_class_ env { c with c_doc_comment = None }
303 method! on_class_var env cv =
304 super#on_class_var env { cv with cv_doc_comment = None }
306 method! on_method_ env m =
307 super#on_method_ env { m with m_doc_comment = None }
309 method! on_class_const env ccs =
310 super#on_class_const env { ccs with cc_doc_comment = None }
312 method! on_class_typeconst_def env tc =
313 super#on_class_typeconst_def env { tc with c_tconst_doc_comment = None }
315 (* Skip all blocks because we don't care about method bodies *)
316 method! on_block _ _ = []
319 (* Given an AST, return an AST with no position or docblock info *)
320 let remove_pos_and_docblock ast =
321 ast_no_pos_or_docblock_mapper#on_program () ast
323 (* Given an AST, generate a unique hash for its decl tree. *)
324 let generate_ast_decl_hash ast =
325 (* Why we marshal it into a string first: regular Hashtbl.hash will
326 collide improperly because it doesn't compare ADTs with strings correctly.
327 Using Marshal, we guarantee that the two ASTs are represented by a single
328 primitive type, which we hash.
330 let str = Marshal.to_string (remove_pos_and_docblock ast) [] in
331 OpaqueDigest.string str
333 (*****************************************************************************)
334 (** This module defines a visitor class on the Nast data structure.
335 To use it you must inherit the generic object and redefine the appropriate
336 methods.
338 It has been deprecated because it contains holes and needs to be updated
339 manually. Please use the autogenerated visitors instead (e.g., {!Nast.iter},
340 {!Nast.reduce}).
342 @see <https://gitlab.inria.fr/fpottier/visitors> Visitor generation plugin
343 @see <http://gallium.inria.fr/~fpottier/visitors/manual.pdf> Visitors docs
345 To convert a visitor using this deprecated base class to the autogenerated
346 visitors, you will likely want to use either {!Nast.iter} with a mutable
347 result member or {!Nast.reduce}.
349 For example, this visitor:
351 let has_return_visitor = object
352 inherit [bool] Nast.Visitor_DEPRECATED.visitor
353 method! on_return _ _ _ = true
356 let has_return block =
357 has_return_visitor#on_block false block
359 Could be written this way:
361 class has_return_visitor = object (_ : 'self)
362 inherit [_] Nast.iter
363 val mutable result = false
364 method result = result
365 method! on_Return () _ _ = result <- true
368 let has_return block =
369 let visitor = new has_return_visitor in
370 visitor#on_block () block;
371 visitor#result
373 But it would be even better to use a reduce visitor:
375 let has_return_visitor = object (_ : 'self)
376 inherit [_] Nast.reduce
377 method zero = false
378 method plus = (||)
379 method! on_Return () _ _ = true
382 let has_return block =
383 has_return_visitor#on_block () block
386 (*****************************************************************************)
387 module Visitor_DEPRECATED = struct
388 (*****************************************************************************)
389 (* The signature of the visitor. *)
390 (*****************************************************************************)
391 type id = lid
393 class type ['a] visitor_type =
394 object
395 method on_block : 'a -> block -> 'a
397 method on_break : 'a -> 'a
399 method on_case : 'a -> case -> 'a
401 method on_default_case : 'a -> default_case -> 'a
403 method on_catch : 'a -> catch -> 'a
405 method on_continue : 'a -> 'a
407 method on_darray : 'a -> (targ * targ) option -> field list -> 'a
409 method on_varray : 'a -> targ option -> expr list -> 'a
411 method on_do : 'a -> block -> expr -> 'a
413 method on_expr : 'a -> expr -> 'a
415 method on_expr_ : 'a -> expr_ -> 'a
417 method on_for : 'a -> expr list -> expr option -> expr list -> block -> 'a
419 method on_foreach : 'a -> expr -> (unit, unit) as_expr -> block -> 'a
421 method on_if : 'a -> expr -> block -> block -> 'a
423 method on_noop : 'a -> 'a
425 method on_fallthrough : 'a -> 'a
427 method on_return : 'a -> expr option -> 'a
429 method on_awaitall : 'a -> (id option * expr) list -> block -> 'a
431 method on_stmt : 'a -> stmt -> 'a
433 method on_stmt_ : 'a -> (unit, unit) stmt_ -> 'a
435 method on_switch : 'a -> expr -> case list -> default_case option -> 'a
437 method on_throw : 'a -> expr -> 'a
439 method on_try : 'a -> block -> catch list -> block -> 'a
441 method on_while : 'a -> expr -> block -> 'a
443 method on_using : 'a -> (unit, unit) using_stmt -> 'a
445 method on_as_expr : 'a -> (unit, unit) as_expr -> 'a
447 method on_shape : 'a -> (Ast_defs.shape_field_name * expr) list -> 'a
449 method on_valCollection : 'a -> vc_kind -> targ option -> expr list -> 'a
451 method on_keyValCollection :
452 'a -> kvc_kind -> (targ * targ) option -> field list -> 'a
454 method on_collection :
455 'a -> unit collection_targ option -> afield list -> 'a
457 method on_this : 'a -> 'a
459 method on_id : 'a -> sid -> 'a
461 method on_lvar : 'a -> id -> 'a
463 method on_dollardollar : 'a -> id -> 'a
465 method on_fun_id : 'a -> sid -> 'a
467 method on_method_id : 'a -> expr -> pstring -> 'a
469 method on_smethod_id : 'a -> class_id -> pstring -> 'a
471 method on_method_caller : 'a -> sid -> pstring -> 'a
473 method on_obj_get : 'a -> expr -> expr -> 'a
475 method on_array_get : 'a -> expr -> expr option -> 'a
477 method on_class_get : 'a -> class_id -> (unit, unit) class_get_expr -> 'a
479 method on_class_const : 'a -> class_id -> pstring -> 'a
481 method on_call :
482 'a -> expr -> (Ast_defs.param_kind * expr) list -> expr option -> 'a
484 method on_function_pointer :
485 'a -> (unit, unit) function_ptr_id -> targ list -> 'a
487 method on_true : 'a -> 'a
489 method on_false : 'a -> 'a
491 method on_int : 'a -> string -> 'a
493 method on_float : 'a -> string -> 'a
495 method on_null : 'a -> 'a
497 method on_string : 'a -> string -> 'a
499 method on_string2 : 'a -> expr list -> 'a
501 method on_yield_break : 'a -> 'a
503 method on_yield : 'a -> afield -> 'a
505 method on_await : 'a -> expr -> 'a
507 method on_list : 'a -> expr list -> 'a
509 method on_pair : 'a -> (targ * targ) option -> expr -> expr -> 'a
511 method on_cast : 'a -> hint -> expr -> 'a
513 method on_expression_tree : 'a -> expression_tree -> 'a
515 method on_unop : 'a -> Ast_defs.uop -> expr -> 'a
517 method on_binop : 'a -> Ast_defs.bop -> expr -> expr -> 'a
519 method on_pipe : 'a -> id -> expr -> expr -> 'a
521 method on_eif : 'a -> expr -> expr option -> expr -> 'a
523 method on_is : 'a -> expr -> hint -> 'a
525 method on_as : 'a -> expr -> hint -> bool -> 'a
527 method on_upcast : 'a -> expr -> hint -> 'a
529 method on_class_id : 'a -> class_id -> 'a
531 method on_class_id_ : 'a -> class_id_ -> 'a
533 method on_new : 'a -> class_id -> expr list -> expr option -> 'a
535 method on_record : 'a -> sid -> (expr * expr) list -> 'a
537 method on_efun : 'a -> fun_ -> id list -> 'a
539 method on_lfun : 'a -> fun_ -> id list -> 'a
541 method on_xml : 'a -> sid -> xhp_attribute list -> expr list -> 'a
543 method on_param_kind : 'a -> Ast_defs.param_kind -> 'a
545 method on_clone : 'a -> expr -> 'a
547 method on_field : 'a -> field -> 'a
549 method on_afield : 'a -> afield -> 'a
551 method on_class_typeconst_def :
552 'a -> (unit, unit) class_typeconst_def -> 'a
554 method on_class_c_const : 'a -> class_const -> 'a
556 method on_class_var : 'a -> class_var -> 'a
558 method on_class_use : 'a -> hint -> 'a
560 method on_class_req : 'a -> hint * require_kind -> 'a
562 method on_func_body : 'a -> func_body -> 'a
564 method on_method_ : 'a -> method_ -> 'a
566 method on_fun_def : 'a -> fun_def -> 'a
568 method on_fun_ : 'a -> fun_ -> 'a
570 method on_class_ : 'a -> class_ -> 'a
572 method on_gconst : 'a -> gconst -> 'a
574 method on_typedef : 'a -> typedef -> 'a
576 method on_hint : 'a -> hint -> 'a
578 method on_type_hint : 'a -> type_hint -> 'a
580 method on_targ : 'a -> targ -> 'a
582 method on_def : 'a -> def -> 'a
584 method on_program : 'a -> program -> 'a
586 method on_markup : 'a -> pstring -> 'a
588 method on_enum_class_label : 'a -> sid option -> string -> 'a
590 method on_function_ptr_id : 'a -> (unit, unit) function_ptr_id -> 'a
592 method on_et_splice : 'a -> expr -> 'a
594 method on_readonly_expr : 'a -> expr -> 'a
597 (*****************************************************************************)
598 (* The generic visitor ('a is the type of the accumulator). *)
599 (*****************************************************************************)
601 class virtual ['a] visitor : ['a] visitor_type =
602 object (this)
603 method on_break acc = acc
605 method on_continue acc = acc
607 method on_noop acc = acc
609 method on_fallthrough acc = acc
611 method on_markup acc _ = acc
613 method on_throw acc e =
614 let acc = this#on_expr acc e in
617 method on_return acc eopt =
618 match eopt with
619 | None -> acc
620 | Some e -> this#on_expr acc e
622 method on_awaitall acc el b =
623 let acc =
624 List.fold_left
625 ~f:(fun acc (x, y) ->
626 let acc =
627 match x with
628 | Some x -> this#on_lvar acc x
629 | None -> acc
631 let acc = this#on_expr acc y in
632 acc)
633 ~init:acc
636 let acc = this#on_block acc b in
639 method on_if acc e b1 b2 =
640 let acc = this#on_expr acc e in
641 let acc = this#on_block acc b1 in
642 let acc = this#on_block acc b2 in
645 method on_do acc b e =
646 let acc = this#on_block acc b in
647 let acc = this#on_expr acc e in
650 method on_while acc e b =
651 let acc = this#on_expr acc e in
652 let acc = this#on_block acc b in
655 method on_using acc us =
656 let acc = List.fold_left (snd us.us_exprs) ~f:this#on_expr ~init:acc in
657 let acc = this#on_block acc us.us_block in
660 method on_for acc e1 e2 e3 b =
661 let on_expr_list acc es = List.fold_left es ~f:this#on_expr ~init:acc in
663 let acc = on_expr_list acc e1 in
664 let acc = on_expr_list acc e3 in
665 let acc =
666 match e2 with
667 | None -> acc
668 | Some e -> this#on_expr acc e
670 let acc = this#on_block acc b in
673 method on_switch acc e cl dfl =
674 let acc = this#on_expr acc e in
675 let acc = List.fold_left cl ~f:this#on_case ~init:acc in
676 let acc =
677 match dfl with
678 | None -> acc
679 | Some dfl -> this#on_default_case acc dfl
683 method on_foreach acc e ae b =
684 let acc = this#on_expr acc e in
685 let acc = this#on_as_expr acc ae in
686 let acc = this#on_block acc b in
689 method on_try acc b cl fb =
690 let acc = this#on_block acc b in
691 let acc = List.fold_left cl ~f:this#on_catch ~init:acc in
692 let acc = this#on_block acc fb in
695 method on_block acc b = List.fold_left b ~f:this#on_stmt ~init:acc
697 method on_case acc (e, b) =
698 let acc = this#on_expr acc e in
699 let acc = this#on_block acc b in
702 method on_default_case acc (_, dfl) = this#on_block acc dfl
704 method on_as_expr acc =
705 function
706 | As_v e
707 | Await_as_v (_, e) ->
708 let acc = this#on_expr acc e in
710 | As_kv (e1, e2)
711 | Await_as_kv (_, e1, e2) ->
712 let acc = this#on_expr acc e1 in
713 let acc = this#on_expr acc e2 in
716 method on_catch acc (_, _, b) = this#on_block acc b
718 method on_stmt acc (_, stmt) = this#on_stmt_ acc stmt
720 method on_stmt_ acc =
721 function
722 | Expr e -> this#on_expr acc e
723 | Break -> this#on_break acc
724 | Continue -> this#on_continue acc
725 | Throw e -> this#on_throw acc e
726 | Return eopt -> this#on_return acc eopt
727 | Yield_break -> this#on_yield_break acc
728 | If (e, b1, b2) -> this#on_if acc e b1 b2
729 | Do (b, e) -> this#on_do acc b e
730 | While (e, b) -> this#on_while acc e b
731 | Using us -> this#on_using acc us
732 | For (e1, e2, e3, b) -> this#on_for acc e1 e2 e3 b
733 | Switch (e, cl, dfl) -> this#on_switch acc e cl dfl
734 | Foreach (e, ae, b) -> this#on_foreach acc e ae b
735 | Try (b, cl, fb) -> this#on_try acc b cl fb
736 | Noop -> this#on_noop acc
737 | Fallthrough -> this#on_fallthrough acc
738 | Awaitall (el, b) -> this#on_awaitall acc el b
739 | Block b -> this#on_block acc b
740 | Markup s -> this#on_markup acc s
741 | AssertEnv _ -> this#on_noop acc
743 method on_expr acc (_, _, e) = this#on_expr_ acc e
745 method on_expr_ acc e =
746 match e with
747 | Darray (tap, fieldl) -> this#on_darray acc tap fieldl
748 | Varray (ta, el) -> this#on_varray acc ta el
749 | Shape sh -> this#on_shape acc sh
750 | True -> this#on_true acc
751 | False -> this#on_false acc
752 | Int n -> this#on_int acc n
753 | Float n -> this#on_float acc n
754 | Null -> this#on_null acc
755 | String s -> this#on_string acc s
756 | This -> this#on_this acc
757 | Id sid -> this#on_id acc sid
758 | Lplaceholder _pos -> acc
759 | Dollardollar id -> this#on_dollardollar acc id
760 | Lvar id -> this#on_lvar acc id
761 | Fun_id sid -> this#on_fun_id acc sid
762 | Method_id (expr, pstr) -> this#on_method_id acc expr pstr
763 | Method_caller (sid, pstr) -> this#on_method_caller acc sid pstr
764 | Smethod_id (cid, pstr) -> this#on_smethod_id acc cid pstr
765 | Yield e -> this#on_yield acc e
766 | Await e -> this#on_await acc e
767 | Tuple el -> this#on_list acc el
768 | List el -> this#on_list acc el
769 | Clone e -> this#on_clone acc e
770 | Obj_get (e1, e2, _, _) -> this#on_obj_get acc e1 e2
771 | Array_get (e1, e2) -> this#on_array_get acc e1 e2
772 | Class_get (cid, e, _) -> this#on_class_get acc cid e
773 | Class_const (cid, id) -> this#on_class_const acc cid id
774 | Call (e, _, el, unpacked_element) ->
775 this#on_call acc e el unpacked_element
776 | FunctionPointer (fpid, targs) ->
777 this#on_function_pointer acc fpid targs
778 | String2 el -> this#on_string2 acc el
779 | PrefixedString (_, e) -> this#on_expr acc e
780 | Pair (ta, e1, e2) -> this#on_pair acc ta e1 e2
781 | Cast (hint, e) -> this#on_cast acc hint e
782 | ExpressionTree et -> this#on_expression_tree acc et
783 | Unop (uop, e) -> this#on_unop acc uop e
784 | Binop (bop, e1, e2) -> this#on_binop acc bop e1 e2
785 | Pipe (id, e1, e2) -> this#on_pipe acc id e1 e2
786 | Eif (e1, e2, e3) -> this#on_eif acc e1 e2 e3
787 | Is (e, h) -> this#on_is acc e h
788 | As (e, h, b) -> this#on_as acc e h b
789 | Upcast (e, h) -> this#on_upcast acc e h
790 | New (cid, _, el, unpacked_element, _) ->
791 this#on_new acc cid el unpacked_element
792 | Efun (f, idl) -> this#on_efun acc f idl
793 | Xml (sid, attrl, el) -> this#on_xml acc sid attrl el
794 | ValCollection (s, ta, el) -> this#on_valCollection acc s ta el
795 | KeyValCollection (s, tap, fl) -> this#on_keyValCollection acc s tap fl
796 | Omitted -> acc
797 | Lfun (f, idl) -> this#on_lfun acc f idl
798 | Import (_, e) -> this#on_expr acc e
799 | Collection (_, tal, fl) -> this#on_collection acc tal fl
800 | ET_Splice e -> this#on_et_splice acc e
801 | EnumClassLabel (opt_sid, name) ->
802 this#on_enum_class_label acc opt_sid name
803 | ReadonlyExpr e -> this#on_readonly_expr acc e
804 | Hole (e, _, _, _) -> this#on_expr acc e
806 method on_collection acc tal afl =
807 let acc =
808 match tal with
809 | Some (CollectionTKV (tk, tv)) ->
810 let acc = this#on_targ acc tk in
811 let acc = this#on_targ acc tv in
813 | Some (CollectionTV tv) -> this#on_targ acc tv
814 | None -> acc
816 List.fold_left afl ~f:this#on_afield ~init:acc
818 method on_shape acc sm =
819 List.fold_left
821 begin
822 fun acc (_, e) ->
823 let acc = this#on_expr acc e in
826 ~init:acc
829 method on_darray acc tap fieldl =
830 let acc =
831 match tap with
832 | Some (t1, t2) ->
833 let acc = this#on_targ acc t1 in
834 let acc = this#on_targ acc t2 in
836 | None -> acc
838 List.fold_left fieldl ~f:this#on_field ~init:acc
840 method on_varray acc ta el =
841 let acc =
842 match ta with
843 | Some t -> this#on_targ acc t
844 | None -> acc
846 List.fold_left el ~f:this#on_expr ~init:acc
848 method on_valCollection acc _ ta el =
849 let acc =
850 match ta with
851 | Some t -> this#on_targ acc t
852 | None -> acc
854 List.fold_left el ~f:this#on_expr ~init:acc
856 method on_keyValCollection acc _ tap fieldl =
857 let acc =
858 match tap with
859 | Some (t1, t2) ->
860 let acc = this#on_targ acc t1 in
861 let acc = this#on_targ acc t2 in
863 | None -> acc
865 List.fold_left fieldl ~f:this#on_field ~init:acc
867 method on_this acc = acc
869 method on_id acc _ = acc
871 method on_lvar acc _ = acc
873 method on_dollardollar acc id = this#on_lvar acc id
875 method on_fun_id acc _ = acc
877 method on_method_id acc _ _ = acc
879 method on_smethod_id acc _ _ = acc
881 method on_method_caller acc _ _ = acc
883 method on_obj_get acc e1 e2 =
884 let acc = this#on_expr acc e1 in
885 let acc = this#on_expr acc e2 in
888 method on_array_get acc e e_opt =
889 let acc = this#on_expr acc e in
890 let acc =
891 match e_opt with
892 | None -> acc
893 | Some e -> this#on_expr acc e
897 method on_class_get acc cid e =
898 let acc = this#on_class_id acc cid in
899 match e with
900 | CGstring _ -> acc
901 | CGexpr e -> this#on_expr acc e
903 method on_class_const acc cid _ = this#on_class_id acc cid
905 method on_call acc e el unpacked_element =
906 let acc = this#on_expr acc e in
907 let f acc_ (pk, e_) =
908 let acc_ = this#on_param_kind acc_ pk in
909 this#on_expr acc_ e_
911 let acc = List.fold_left el ~f ~init:acc in
912 let acc =
913 Option.value_map unpacked_element ~f:(this#on_expr acc) ~default:acc
917 method on_function_pointer acc e targs =
918 let acc = this#on_function_ptr_id acc e in
919 let acc = List.fold_left targs ~f:this#on_targ ~init:acc in
922 method on_true acc = acc
924 method on_false acc = acc
926 method on_int acc _ = acc
928 method on_float acc _ = acc
930 method on_null acc = acc
932 method on_string acc _ = acc
934 method on_string2 acc el =
935 let acc = List.fold_left el ~f:this#on_expr ~init:acc in
938 method on_yield_break acc = acc
940 method on_yield acc e = this#on_afield acc e
942 method on_await acc e = this#on_expr acc e
944 method on_list acc el = List.fold_left el ~f:this#on_expr ~init:acc
946 method on_pair acc tap e1 e2 =
947 let acc =
948 match tap with
949 | Some (t1, t2) ->
950 let acc = this#on_targ acc t1 in
951 let acc = this#on_targ acc t2 in
953 | None -> acc
955 let acc = this#on_expr acc e1 in
956 let acc = this#on_expr acc e2 in
959 method on_cast acc _ e = this#on_expr acc e
961 method on_expression_tree acc (et : expression_tree) =
962 let acc = this#on_hint acc et.et_hint in
963 let acc = this#on_block acc et.et_splices in
964 let acc = this#on_expr acc et.et_virtualized_expr in
965 let acc = this#on_expr acc et.et_runtime_expr in
968 method on_unop acc _ e = this#on_expr acc e
970 method on_binop acc _ e1 e2 =
971 let acc = this#on_expr acc e1 in
972 let acc = this#on_expr acc e2 in
975 method on_pipe acc _id e1 e2 =
976 let acc = this#on_expr acc e1 in
977 let acc = this#on_expr acc e2 in
980 method on_eif acc e1 e2 e3 =
981 let acc = this#on_expr acc e1 in
982 let acc =
983 match e2 with
984 | None -> acc
985 | Some e -> this#on_expr acc e
987 let acc = this#on_expr acc e3 in
990 method on_is acc e _ = this#on_expr acc e
992 method on_as acc e _ _ = this#on_expr acc e
994 method on_upcast acc e _ = this#on_expr acc e
996 method on_class_id acc (_, _, cid) = this#on_class_id_ acc cid
998 method on_class_id_ acc =
999 function
1000 | CIexpr e -> this#on_expr acc e
1001 | _ -> acc
1003 method on_new acc cid el unpacked_element =
1004 let acc = this#on_class_id acc cid in
1005 let acc = List.fold_left el ~f:this#on_expr ~init:acc in
1006 let acc =
1007 Option.value_map unpacked_element ~default:acc ~f:(this#on_expr acc)
1011 method on_efun acc f _ = this#on_block acc f.f_body.fb_ast
1013 method on_lfun acc f _ = this#on_block acc f.f_body.fb_ast
1015 method on_record acc _ fl = List.fold_left fl ~f:this#on_field ~init:acc
1017 method on_xml acc _ attrl el =
1018 let acc =
1019 List.fold_left attrl ~init:acc ~f:(fun acc attr ->
1020 match attr with
1021 | Xhp_simple { xs_expr = e; _ }
1022 | Xhp_spread e ->
1023 this#on_expr acc e)
1025 let acc = List.fold_left el ~f:this#on_expr ~init:acc in
1028 method on_param_kind acc _ = acc
1030 method on_clone acc e = this#on_expr acc e
1032 method on_field acc (e1, e2) =
1033 let acc = this#on_expr acc e1 in
1034 let acc = this#on_expr acc e2 in
1037 method on_afield acc =
1038 function
1039 | AFvalue e -> this#on_expr acc e
1040 | AFkvalue (e1, e2) ->
1041 let acc = this#on_expr acc e1 in
1042 let acc = this#on_expr acc e2 in
1045 method on_hint acc _ = acc
1047 method on_type_hint acc _ = acc
1049 method on_targ acc _ = acc
1051 method on_fun_ acc f =
1052 let acc = this#on_id acc f.f_name in
1053 let acc = this#on_func_body acc f.f_body in
1054 let acc =
1055 match hint_of_type_hint f.f_ret with
1056 | Some h -> this#on_hint acc h
1057 | None -> acc
1061 method on_func_body acc fb = this#on_block acc fb.fb_ast
1063 method on_method_ acc m =
1064 let acc = this#on_id acc m.m_name in
1065 let acc = this#on_func_body acc m.m_body in
1068 method on_class_ acc c =
1069 let acc = this#on_id acc c.c_name in
1070 let acc = List.fold_left c.c_extends ~f:this#on_hint ~init:acc in
1071 let acc = List.fold_left c.c_uses ~f:this#on_hint ~init:acc in
1072 let acc = List.fold_left c.c_implements ~f:this#on_hint ~init:acc in
1073 let acc =
1074 List.fold_left c.c_typeconsts ~f:this#on_class_typeconst_def ~init:acc
1076 let acc =
1077 List.fold_left c.c_consts ~f:this#on_class_c_const ~init:acc
1079 let acc = List.fold_left c.c_vars ~f:this#on_class_var ~init:acc in
1080 let acc = List.fold_left c.c_uses ~f:this#on_class_use ~init:acc in
1081 let acc = List.fold_left c.c_reqs ~f:this#on_class_req ~init:acc in
1082 let acc = List.fold_left c.c_methods ~f:this#on_method_ ~init:acc in
1085 method on_fun_def acc f = this#on_fun_ acc f.fd_fun
1087 method on_class_typeconst_def acc t =
1088 let acc = this#on_id acc t.c_tconst_name in
1089 match t.c_tconst_kind with
1090 | TCAbstract
1091 { c_atc_as_constraint; c_atc_super_constraint; c_atc_default } ->
1092 let acc =
1093 match c_atc_as_constraint with
1094 | Some cstr -> this#on_hint acc cstr
1095 | None -> acc
1097 let acc =
1098 match c_atc_super_constraint with
1099 | Some cstr -> this#on_hint acc cstr
1100 | None -> acc
1102 (match c_atc_default with
1103 | Some d -> this#on_hint acc d
1104 | None -> acc)
1105 | TCConcrete { c_tc_type } -> this#on_hint acc c_tc_type
1107 method on_class_c_const acc c_const =
1108 let acc =
1109 match c_const.cc_type with
1110 | Some h -> this#on_hint acc h
1111 | None -> acc
1113 let acc = this#on_id acc c_const.cc_id in
1114 let acc =
1115 match c_const.cc_kind with
1116 | CCConcrete e -> this#on_expr acc e
1117 | CCAbstract (Some default) -> this#on_expr acc default
1118 | CCAbstract None -> acc
1122 method on_readonly_expr acc e =
1123 let acc = this#on_expr acc e in
1126 method on_class_var acc c_var =
1127 let acc = this#on_id acc c_var.cv_id in
1128 let acc =
1129 match hint_of_type_hint c_var.cv_type with
1130 | Some h -> this#on_hint acc h
1131 | None -> acc
1133 let acc =
1134 match c_var.cv_expr with
1135 | Some e -> this#on_expr acc e
1136 | None -> acc
1140 method on_class_use acc h = this#on_hint acc h
1142 method on_class_req acc (h, _) = this#on_hint acc h
1144 method on_gconst acc g =
1145 let acc = this#on_id acc g.cst_name in
1146 let acc = this#on_expr acc g.cst_value in
1147 let acc =
1148 match g.cst_type with
1149 | Some h -> this#on_hint acc h
1150 | None -> acc
1154 method on_enum_class_label acc opt_sid name =
1155 let acc =
1156 match opt_sid with
1157 | Some sid -> this#on_id acc sid
1158 | None -> acc
1160 this#on_string acc name
1162 method on_function_ptr_id acc fpi =
1163 match fpi with
1164 | FP_id sid -> this#on_id acc sid
1165 | FP_class_const (cid, _) -> this#on_class_id acc cid
1167 method on_et_splice acc e = this#on_expr acc e
1169 method on_typedef acc t =
1170 let acc = this#on_id acc t.t_name in
1171 let acc = this#on_hint acc t.t_kind in
1172 let acc =
1173 match t.t_constraint with
1174 | Some c -> this#on_hint acc c
1175 | None -> acc
1179 method on_def acc =
1180 function
1181 | Fun f -> this#on_fun_def acc f
1182 | Class c -> this#on_class_ acc c
1183 | Stmt s -> this#on_stmt acc s
1184 | Typedef t -> this#on_typedef acc t
1185 | Constant g -> this#on_gconst acc g
1186 | Namespace (_, p) -> this#on_program acc p
1187 | NamespaceUse _
1188 | SetNamespaceEnv _
1189 | FileAttributes _
1190 | SetModule _
1191 | Module _ ->
1194 method on_program acc p =
1195 let acc = List.fold_left p ~init:acc ~f:this#on_def in