2 * Copyright (c) 2018, 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 Env
= Typing_env
13 module MakeType
= Typing_make_type
15 (*****************************************************************************)
16 (* Construct a Typing_env from an AAST toplevel definition.
18 (*****************************************************************************)
22 let fun_env ?origin ctx fd
=
24 let file = Pos.filename
(fst
f.f_name
) in
25 let droot = Some
(Typing_deps.Dep.Fun
(snd
f.f_name
)) in
26 let env = Typing_env_types.empty ?origin ctx
file ~mode
:fd
.fd_mode ~
droot in
27 Typing_inference_env.Identifier_provider.reinitialize
();
30 (* Given a class definition construct a type consisting of the
31 * class instantiated at its generic parameters. *)
32 let get_self_from_c c
=
34 List.map c
.c_tparams ~
f:(fun { tp_name
= (p
, s
); _
} ->
36 ( Reason.Rwitness_from_decl
(Pos_or_decl.of_raw_pos p
),
39 let (name_pos
, name
) = c
.c_name
in
40 let name_pos = Pos_or_decl.of_raw_pos
name_pos in
41 mk
(Reason.Rwitness_from_decl
name_pos, Tapply
((name_pos, name
), tparams))
43 (** Set 'self' identifier and type in environment. *)
45 let self_id = snd c
.c_name
in
46 let self = get_self_from_c c
in
47 (* For enums, localize makes self:: into an abstract type, which we don't
51 | Ast_defs.Cenum_class _
54 MakeType.class_type
(Reason.Rwitness
(fst c
.c_name
)) (snd c
.c_name
) []
59 let ((env, ty_err_opt
), res
) =
60 Typing_phase.localize_no_subst
env ~ignore_errors
:true self
62 Option.iter ty_err_opt ~
f:Errors.add_typing_error
;
65 let env = Env.set_self env self_id self_ty
in
67 Env.add_upper_bound
env Naming_special_names.Typehints.this self_ty
71 Env.add_lower_bound
env Naming_special_names.Typehints.this self_ty
77 let set_parent env c
=
78 (* In order to type-check a class, we need to know what "parent"
79 * refers to. Sometimes people write "parent::", when that happens,
80 * we need to know the type of parent.
82 match c
.c_extends
with
83 | ((_
, Happly
((_
, parent_id
), _
)) as parent_ty
) :: _
->
84 let parent_ty = Decl_hint.hint
env.Typing_env_types.decl_env
parent_ty in
85 Env.set_parent env parent_id
parent_ty
86 (* The only case where we have more than one parent class is when
87 * dealing with interfaces and interfaces cannot use parent.
93 let class_env ?origin ctx c
=
94 let file = Pos.filename
(fst c
.c_name
) in
95 let droot = Some
(Typing_deps.Dep.Type
(snd c
.c_name
)) in
96 let env = Typing_env_types.empty ?origin ctx
file ~mode
:c
.c_mode ~
droot in
97 Typing_inference_env.Identifier_provider.reinitialize
();
98 let env = set_self env c
in
99 let env = set_parent env c
in
102 let typedef_env ?origin ctx t
=
103 let file = Pos.filename
(fst t
.t_kind
) in
104 let droot = Some
(Typing_deps.Dep.Type
(snd t
.t_name
)) in
105 let env = Typing_env_types.empty ?origin ctx
file ~mode
:t
.t_mode ~
droot in
106 Typing_inference_env.Identifier_provider.reinitialize
();
109 let gconst_env ?origin ctx cst
=
110 let file = Pos.filename
(fst cst
.cst_name
) in
111 let droot = Some
(Typing_deps.Dep.GConst
(snd cst
.cst_name
)) in
112 let env = Typing_env_types.empty ?origin ctx
file ~mode
:cst
.cst_mode ~
droot in
113 Typing_inference_env.Identifier_provider.reinitialize
();