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.
11 module SN
= Naming_special_names
15 c_uses
: Aast.hint list
;
16 c_method_redeclarations
: Aast.method_redeclaration list
;
17 c_xhp_attr_uses
: Aast.hint list
;
18 c_xhp_category
: pstring list
;
19 c_req_extends
: Aast.hint list
;
20 c_req_implements
: Aast.hint list
;
21 c_consts
: Aast.class_const list
;
22 c_typeconsts
: Aast.class_typeconst list
;
23 c_static_vars
: Aast.static_var list
;
24 c_vars
: Aast.class_var list
;
25 c_constructor
: Aast.constructor
option ;
26 c_static_methods
: Aast.static_method list
;
27 c_methods
: Aast.method_ list
;
28 c_attributes
: Aast.class_attr list
;
29 c_xhp_children
: (pos
* Aast.xhp_child
) list
;
30 c_xhp_attrs
: Aast.xhp_attr list
;
31 c_pu_enums
: Aast.pu_enum list
;
34 let make_empty_class_body = {
36 c_method_redeclarations
= [];
40 c_req_implements
= [];
46 c_static_methods
= [];
54 let on_list f l
= List.map f l
56 let on_list_append_acc acc f l
=
58 (fun acc li
-> f li
:: acc
)
61 let optional f
= function
63 | Some x
-> Some
(f x
)
65 let both f
(p1
, p2
) = (f p1
, f p2
)
67 let rec on_variadic_hint h
=
69 | Hvariadic h
-> Aast.Hvariadic
(optional on_hint h
)
70 | Hnon_variadic
-> Aast.Hnon_variadic
72 and get_pos_shape_name name
=
76 | SFclass_const
(_
, (pos
, _
)) -> pos
78 and on_shape_info info
=
79 let on_shape_field sf
=
80 Aast.{ sfi_optional
= sf
.sf_optional
; sfi_hint
= on_hint sf
.sf_hint
} in
84 if ShapeMap.mem sf
.sf_name acc
85 then Errors.fd_name_already_bound
(get_pos_shape_name sf
.sf_name
);
86 ShapeMap.add sf
.sf_name
(on_shape_field sf
) acc
)
88 info
.si_shape_field_list
in
90 nsi_allows_unknown_fields
= info
.si_allows_unknown_fields
;
94 and on_haccess
(pos
, root_id
) id ids
=
95 let root_ty = Aast.Happly
((pos
, root_id
), []) in
96 Aast.Haccess
((pos
, root_ty), id
:: ids
)
98 and on_hint
(p
, h
) : Aast.hint
=
100 | Hoption h
-> (p
, Aast.Hoption
(on_hint h
))
101 | Hfun
(is_coroutine
, hl
, param_kinds
, variadic
, h
) ->
105 (on_list on_hint hl
),
108 (on_variadic_hint variadic
),
113 | Htuple
(hl
) -> (p
, Aast.Htuple
(on_list on_hint hl
))
114 | Happly
(x
, hl
) -> (p
, Aast.Happly
(x
, on_list on_hint hl
))
115 | Hshape s
-> (p
, Aast.Hshape
(on_shape_info s
))
116 | Haccess
(root
, id
, ids
) -> (p
, on_haccess root id ids
)
117 | Hsoft h
-> (p
, Aast.Hsoft
(on_hint h
))
119 and on_class_elt trait_or_interface body elt
: class_body
=
121 | Attributes attrs
->
122 let attrs = on_list_append_acc body
.c_attributes on_class_attr
attrs in
123 { body
with c_attributes
= attrs; }
124 | Const
(hopt
, el
) ->
125 let hopt = optional on_hint
hopt in
126 let consts = on_list_append_acc body
.c_consts
(fun (id
, e
) ->
127 (hopt, id
, Some
(on_expr e
))
129 { body
with c_consts
= consts; }
130 | AbsConst
(hopt, id
) ->
131 let consts = (optional on_hint
hopt, id
, None
) :: body
.c_consts
in
132 { body
with c_consts
= consts; }
134 let hints = on_hint h
:: body
.c_uses
in
135 { body
with c_uses
= hints; }
136 | ClassUseAlias
(_
, (p
, _
), _
, _
) ->
137 Errors.unsupported_feature p
"Trait use aliasing"; body
138 | ClassUsePrecedence
(_
, (p
, _
), _
) ->
139 Errors.unsupported_feature p
"The insteadof keyword"; body
140 | MethodTraitResolution res
->
141 let redecls = on_method_trait_resolution res
:: body
.c_method_redeclarations
in
142 { body
with c_method_redeclarations
= redecls; }
144 let hints = on_hint h
:: body
.c_xhp_attr_uses
in
145 { body
with c_xhp_attr_uses
= hints }
146 | ClassTraitRequire
(MustExtend
, h
) ->
147 let hints = on_hint h
:: body
.c_req_extends
in
148 { body
with c_req_extends
= hints; }
149 | ClassTraitRequire
(MustImplement
, h
) ->
150 let hints = on_hint h
:: body
.c_req_implements
in
151 { body
with c_req_implements
= hints; }
152 | ClassVars cv
when List.mem Static cv
.cv_kinds
->
153 let attrs = on_list on_user_attribute cv
.cv_user_attributes
in
157 (on_class_var
false (optional on_hint cv
.cv_hint
) attrs cv
.cv_kinds
)
159 { body
with c_static_vars
= vars; }
160 | ClassVars
{ cv_names
; cv_user_attributes
; cv_hint
; cv_kinds
; _
} ->
161 let attrs = on_list on_user_attribute cv_user_attributes
in
165 (on_class_var
false (optional on_hint cv_hint
) attrs cv_kinds
)
167 { body
with c_vars
= vars; }
168 | XhpAttr
(hopt, var
, is_required
, maybe_enum
) ->
169 (* TODO: T37984688 Updating naming.ml to use c_xhp_attrs *)
170 let hopt = optional on_hint
hopt in
173 on_class_var
true hopt [] [] var
,
175 optional on_xhp_attr maybe_enum
) :: body
.c_xhp_attrs
in
176 { body
with c_xhp_attrs
= attrs; }
177 | XhpCategory
(_
, cs
) ->
178 if body
.c_xhp_category
<> [] && cs
<> []
179 then Errors.multiple_xhp_category
(fst
(List.hd cs
));
180 { body
with c_xhp_category
= cs
; }
182 let children = (p
, on_xhp_child c
) :: body
.c_xhp_children
in
183 { body
with c_xhp_children
= children; }
184 | Method m
when snd m
.m_name
= SN.Members.__construct
->
185 if body
.c_constructor
<> None
186 then Errors.method_name_already_bound
(fst m
.m_name
) (snd m
.m_name
);
187 { body
with c_constructor
= Some
(on_method ~trait_or_interface m
) }
188 | Method m
when List.mem Static m
.m_kind
->
189 let statics = on_method m
:: body
.c_static_methods
in
190 { body
with c_static_methods
= statics; }
192 let methods = on_method m
:: body
.c_methods
in
193 { body
with c_methods
= methods; }
195 let typeconsts = on_class_typeconst tc
:: body
.c_typeconsts
in
196 { body
with c_typeconsts
= typeconsts; }
197 | ClassEnum
(pu_is_final
, pu_name
, fields
) ->
198 let pu_enum = on_pu pu_name pu_is_final fields
in
199 let pu_enums = pu_enum :: body
.c_pu_enums
in
200 { body
with c_pu_enums
= pu_enums }
202 and on_as_expr aw e
: Aast.as_expr
=
204 | None
, As_v ev
-> Aast.As_v
(on_expr ev
)
205 | Some p
, As_v ev
-> Aast.Await_as_v
(p
, on_expr ev
)
206 | None
, As_kv
(k
, ev
) -> Aast.As_kv
(on_expr k
, on_expr ev
)
207 | Some p
, As_kv
(k
, ev
) -> Aast.Await_as_kv
(p
, on_expr k
, on_expr ev
)
209 and on_afield f
: Aast.afield
=
211 | AFvalue e
-> Aast.AFvalue
(on_expr e
)
212 | AFkvalue
(e1
, e2
) -> Aast.AFkvalue
(on_expr e1
, on_expr e2
)
214 and on_darray_element
(e1
, e2
) =
215 (on_expr e1
, on_expr e2
)
217 and on_shape
(sfn
, e
) =
220 and on_awaitall_expr
(e1
, e2
) =
221 let e2 = on_expr
e2 in
224 | Some
(pos
, name
) ->
225 let e = pos
, Local_id.make_unscoped name
in
231 and on_xhp_attribute a
: Aast.xhp_attribute
=
233 | Xhp_simple
(id
, e) -> Aast.Xhp_simple
(id
, on_expr
e)
234 | Xhp_spread
e -> Aast.Xhp_spread
(on_expr
e)
236 and on_targ h
: Aast.targ
= on_hint h
238 and on_collection_targ targ
= match targ
with
239 | Some CollectionTKV
(tk
, tv
) -> Some
(Aast.CollectionTKV
(on_targ tk
, on_targ tv
))
240 | Some CollectionTV tv
-> Some
(Aast.CollectionTV
(on_targ tv
))
243 and on_expr
(p
, e) : Aast.expr
=
244 let node = match e with
245 | Array al
-> Aast.Array
(on_list on_afield al
)
246 | Varray
(ta
, el
) -> Aast.Varray
(optional on_targ ta
, on_list on_expr el
)
247 | Darray
(tap
, d
) -> Aast.Darray
(optional (both on_targ
) tap
, on_list on_darray_element d
)
248 | Shape s
-> Aast.Shape
(on_list on_shape s
)
249 | Collection
(id
, tal
, al
) -> Aast.Collection
(id
, on_collection_targ tal
, on_list on_afield al
)
252 | False
-> Aast.False
253 | Omitted
-> Aast.Omitted
254 | Id id
-> Aast.Id id
256 let lid = Local_id.make_unscoped
(snd id
) in
258 | Clone
e -> Aast.Clone
(on_expr
e)
259 | Obj_get
(e1, e2, f
) -> Aast.Obj_get
(on_expr
e1, on_expr
e2, f
)
260 | Array_get
(e, opt_e
) -> Aast.Array_get
(on_expr
e, optional on_expr opt_e
)
261 | Class_get
(e1, (_
, (Id x2
| Lvar x2
))) ->
262 Aast.Class_get
((p
, Aast.CIexpr
(on_expr
e1)), Aast.CGstring x2
)
263 | Class_get
(e1, e2) -> Aast.Class_get
((p
, Aast.CIexpr
(on_expr
e1)), Aast.CGexpr
(on_expr
e2))
264 | Class_const
(e, s
) -> Aast.Class_const
((p
, Aast.CIexpr
(on_expr
e)), s
)
265 | Call
(e, tl
, el
, uel
) ->
266 Aast.Call
(Aast.Cnormal
, on_expr
e, on_list on_targ tl
, on_list on_expr el
, on_list on_expr uel
)
267 | Int s
-> Aast.Int s
268 | Float s
-> Aast.Float s
269 | String s
-> Aast.String s
270 | String2 el
-> Aast.String2
(on_list on_expr el
)
271 | PrefixedString
(s
, e) -> Aast.PrefixedString
(s
, on_expr
e)
272 | Yield f
-> Aast.Yield
(on_afield f
)
273 | Yield_break
-> Aast.Yield_break
274 | Yield_from
e -> Aast.Yield_from
(on_expr
e)
275 | Await
e -> Aast.Await
(on_expr
e)
276 | Suspend
e -> Aast.Suspend
(on_expr
e)
277 | List el
-> Aast.List
(on_list on_expr el
)
278 | Expr_list el
-> Aast.Expr_list
(on_list on_expr el
)
279 | Cast
(h
, e) -> Aast.Cast
(on_hint h
, on_expr
e)
280 | Unop
(op
, e) -> Aast.Unop
(op
, on_expr
e)
281 | Binop
(op
, e1, e2) -> Aast.Binop
(op
, on_expr
e1, on_expr
e2)
283 let id = Local_id.make_scoped
SN.SpecialIdents.dollardollar
in
284 Aast.Pipe
((p
, id), on_expr
e1, on_expr
e2)
285 | Eif
(e1, opt_e
, e2) -> Aast.Eif
(on_expr
e1, optional on_expr opt_e
, on_expr
e2)
286 | InstanceOf
(e1, e2) -> Aast.InstanceOf
(on_expr
e1, (p
, Aast.CIexpr
(on_expr
e2)))
287 | Is
(e, h
) -> Aast.Is
(on_expr
e, on_hint h
)
288 | As
(e, h
, b
) -> Aast.As
(on_expr
e, on_hint h
, b
)
289 | New
(e, tl
, el1
, el2
) ->
291 (p
, Aast.CIexpr
(on_expr
e)),
297 | Efun
(f
, use_list
) ->
299 (fun ((p
, id), is_ref
) ->
300 if is_ref
then Errors.unsupported_feature p
"References in use list";
301 (p
, Local_id.make_unscoped
id)
305 Aast.Efun
(on_fun f
, ids)
306 | Lfun f
-> Aast.Lfun
(on_fun f
)
307 | BracedExpr
e -> Aast.BracedExpr
(on_expr
e)
308 | ParenthesizedExpr
e -> Aast.ParenthesizedExpr
(on_expr
e)
309 | Xml
(id, xhpl
, el
) -> Aast.Xml
(id, on_list on_xhp_attribute xhpl
, on_list on_expr el
)
310 | Unsafeexpr
e -> Aast.Unsafe_expr
(on_expr
e)
311 | Import
(f
, e) -> Aast.Import
(on_import_flavor f
, on_expr
e)
312 | Callconv
(k
, e) -> Aast.Callconv
(k
, on_expr
e)
313 | PU_atom
id -> Aast.PU_atom
(snd
id)
314 | PU_identifier
(e, id1
, id2
) ->
315 Aast.PU_identifier
((p
, Aast.CIexpr
(on_expr
e)), id1
, id2
)
319 and on_import_flavor f
=
321 | Include
-> Aast.Include
322 | Require
-> Aast.Require
323 | IncludeOnce
-> Aast.IncludeOnce
324 | RequireOnce
-> Aast.RequireOnce
326 and on_case c
: Aast.case
=
328 | Default b
-> Aast.Default
(on_block b
)
329 | Case
(e, b
) -> Aast.Case
(on_expr
e, on_block b
)
331 and on_catch
(id1
, id2
, b
) : Aast.catch
=
332 let lid = Local_id.make_unscoped
(snd id2
) in
333 (id1
, ((fst id2
), lid), on_block b
)
335 and on_stmt
(p
, st
) : Aast.stmt
=
338 and on_stmt_ p st
: Aast.stmt_
=
341 let lid = Local_id.make_unscoped
(snd
id) in
342 Aast.Let
((p
, lid), optional on_hint h
, on_expr
e)
343 | Block sl
-> Aast.Block
(on_block sl
)
344 | Unsafe
-> failwith
"Unsafe statements should be removed in on_block"
345 | Fallthrough
-> Aast.Fallthrough
347 | Markup
(s
, e) -> Aast.Markup
(s
, optional on_expr
e)
348 | Break
(Some _
) -> Errors.break_continue_n_not_supported p
; Aast.Break p
349 | Break None
-> Aast.Break p
350 | Continue
(Some _
) -> Errors.break_continue_n_not_supported p
; Aast.Continue p
351 | Continue None
-> Aast.Continue p
352 | Throw
e -> Aast.Throw
(false, on_expr
e)
353 | Return
e -> Aast.Return
(p
, optional on_expr
e)
354 | GotoLabel label
-> Aast.GotoLabel label
355 | Goto label
-> Aast.Goto label
356 | Global_var el
-> Aast.Global_var
(on_list on_expr el
)
357 | Awaitall el
-> Aast.Awaitall
(p
, on_list on_awaitall_expr el
)
358 | If
(e, b1
, b2
) -> Aast.If
(on_expr
e, on_block b1
, on_block b2
)
359 | Do
(b
, e) -> Aast.Do
(on_block b
, on_expr
e)
360 | While
(e, b
) -> Aast.While
(on_expr
e, on_block b
)
361 | Declare
(is_blk
, e, b
) -> Aast.Declare
(is_blk
, on_expr
e, on_block b
)
364 us_expr
= on_expr s
.us_expr
;
365 us_block
= on_block s
.us_block
;
366 us_has_await
= s
.us_has_await
;
367 us_is_block_scoped
= s
.us_is_block_scoped
;
369 | For
(st1
, e, st2
, b
) -> Aast.For
(on_expr st1
, on_expr
e, on_expr st2
, on_block b
)
370 | Switch
(e, cl
) -> Aast.Switch
(on_expr
e, on_list on_case cl
)
371 | Foreach
(e, aw
, ae
, b
) -> Aast.Foreach
(on_expr
e, on_as_expr aw ae
, on_block b
)
372 | Try
(b
, cl
, fb
) -> Aast.Try
(on_block b
, on_list on_catch cl
, on_block fb
)
373 | Def_inline d
-> Aast.Def_inline
(on_def d
)
374 | Expr
e -> Aast.Expr
(on_expr
e)
376 and on_block stmt_list
: Aast.stmt list
=
379 | (p
, Unsafe
) :: rest
-> [p
, Aast.Unsafe_block
(on_block rest
)]
380 | x
:: rest
-> (on_stmt x
) :: (on_block rest
)
382 and on_tparam_constraint
(kind
, hint
) : (constraint_kind
* Aast.hint
) =
385 and on_tparam t
: Aast.tparam
=
386 { Aast.tp_variance
= t
.tp_variance
;
388 tp_constraints
= on_list on_tparam_constraint t
.tp_constraints
;
389 tp_reified
= t
.tp_reified
;
390 tp_user_attributes
= on_list on_user_attribute t
.tp_user_attributes
;
393 and on_fun_param ?
(trait_or_interface
=false) param
: Aast.fun_param
=
394 let p, name
= param
.param_id
in
395 if trait_or_interface
&& param
.param_modifier
<> None
396 then Errors.trait_interface_constructor_promo
p;
397 { Aast.param_annotation
= p;
398 param_hint
= optional on_hint param
.param_hint
;
399 param_is_reference
= param
.param_is_reference
;
400 param_is_variadic
= param
.param_is_variadic
;
403 param_expr
= optional on_expr param
.param_expr
;
404 param_callconv
= param
.param_callconv
;
405 param_user_attributes
= on_list on_user_attribute param
.param_user_attributes
;
408 and determine_variadicity params
=
410 | [] -> Aast.FVnonVariadic
413 match x
.param_is_variadic
, x
.param_id
with
414 | false, _
-> Aast.FVnonVariadic
415 | true, (p, "...") -> Aast.FVellipsis
p
416 | true, _
-> Aast.FVvariadicArg
(on_fun_param x
)
419 determine_variadicity rl
421 and on_user_attribute attribute
: Aast.user_attribute
=
422 let ua_params = on_list on_expr attribute
.ua_params in
423 Aast.{ ua_name
= attribute
.ua_name
; ua_params; }
425 and on_file_attribute
(attribute
:Ast.file_attributes
) : Aast.file_attribute
=
427 { fa_user_attributes
= on_list on_user_attribute attribute
.fa_user_attributes
428 ; fa_namespace
= attribute
.fa_namespace
431 and on_fun f
: Aast.fun_
=
432 let body = on_block f
.f_body
in
435 (* Still seems incorrect to have this as a Named body... *)
436 Aast.fb_annotation
= Aast.BodyNamingAnnotation.NamedWithUnsafeBlocks
;
439 Aast.f_annotation
= ();
442 f_ret
= (optional on_hint f
.f_ret
);
445 on_list on_tparam f
.f_tparams
;
446 f_where_constraints
= on_list on_constr f
.f_constrs
;
447 f_params
= on_list on_fun_param f
.f_params
;
449 f_fun_kind
= f
.f_fun_kind
;
450 f_variadic
= determine_variadicity f
.f_params
;
451 f_user_attributes
= on_list on_user_attribute f
.f_user_attributes
;
452 f_file_attributes
= on_list on_file_attribute f
.f_file_attributes
;
453 f_external
= f
.f_external
;
454 f_namespace
= f
.f_namespace
;
455 f_doc_comment
= f
.f_doc_comment
;
456 f_static
= f
.f_static
;
460 and on_enum
(e : enum_
) : Aast.enum_
=
462 e_base
= on_hint
e.e_base
;
463 e_constraint
= optional on_hint
e.e_constraint
466 and on_class_attr attr
: Aast.class_attr
=
468 | CA_name
id -> Aast.CA_name
id
469 | CA_field f
-> Aast.CA_field
Aast.{
470 ca_type
= on_ca_type f
.ca_type
;
472 ca_value
= optional on_expr f
.ca_value
;
473 ca_required
= f
.ca_required
;
476 and on_ca_type ty
: Aast.ca_type
=
478 | CA_hint h
-> Aast.CA_hint
(on_hint h
)
479 | CA_enum sl
-> Aast.CA_enum
(sl
)
481 and on_class_typeconst
(tc
: Ast.typeconst
) : Aast.class_typeconst
=
483 match tc
.tconst_type, tc
.tconst_abstract
with
485 Errors.not_abstract_without_typeconst tc
.tconst_name
;
488 Errors.abstract_with_typeconst tc
.tconst_name
;
492 c_tconst_name
= tc
.tconst_name
;
493 c_tconst_constraint
= optional on_hint tc
.tconst_constraint
;
494 c_tconst_type
= optional on_hint
tconst_type;
495 c_tconst_user_attributes
= on_list on_user_attribute tc
.tconst_user_attributes
;
498 and on_class_var is_xhp h
attrs kinds
(_
, id, eopt
) : Aast.class_var
=
499 let cv_final = List.mem Final kinds
in
500 let cv_visibility = List.fold_left
504 | Private
-> Aast.Private
505 | Public
-> Aast.Public
506 | Protected
-> Aast.Protected
517 cv_expr
= optional on_expr eopt
;
518 cv_user_attributes
= attrs;
521 and on_xhp_attr
(p, b
, el
) = (p, b
, on_list on_expr el
)
523 and on_constr
(h1
, k
, h2
) = (on_hint h1
, k
, on_hint h2
)
525 and on_method_trait_resolution res
: Aast.method_redeclaration
=
526 let acc = false, false, false, None
in
527 let final, abs
, static
, vis
= List.fold_left kind
acc res
.mt_kind
in
531 Errors.method_needs_visibility
(fst res
.mt_name
);
539 mt_name
= res
.mt_name
;
540 mt_tparams
= on_list on_tparam res
.mt_tparams
;
541 mt_where_constraints
= on_list on_constr res
.mt_constrs
;
542 mt_variadic
= determine_variadicity res
.mt_params
;
543 mt_params
= on_list on_fun_param res
.mt_params
;
544 mt_fun_kind
= res
.mt_fun_kind
;
545 mt_ret
= optional on_hint res
.mt_ret
;
546 mt_trait
= on_hint res
.mt_trait
;
547 mt_method
= res
.mt_method
;
548 mt_user_attributes
= on_list on_user_attribute res
.mt_user_attributes
;
551 and on_xhp_child c
: Aast.xhp_child
=
553 | ChildName
id -> Aast.ChildName
id
554 | ChildList cl
-> Aast.ChildList
(on_list on_xhp_child cl
)
555 | ChildUnary
(c
, op
) -> Aast.ChildUnary
(on_xhp_child c
, on_xhp_child_op op
)
556 | ChildBinary
(c1
, c2
) -> Aast.ChildBinary
(on_xhp_child c1
, on_xhp_child c2
)
558 and on_xhp_child_op op
: Aast.xhp_child_op
=
560 | ChildStar
-> Aast.ChildStar
561 | ChildPlus
-> Aast.ChildPlus
562 | ChildQuestion
-> Aast.ChildQuestion
564 and kind
(final, abs
, static
, vis) = function
565 | Final
-> true, abs
, static
, vis
566 | Static
-> final, abs
, true, vis
567 | Abstract
-> final, true, static
, vis
568 | Private
-> final, abs
, static
, Some
Aast.Private
569 | Public
-> final, abs
, static
, Some
Aast.Public
570 | Protected
-> final, abs
, static
, Some
Aast.Protected
572 and on_method ?
(trait_or_interface
=false) m
: Aast.method_
=
573 let body = on_block m
.m_body
in
576 (* Still seems incorrect to have this as a Named body... *)
577 Aast.fb_annotation
= Aast.BodyNamingAnnotation.NamedWithUnsafeBlocks
;
579 let acc = false, false, false, None
in
580 let final, abs
, static
, vis = List.fold_left kind
acc m
.m_kind
in
583 | None
-> Errors.method_needs_visibility
(fst m
.m_name
); Aast.Public
593 m_tparams
= on_list on_tparam m
.m_tparams
;
594 m_where_constraints
= on_list on_constr m
.m_constrs
;
595 m_variadic
= determine_variadicity m
.m_params
;
596 m_params
= on_list (on_fun_param ~trait_or_interface
) m
.m_params
;
598 m_fun_kind
= m
.m_fun_kind
;
599 m_user_attributes
= on_list on_user_attribute m
.m_user_attributes
;
600 m_ret
= optional on_hint m
.m_ret
;
601 m_external
= m
.m_external
;
602 m_doc_comment
= m
.m_doc_comment
;
605 and on_pu_mapping pum_atom mappings
=
606 let rec aux types exprs
= function
607 | (PUMappingType
(id, hint
)) :: tl
->
608 aux ((id, on_hint hint
) :: types
) exprs tl
609 | (PUMappingID
(id, expr
)) :: tl
->
610 aux types
((id, on_expr expr
) :: exprs
) tl
611 | [] -> (List.rev types
, List.rev exprs
) in
612 let (pum_types
, pum_exprs
) = aux [] [] mappings
in
613 Aast.{ pum_atom
; pum_types
; pum_exprs
}
615 and on_pu pu_name pu_is_final fields
=
616 let rec aux case_types case_values members
= function
617 | (PUCaseType
id) :: tl
->
618 aux (id :: case_types
) case_values members tl
619 | (PUCaseTypeExpr
(h
, id)) :: tl
->
620 aux case_types
((id, on_hint h
) :: case_values
) members tl
621 | (PUAtomDecl
(id, maps
)) :: tl
->
622 let member = on_pu_mapping
id maps
in
623 aux case_types case_values
(member :: members
) tl
624 | [] -> (List.rev case_types
, List.rev case_values
, List.rev members
) in
625 let (pu_case_types
, pu_case_values
, pu_members
) = aux [] [] [] fields
in
633 and on_class_body trait_or_interface cb
=
634 let reversed_body = List.fold_left
(on_class_elt trait_or_interface
) make_empty_class_body cb
in
636 c_uses
= List.rev
reversed_body.c_uses
;
637 c_method_redeclarations
= List.rev
reversed_body.c_method_redeclarations
;
638 c_xhp_attr_uses
= List.rev
reversed_body.c_xhp_attr_uses
;
639 c_xhp_category
= List.rev
reversed_body.c_xhp_category
;
640 c_req_extends
= List.rev
reversed_body.c_req_extends
;
641 c_req_implements
= List.rev
reversed_body.c_req_implements
;
642 c_consts
= List.rev
reversed_body.c_consts
;
643 c_typeconsts
= List.rev
reversed_body.c_typeconsts
;
644 c_static_vars
= List.rev
reversed_body.c_static_vars
;
645 c_vars
= List.rev
reversed_body.c_vars
;
646 c_static_methods
= List.rev
reversed_body.c_static_methods
;
647 c_methods
= List.rev
reversed_body.c_methods
;
648 c_attributes
= List.rev
reversed_body.c_attributes
;
649 c_xhp_children
= List.rev
reversed_body.c_xhp_children
;
650 c_xhp_attrs
= List.rev
reversed_body.c_xhp_attrs
;
651 c_pu_enums
= List.rev
reversed_body.c_pu_enums
;
654 and on_class c
: Aast.class_
=
656 Aast.c_tparam_list
= on_list on_tparam c
.c_tparams;
657 Aast.c_tparam_constraints
= SMap.empty
;
659 let trait_or_interface = c
.c_kind
= Ctrait
|| c
.c_kind
= Cinterface
in
660 let body = on_class_body
trait_or_interface c
.c_body
in
667 c_is_xhp
= c
.c_is_xhp
;
670 c_tparams = c_tparams;
671 c_extends
= on_list on_hint c
.c_extends
;
672 c_uses
= body.c_uses
;
673 c_method_redeclarations
= body.c_method_redeclarations
;
674 c_xhp_attr_uses
= body.c_xhp_attr_uses
;
675 c_xhp_category
= body.c_xhp_category
;
676 c_req_extends
= body.c_req_extends
;
677 c_req_implements
= body.c_req_implements
;
678 c_implements
= on_list on_hint c
.c_implements
;
679 c_consts
= body.c_consts
;
680 c_typeconsts
= body.c_typeconsts
;
681 c_static_vars
= body.c_static_vars
;
682 c_vars
= body.c_vars
;
683 c_constructor
= body.c_constructor
;
684 c_static_methods
= body.c_static_methods
;
685 c_methods
= body.c_methods
;
686 c_attributes
= body.c_attributes
;
687 c_xhp_children
= body.c_xhp_children
;
688 c_xhp_attrs
= body.c_xhp_attrs
;
689 c_user_attributes
= on_list on_user_attribute c
.c_user_attributes
;
690 c_file_attributes
= on_list on_file_attribute c
.c_file_attributes
;
691 c_namespace
= c
.c_namespace
;
692 c_enum
= optional on_enum c
.c_enum
;
693 c_doc_comment
= c
.c_doc_comment
;
694 c_pu_enums
= body.c_pu_enums
699 and on_typedef t
: Aast.typedef
=
700 let t_vis = match t
.t_kind
with
701 | Alias _
-> Aast.Transparent
702 | NewType _
-> Aast.Opaque
704 let t_kind = match t
.t_kind with
705 | Alias h
-> on_hint h
706 | NewType h
-> on_hint h
711 t_tparams
= on_list on_tparam t
.t_tparams
;
712 t_constraint
= optional on_hint t
.t_constraint
;
714 t_user_attributes
= on_list on_user_attribute t
.t_user_attributes
;
717 t_namespace
= t
.t_namespace
;
720 and on_constant
(c
: gconst
) : Aast.gconst
=
723 cst_mode
= c
.cst_mode
;
724 cst_name
= c
.cst_name
;
725 cst_type
= optional on_hint c
.cst_type
;
726 cst_value
= Some
(on_expr c
.cst_value
);
727 cst_namespace
= c
.cst_namespace
;
730 and on_ns_use
(k
, id1
, id2
): (Aast.ns_kind
* Aast.sid
* Aast.sid
) =
731 let kind = match k
with
732 | NSNamespace
-> Aast.NSNamespace
733 | NSClass
-> Aast.NSClass
734 | NSClassAndNamespace
-> Aast.NSClassAndNamespace
735 | NSFun
-> Aast.NSFun
736 | NSConst
-> Aast.NSConst
740 and on_def
: def
-> Aast.def
= function
741 | Fun f
-> Aast.Fun
(on_fun f
)
742 | Class c
-> Aast.Class
(on_class c
)
743 | Stmt s
-> Aast.Stmt
(on_stmt s
)
744 | Typedef t
-> Aast.Typedef
(on_typedef t
)
745 | Constant c
-> Aast.Constant
(on_constant c
)
746 | Namespace
(id, p) -> Aast.Namespace
(id, on_program
p)
747 | NamespaceUse usel
-> Aast.NamespaceUse
(on_list on_ns_use usel
)
748 | SetNamespaceEnv env
-> Aast.SetNamespaceEnv env
749 | FileAttributes _
-> Aast.Stmt
(Pos.none
, Aast.Noop
)
751 and on_program ast
= on_list on_def ast
753 let convert ast
: Aast.program
= on_program ast