2 * Copyright (c) 2015, 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 module SN
= Naming_special_names
15 Naming_special_names.Typehints.(
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
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
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
=
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
126 Errors.internal_error
Pos.none
("Invalid KeyValueCollection name: " ^ name
);
129 let kvc_kind_to_name kind
=
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
=
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
152 Errors.internal_error
Pos.none
("Invalid ValueCollection name: " ^ name
);
155 let vc_kind_to_name kind
=
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
; _
}
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
=
192 ~f
:(fun def
((funs
, classes
, typedefs
, constants
, modules
) as acc
) ->
196 ( FileInfo.pos_full
(to_id f
.fd_fun
.f_name
) :: funs
,
203 FileInfo.pos_full
(to_id c
.c_name
) :: classes
,
210 FileInfo.pos_full
(to_id t
.t_name
) :: typedefs
,
217 FileInfo.pos_full
(to_id cst
.cst_name
) :: constants
,
224 FileInfo.pos_full
(to_id md
.md_name
) :: modules
)
225 | Namespace
(_
, defs
) -> get_defs defs acc
230 (* toplevel statements are ignored *)
235 get_defs ast
([], [], [], [], [])
237 type ignore_attribute_env
= { ignored_attributes
: string list
}
239 (** Some utility functions **)
241 let ast_deregister_attributes_mapper =
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
=
256 List.filter
toplevels ~f
:(fun toplevel
->
258 | Fun f
when self#ignored_attr env f
.fd_fun
.f_user_attributes
->
260 | Class c
when self#ignored_attr env c
.c_user_attributes
-> false
263 super#on_program env
toplevels
265 method! on_class_ env this
=
266 (* Filter out class elements which are methods with wrong attributes *)
268 List.filter this
.c_methods ~f
:(fun m
->
269 not
@@ self#ignored_attr env m
.m_user_attributes
)
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
) =
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 =
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
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},
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;
373 But it would be even better to use a reduce visitor:
375 let has_return_visitor = object (_ : 'self)
376 inherit [_] Nast.reduce
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 (*****************************************************************************)
393 class type ['a
] visitor_type
=
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
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
=
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
=
620 | Some e
-> this#on_expr
acc e
622 method on_awaitall
acc el b
=
625 ~f
:(fun acc (x
, y
) ->
628 | Some x
-> this#on_lvar
acc x
631 let acc = this#on_expr
acc y
in
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
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
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 =
707 | Await_as_v
(_
, e
) ->
708 let acc = this#on_expr
acc e
in
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 =
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
=
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
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
=
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
816 List.fold_left afl ~f
:this#on_afield ~init
:acc
818 method on_shape
acc sm
=
823 let acc = this#on_expr
acc e
in
829 method on_darray
acc tap fieldl
=
833 let acc = this#on_targ
acc t1
in
834 let acc = this#on_targ
acc t2
in
838 List.fold_left fieldl ~f
:this#on_field ~init
:acc
840 method on_varray
acc ta el
=
843 | Some t
-> this#on_targ
acc t
846 List.fold_left el ~f
:this#on_expr ~init
:acc
848 method on_valCollection
acc _ ta el
=
851 | Some t
-> this#on_targ
acc t
854 List.fold_left el ~f
:this#on_expr ~init
:acc
856 method on_keyValCollection
acc _ tap fieldl
=
860 let acc = this#on_targ
acc t1
in
861 let acc = this#on_targ
acc t2
in
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
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
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
911 let acc = List.fold_left el ~
f ~init
:acc in
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
=
950 let acc = this#on_targ
acc t1
in
951 let acc = this#on_targ
acc t2
in
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
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 =
1000 | CIexpr e
-> this#on_expr
acc e
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
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
=
1019 List.fold_left attrl ~init
:acc ~
f:(fun acc attr
->
1021 | Xhp_simple
{ xs_expr
= 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 =
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
1055 match hint_of_type_hint
f.f_ret
with
1056 | Some h
-> this#on_hint
acc h
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
1074 List.fold_left c
.c_typeconsts ~
f:this#on_class_typeconst_def ~init
: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
1091 { c_atc_as_constraint
; c_atc_super_constraint
; c_atc_default
} ->
1093 match c_atc_as_constraint
with
1094 | Some cstr
-> this#on_hint
acc cstr
1098 match c_atc_super_constraint
with
1099 | Some cstr
-> this#on_hint
acc cstr
1102 (match c_atc_default
with
1103 | Some d
-> this#on_hint
acc d
1105 | TCConcrete
{ c_tc_type
} -> this#on_hint
acc c_tc_type
1107 method on_class_c_const
acc c_const
=
1109 match c_const
.cc_type
with
1110 | Some h
-> this#on_hint
acc h
1113 let acc = this#on_id
acc c_const
.cc_id
in
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
1129 match hint_of_type_hint c_var
.cv_type
with
1130 | Some h
-> this#on_hint
acc h
1134 match c_var
.cv_expr
with
1135 | Some e
-> this#on_expr
acc e
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
1148 match g
.cst_type
with
1149 | Some h
-> this#on_hint
acc h
1154 method on_enum_class_label
acc opt_sid name
=
1157 | Some sid
-> this#on_id
acc sid
1160 this#on_string
acc name
1162 method on_function_ptr_id
acc fpi
=
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
1173 match t
.t_constraint
with
1174 | Some c
-> this#on_hint
acc c
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
1194 method on_program
acc p
=
1195 let acc = List.fold_left p ~init
:acc ~
f:this#on_def
in