enable class constants in folded classes
[hiphop-php.git] / hphp / hack / src / rupro / lib / typing_env.rs
blob50a199241f761c801c1d499ed1c9e4e795a0d6b7
1 // Copyright (c) Facebook, Inc. and its affiliates.
2 //
3 // This source code is licensed under the MIT license found in the
4 // LICENSE file in the "hack" directory of this source tree.
6 #![allow(dead_code)]
7 use std::cell::RefCell;
8 use std::rc::Rc;
9 use std::sync::Arc;
11 use crate::reason::Reason;
12 use crate::tast::SavedEnv;
13 use crate::typing_ctx::TypingCtx;
14 use crate::typing_defs::{ParamMode, Ty};
15 use crate::typing_error::TypingError;
16 use crate::typing_local_types::{Local, LocalMap};
17 use crate::typing_return::TypingReturnInfo;
18 use crate::utils::core::{IdentGen, LocalId};
20 use im::HashMap;
22 pub struct TEnv<R: Reason> {
23     pub ctx: Arc<TypingCtx<R>>,
25     genv: Rc<TGEnv<R>>,
26     lenv: Rc<TLEnv<R>>,
28     idents: IdentGen,
29     errors: Rc<RefCell<Vec<TypingError<R>>>>,
32 struct TGEnv<R: Reason> {
33     return_: RefCell<TypingReturnInfo<R>>,
34     params: RefCell<HashMap<LocalId, (Ty<R>, R::Pos, ParamMode)>>,
37 struct TLEnv<R: Reason> {
38     per_cont_env: PerContEnv<R>,
41 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
42 enum TypingContKey {
43     Next,
44     Continue,
45     Break,
46     Catch,
47     Do,
48     Exit,
49     Fallthrough,
50     Finally,
53 #[derive(Debug, Clone)]
54 struct PerContEnv<R: Reason>(RefCell<HashMap<TypingContKey, PerContEntry<R>>>);
56 #[derive(Debug, Clone)]
57 struct PerContEntry<R: Reason> {
58     local_types: LocalMap<R>,
61 impl<R: Reason> TGEnv<R> {
62     fn new(ctx: &TypingCtx<R>) -> Self {
63         Self {
64             return_: RefCell::new(TypingReturnInfo::placeholder(ctx.alloc)),
65             params: RefCell::new(HashMap::new()),
66         }
67     }
70 impl<R: Reason> TLEnv<R> {
71     fn new() -> Self {
72         Self {
73             per_cont_env: PerContEnv::new(),
74         }
75     }
78 impl<R: Reason> PerContEnv<R> {
79     fn new() -> Self {
80         Self(RefCell::new(HashMap::new()))
81     }
83     fn add(&self, key: TypingContKey, x: LocalId, ty: Local<R>) {
84         if let Some(cont) = self.0.borrow_mut().get_mut(&key) {
85             cont.local_types.add(x, ty);
86         }
87     }
89     fn get(&self, key: TypingContKey, x: &LocalId) -> Option<Local<R>> {
90         self.0
91             .borrow()
92             .get(&key)
93             .and_then(|env| env.local_types.get(x))
94             .cloned()
95     }
97     fn has_cont(&self, key: TypingContKey) -> bool {
98         self.0.borrow().get(&key).is_some()
99     }
102 impl<R: Reason> TEnv<R> {
103     pub fn new(ctx: Arc<TypingCtx<R>>) -> Self {
104         let genv = Rc::new(TGEnv::new(&ctx));
105         Self {
106             ctx,
108             genv,
109             lenv: Rc::new(TLEnv::new()),
111             idents: IdentGen::new(),
112             errors: Rc::new(RefCell::new(Vec::new())),
113         }
114     }
116     pub fn destruct(self) -> Vec<TypingError<R>> {
117         let mut empty = Vec::new();
118         let mut full = self.errors.borrow_mut();
119         std::mem::swap(&mut empty, &mut full);
120         empty
121     }
123     pub fn add_error(&self, error: TypingError<R>) {
124         self.errors.borrow_mut().push(error)
125     }
127     pub fn fun_env(ctx: Arc<TypingCtx<R>>, _fd: &oxidized::aast::FunDef<(), ()>) -> Self {
128         Self::new(ctx)
129     }
131     pub fn set_param(&self, id: LocalId, ty: Ty<R>, pos: R::Pos, param_mode: ParamMode) {
132         self.genv
133             .params
134             .borrow_mut()
135             .insert(id, (ty, pos, param_mode));
136     }
138     pub fn get_params(&self) -> HashMap<LocalId, (Ty<R>, R::Pos, ParamMode)> {
139         self.genv.params.borrow().clone()
140     }
142     pub fn set_params(&self, m: HashMap<LocalId, (Ty<R>, R::Pos, ParamMode)>) {
143         *self.genv.params.borrow_mut() = m;
144     }
146     fn set_local_(&self, x: LocalId, ty: Local<R>) {
147         self.lenv.per_cont_env.add(TypingContKey::Next, x, ty);
148     }
150     pub fn set_local(&self, immutable: bool, x: LocalId, ty: Ty<R>, pos: R::Pos) {
151         // TODO(hrust): union simplification
152         let expr_id = match self.lenv.per_cont_env.get(TypingContKey::Next, &x) {
153             None => self.idents.make(),
154             Some(l) => l.expr_id,
155         };
156         if immutable {
157             unimplemented!()
158         }
159         self.set_local_(x, Local { ty, pos, expr_id })
160     }
162     pub fn get_return(&self) -> TypingReturnInfo<R> {
163         self.genv.return_.borrow().clone()
164     }
166     pub fn set_return(&self, ret: TypingReturnInfo<R>) {
167         *self.genv.return_.borrow_mut() = ret;
168     }
170     pub fn has_next(&self) -> bool {
171         self.lenv.per_cont_env.has_cont(TypingContKey::Next)
172     }
174     pub fn save(&self, _local_tpenv: ()) -> SavedEnv {
175         SavedEnv
176     }