1use super::check::DeclInfo;
13use super::constant;
14use super::obj::LangObj;
15use super::package::Package;
16use super::scope::Scope;
17use super::typ::*;
18use super::universe::Universe;
19use go_parser::{piggy_key_type, PiggyVec, Pos};
20use std::borrow::Cow;
21
22piggy_key_type! {
23 pub struct ObjKey;
24 pub struct TypeKey;
25 pub struct PackageKey;
26 pub struct DeclInfoKey;
27 pub struct ScopeKey;
28}
29
30pub type LangObjs = PiggyVec<ObjKey, LangObj>;
31pub type Types = PiggyVec<TypeKey, Type>;
32pub type Packages = PiggyVec<PackageKey, Package>;
33pub type Decls = PiggyVec<DeclInfoKey, DeclInfo>;
34pub type Scopes = PiggyVec<ScopeKey, Scope>;
35
36pub struct TCObjects {
39 pub lobjs: LangObjs,
40 pub types: Types,
41 pub pkgs: Packages,
42 pub decls: Decls,
43 pub scopes: Scopes,
44 pub universe: Option<Universe>,
45 pub fmt_qualifier: Box<dyn Fn(&Package) -> Cow<str>>,
47}
48
49fn default_fmt_qualifier(p: &Package) -> Cow<str> {
50 p.path().into()
51}
52
53impl TCObjects {
54 pub fn new() -> TCObjects {
55 let fmtq = Box::new(default_fmt_qualifier);
56 const CAP: usize = 16;
57 let mut objs = TCObjects {
58 lobjs: PiggyVec::with_capacity(CAP),
59 types: PiggyVec::with_capacity(CAP),
60 pkgs: PiggyVec::with_capacity(CAP),
61 decls: PiggyVec::with_capacity(CAP),
62 scopes: PiggyVec::with_capacity(CAP),
63 universe: None,
64 fmt_qualifier: fmtq,
65 };
66 objs.universe = Some(Universe::new(&mut objs));
67 objs
68 }
69
70 pub fn universe(&self) -> &Universe {
71 self.universe.as_ref().unwrap()
72 }
73
74 pub fn new_scope(
75 &mut self,
76 parent: Option<ScopeKey>,
77 pos: Pos,
78 end: Pos,
79 comment: String,
80 is_func: bool,
81 ) -> ScopeKey {
82 let scope = Scope::new(parent, pos, end, comment, is_func);
83 let skey = self.scopes.insert(scope);
84 if let Some(s) = parent {
85 if s != *self.universe().scope() {
87 self.scopes[s].add_child(skey);
88 }
89 }
90 skey
91 }
92
93 pub fn new_package(&mut self, path: String) -> PackageKey {
94 let skey = self.new_scope(
95 Some(*self.universe().scope()),
96 0,
97 0,
98 format!("package {}", path),
99 false,
100 );
101 let pkg = Package::new(path, None, skey);
102 self.pkgs.insert(pkg)
103 }
104
105 pub fn new_pkg_name(
106 &mut self,
107 pos: Pos,
108 pkg: Option<PackageKey>,
109 name: String,
110 imported: PackageKey,
111 ) -> ObjKey {
112 let lobj = LangObj::new_pkg_name(pos, pkg, name, imported, self.universe());
113 self.lobjs.insert(lobj)
114 }
115
116 pub fn new_const(
117 &mut self,
118 pos: Pos,
119 pkg: Option<PackageKey>,
120 name: String,
121 typ: Option<TypeKey>,
122 val: constant::Value,
123 ) -> ObjKey {
124 let lobj = LangObj::new_const(pos, pkg, name, typ, val);
125 self.lobjs.insert(lobj)
126 }
127
128 pub fn new_type_name(
129 &mut self,
130 pos: Pos,
131 pkg: Option<PackageKey>,
132 name: String,
133 typ: Option<TypeKey>,
134 ) -> ObjKey {
135 let lobj = LangObj::new_type_name(pos, pkg, name, typ);
136 self.lobjs.insert(lobj)
137 }
138
139 pub fn new_var(
140 &mut self,
141 pos: Pos,
142 pkg: Option<PackageKey>,
143 name: String,
144 typ: Option<TypeKey>,
145 ) -> ObjKey {
146 let lobj = LangObj::new_var(pos, pkg, name, typ);
147 self.lobjs.insert(lobj)
148 }
149
150 pub fn new_param_var(
151 &mut self,
152 pos: Pos,
153 pkg: Option<PackageKey>,
154 name: String,
155 typ: Option<TypeKey>,
156 ) -> ObjKey {
157 let lobj = LangObj::new_param_var(pos, pkg, name, typ);
158 self.lobjs.insert(lobj)
159 }
160
161 pub fn new_field(
162 &mut self,
163 pos: Pos,
164 pkg: Option<PackageKey>,
165 name: String,
166 typ: Option<TypeKey>,
167 embedded: bool,
168 ) -> ObjKey {
169 let lobj = LangObj::new_field(pos, pkg, name, typ, embedded);
170 self.lobjs.insert(lobj)
171 }
172
173 pub fn new_func(
174 &mut self,
175 pos: Pos,
176 pkg: Option<PackageKey>,
177 name: String,
178 typ: Option<TypeKey>,
179 ) -> ObjKey {
180 let lobj = LangObj::new_func(pos, pkg, name, typ);
181 self.lobjs.insert(lobj)
182 }
183
184 pub fn new_label(&mut self, pos: Pos, pkg: Option<PackageKey>, name: String) -> ObjKey {
185 let lobj = LangObj::new_label(pos, pkg, name, self.universe());
186 self.lobjs.insert(lobj)
187 }
188
189 pub fn new_t_basic(&mut self, typ: BasicType, info: BasicInfo, name: &'static str) -> TypeKey {
190 self.types
191 .insert(Type::Basic(BasicDetail::new(typ, info, name)))
192 }
193
194 pub fn new_t_array(&mut self, elem: TypeKey, len: Option<u64>) -> TypeKey {
195 self.types.insert(Type::Array(ArrayDetail::new(elem, len)))
196 }
197
198 pub fn new_t_slice(&mut self, elem: TypeKey) -> TypeKey {
199 self.types.insert(Type::Slice(SliceDetail::new(elem)))
200 }
201
202 pub fn new_t_struct(
203 &mut self,
204 fields: Vec<ObjKey>,
205 tags: Option<Vec<Option<String>>>,
206 ) -> TypeKey {
207 self.types
208 .insert(Type::Struct(StructDetail::new(fields, tags, self)))
209 }
210 pub fn new_t_pointer(&mut self, base: TypeKey) -> TypeKey {
211 self.types.insert(Type::Pointer(PointerDetail::new(base)))
212 }
213
214 pub fn new_t_tuple(&mut self, vars: Vec<ObjKey>) -> TypeKey {
215 self.types.insert(Type::Tuple(TupleDetail::new(vars)))
216 }
217
218 pub fn new_t_signature(
219 &mut self,
220 scope: Option<ScopeKey>,
221 recv: Option<ObjKey>,
222 params: TypeKey,
223 results: TypeKey,
224 variadic: bool,
225 ) -> TypeKey {
226 self.types.insert(Type::Signature(SignatureDetail::new(
227 scope, recv, params, results, variadic, self,
228 )))
229 }
230
231 pub fn new_t_interface(&mut self, methods: Vec<ObjKey>, embeddeds: Vec<TypeKey>) -> TypeKey {
232 let iface = Type::Interface(InterfaceDetail::new(methods, embeddeds, self));
233 self.types.insert(iface)
234 }
235
236 pub fn new_t_empty_interface(&mut self) -> TypeKey {
237 self.types
238 .insert(Type::Interface(InterfaceDetail::new_empty()))
239 }
240
241 pub fn new_t_map(&mut self, key: TypeKey, elem: TypeKey) -> TypeKey {
242 self.types.insert(Type::Map(MapDetail::new(key, elem)))
243 }
244 pub fn new_t_chan(&mut self, dir: ChanDir, elem: TypeKey) -> TypeKey {
245 self.types.insert(Type::Chan(ChanDetail::new(dir, elem)))
246 }
247 pub fn new_t_named(
248 &mut self,
249 obj: Option<ObjKey>,
250 underlying: Option<TypeKey>,
251 methods: Vec<ObjKey>,
252 ) -> TypeKey {
253 self.types.insert(Type::Named(NamedDetail::new(
254 obj, underlying, methods, self,
255 )))
256 }
257}