2 * Copyright (c) 2016, 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.
14 (* Exception representing not finding a class during decl *)
15 exception Decl_not_found
of string
17 (* A substitution context contains all the information necessary for
18 * changing the type of an inherited class element to the class that is
19 * inheriting the class element. It's best illustrated via an example.
21 * class A<Ta1, Ta2> { public function test(Ta1 $x, Ta2 $y): void {} }
23 * class B<Tb> extends A<Tb, int> {}
25 * class C extends B<string> {}
27 * The method `A::test()` has the type (function(Ta1, Ta2): void) in the
28 * context of class A. However in the context of class B, it will have type
29 * (function(Tb, int): void).
31 * The substitution that leads to this change is [Ta1 -> Tb, Ta2 -> int],
32 * which will produce a new type in the context of class B. It's subst_context
35 * { sc_subst = [Ta1 -> Tb, Ta2 -> int];
36 * sc_class_context = 'B';
37 * sc_from_req_extends = false;
40 * The `sc_from_req_extends` field is set to true if the context was inherited
41 * via a require extends type. This information is relevant when folding
42 * `dc_substs` during inheritance. See Decl_inherit module.
44 type subst_context
= {
45 sc_subst
: decl ty
SMap.t
;
46 sc_class_context
: string;
47 sc_from_req_extends
: bool;
50 type source_type
= Child
| Parent
| Trait
| XHPAttr
| Interface
| ReqImpl
| ReqExtends
54 (* The class's name *)
56 (* The position at which this element was directly included in the hierarchy.
57 If C extends B extends A, the use_pos of A in C's linearization will be the
58 position of the class name A in the line "class B extends A". *)
60 (* Like mro_use_pos, but includes type arguments (if any). *)
62 (* The type arguments with which this ancestor class was instantiated. The
63 first class in the linearization (the one which was linearized) will have
64 an empty list here, even when it takes type parameters. *)
65 mro_type_args
: decl ty list
;
66 (* True if this element referred to a class whose definition could not be
67 found. This is always indicative of an "Unbound name" error (emitted by
68 Naming), so one could imagine omitting elements with this flag set from the
69 linearization (since correct programs will not have them), but keeping
70 track of them helps reduce cascading errors in the event of a typo.
71 Additionally, it's helpful to do this (for now) to keep the behavior of
72 shallow_class_decl equivalent to legacy decl. *)
73 mro_class_not_found
: bool;
74 (* When this is [Some], this mro_element represents an attempt to include a
75 linearization within itself. We include these in the linearization for the
76 sake of error reporting (they will not occur in correct programs). The
77 SSet.t is the set of class names known to have been involved in the
78 inclusion of this class in the linearization. *)
79 mro_cyclic
: SSet.t
option;
80 (* If this element is included in the linearization because it was directly
81 required by some ancestor, this will be [Some], and the position will be
82 the location where this requirement was most recently included into the
84 mro_required_at
: Pos.t
option;
85 (* True if this element is included in the linearization (directly or
86 indirectly) because of a require extends or require implements
88 mro_synthesized
: bool;
89 (* True if this element is included in the linearization because of any
90 XHP-attribute-inclusion relationship, and thus, the linearized class
91 inherits only the XHP attributes from this element. *)
92 mro_xhp_attrs_only
: bool;
93 (* True if this element is included in the linearization because of a
94 interface-implementation relationship, and thus, the linearized class
95 inherits only the class constants and type constants from this element. *)
96 mro_consts_only
: bool;
97 (* True if this element is included in the linearization via an unbroken chain
98 of trait-use relationships, and thus, the linearized class inherits the
99 private members of this element (on account of the runtime behavior where
100 they are effectively copied into the linearized class). *)
101 mro_copy_private_members
: bool;
102 (* True if this element is included in the linearization via an unbroken chain
103 of abstract classes, and thus, abstract type constants with default values
104 are inherited unchanged. When this flag is not set, a concrete class was
105 present in the chain. Since we convert abstract type constants with
106 defaults to concrete ones when they are included in a concrete class, any
107 type constant which 1) is abstract, 2) has a default, and 3) was inherited
108 from an ancestor with this flag not set, should be inherited as a concrete
109 type constant instead. *)
110 mro_passthrough_abstract_typeconst
: bool;
114 type linearization
= mro_element
Sequence.t
116 type decl_class_type
= {
118 dc_members_fully_known
: bool;
121 dc_is_disposable
: bool;
124 dc_deferred_init_members
: SSet.t
;
125 dc_kind
: Ast_defs.class_kind
;
129 dc_tparams
: decl tparam list
;
130 (* class name to the subst_context that must be applied to that class *)
131 dc_substs
: subst_context
SMap.t
;
132 dc_consts
: class_const
SMap.t
;
133 dc_typeconsts
: typeconst_type
SMap.t
;
134 dc_props
: element
SMap.t
;
135 dc_sprops
: element
SMap.t
;
136 dc_methods
: element
SMap.t
;
137 dc_smethods
: element
SMap.t
;
138 dc_construct
: element
option * consistent_kind
;
139 dc_ancestors
: decl ty
SMap.t
;
140 dc_req_ancestors
: requirement list
;
141 dc_req_ancestors_extends
: SSet.t
;
143 dc_sealed_whitelist
: SSet.t
option;
144 dc_xhp_attr_deps
: SSet.t
;
145 dc_enum_type
: enum_type
option;
146 dc_decl_errors
: Errors.t
option [@opaque
];
147 (* this field is used to prevent condition types being filtered
148 in Decl_redecl_service.is_dependent_class_of_any *)
149 dc_condition_types
: SSet.t
;
152 (* name of condition type for conditional reactivity of methods.
153 If None - method is unconditionally reactive *)
154 and condition_type_name
= string option
156 and method_reactivity
=
157 | Method_reactive
of condition_type_name
158 | Method_shallow
of condition_type_name
159 | Method_local
of condition_type_name
163 elt_synthesized
: bool;
165 (* Only relevant for methods *)
167 elt_memoizelsb
: bool;
169 elt_reactivity
: method_reactivity
option;
171 (* Only relevant for properties *)
172 elt_xhp_attr
: xhp_attr
option;
178 elt_visibility
: visibility
;