diff options
Diffstat (limited to 'crates/ra_hir_def/src/data.rs')
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 279 |
1 files changed, 0 insertions, 279 deletions
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs deleted file mode 100644 index 88a8ef9bf..000000000 --- a/crates/ra_hir_def/src/data.rs +++ /dev/null | |||
@@ -1,279 +0,0 @@ | |||
1 | //! Contains basic data about various HIR declarations. | ||
2 | |||
3 | use std::sync::Arc; | ||
4 | |||
5 | use hir_expand::{name::Name, InFile}; | ||
6 | use ra_prof::profile; | ||
7 | use ra_syntax::ast; | ||
8 | |||
9 | use crate::{ | ||
10 | attr::Attrs, | ||
11 | body::Expander, | ||
12 | db::DefDatabase, | ||
13 | item_tree::{AssocItem, ItemTreeId, ModItem}, | ||
14 | type_ref::{TypeBound, TypeRef}, | ||
15 | visibility::RawVisibility, | ||
16 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, | ||
17 | Intern, Lookup, ModuleId, StaticId, TraitId, TypeAliasId, TypeAliasLoc, | ||
18 | }; | ||
19 | |||
20 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
21 | pub struct FunctionData { | ||
22 | pub name: Name, | ||
23 | pub params: Vec<TypeRef>, | ||
24 | pub ret_type: TypeRef, | ||
25 | pub attrs: Attrs, | ||
26 | /// True if the first param is `self`. This is relevant to decide whether this | ||
27 | /// can be called as a method. | ||
28 | pub has_self_param: bool, | ||
29 | pub is_unsafe: bool, | ||
30 | pub is_varargs: bool, | ||
31 | pub visibility: RawVisibility, | ||
32 | } | ||
33 | |||
34 | impl FunctionData { | ||
35 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { | ||
36 | let loc = func.lookup(db); | ||
37 | let item_tree = db.item_tree(loc.id.file_id); | ||
38 | let func = &item_tree[loc.id.value]; | ||
39 | |||
40 | Arc::new(FunctionData { | ||
41 | name: func.name.clone(), | ||
42 | params: func.params.to_vec(), | ||
43 | ret_type: func.ret_type.clone(), | ||
44 | attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), | ||
45 | has_self_param: func.has_self_param, | ||
46 | is_unsafe: func.is_unsafe, | ||
47 | is_varargs: func.is_varargs, | ||
48 | visibility: item_tree[func.visibility].clone(), | ||
49 | }) | ||
50 | } | ||
51 | } | ||
52 | |||
53 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
54 | pub struct TypeAliasData { | ||
55 | pub name: Name, | ||
56 | pub type_ref: Option<TypeRef>, | ||
57 | pub visibility: RawVisibility, | ||
58 | /// Bounds restricting the type alias itself (eg. `type Ty: Bound;` in a trait or impl). | ||
59 | pub bounds: Vec<TypeBound>, | ||
60 | } | ||
61 | |||
62 | impl TypeAliasData { | ||
63 | pub(crate) fn type_alias_data_query( | ||
64 | db: &dyn DefDatabase, | ||
65 | typ: TypeAliasId, | ||
66 | ) -> Arc<TypeAliasData> { | ||
67 | let loc = typ.lookup(db); | ||
68 | let item_tree = db.item_tree(loc.id.file_id); | ||
69 | let typ = &item_tree[loc.id.value]; | ||
70 | |||
71 | Arc::new(TypeAliasData { | ||
72 | name: typ.name.clone(), | ||
73 | type_ref: typ.type_ref.clone(), | ||
74 | visibility: item_tree[typ.visibility].clone(), | ||
75 | bounds: typ.bounds.to_vec(), | ||
76 | }) | ||
77 | } | ||
78 | } | ||
79 | |||
80 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
81 | pub struct TraitData { | ||
82 | pub name: Name, | ||
83 | pub items: Vec<(Name, AssocItemId)>, | ||
84 | pub auto: bool, | ||
85 | } | ||
86 | |||
87 | impl TraitData { | ||
88 | pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> { | ||
89 | let tr_loc = tr.lookup(db); | ||
90 | let item_tree = db.item_tree(tr_loc.id.file_id); | ||
91 | let tr_def = &item_tree[tr_loc.id.value]; | ||
92 | let name = tr_def.name.clone(); | ||
93 | let auto = tr_def.auto; | ||
94 | let module_id = tr_loc.container.module(db); | ||
95 | let container = AssocContainerId::TraitId(tr); | ||
96 | let mut expander = Expander::new(db, tr_loc.id.file_id, module_id); | ||
97 | |||
98 | let items = collect_items( | ||
99 | db, | ||
100 | module_id, | ||
101 | &mut expander, | ||
102 | tr_def.items.iter().copied(), | ||
103 | tr_loc.id.file_id, | ||
104 | container, | ||
105 | 100, | ||
106 | ); | ||
107 | |||
108 | Arc::new(TraitData { name, items, auto }) | ||
109 | } | ||
110 | |||
111 | pub fn associated_types(&self) -> impl Iterator<Item = TypeAliasId> + '_ { | ||
112 | self.items.iter().filter_map(|(_name, item)| match item { | ||
113 | AssocItemId::TypeAliasId(t) => Some(*t), | ||
114 | _ => None, | ||
115 | }) | ||
116 | } | ||
117 | |||
118 | pub fn associated_type_by_name(&self, name: &Name) -> Option<TypeAliasId> { | ||
119 | self.items.iter().find_map(|(item_name, item)| match item { | ||
120 | AssocItemId::TypeAliasId(t) if item_name == name => Some(*t), | ||
121 | _ => None, | ||
122 | }) | ||
123 | } | ||
124 | } | ||
125 | |||
126 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
127 | pub struct ImplData { | ||
128 | pub target_trait: Option<TypeRef>, | ||
129 | pub target_type: TypeRef, | ||
130 | pub items: Vec<AssocItemId>, | ||
131 | pub is_negative: bool, | ||
132 | } | ||
133 | |||
134 | impl ImplData { | ||
135 | pub(crate) fn impl_data_query(db: &dyn DefDatabase, id: ImplId) -> Arc<ImplData> { | ||
136 | let _p = profile("impl_data_query"); | ||
137 | let impl_loc = id.lookup(db); | ||
138 | |||
139 | let item_tree = db.item_tree(impl_loc.id.file_id); | ||
140 | let impl_def = &item_tree[impl_loc.id.value]; | ||
141 | let target_trait = impl_def.target_trait.clone(); | ||
142 | let target_type = impl_def.target_type.clone(); | ||
143 | let is_negative = impl_def.is_negative; | ||
144 | let module_id = impl_loc.container.module(db); | ||
145 | let container = AssocContainerId::ImplId(id); | ||
146 | let mut expander = Expander::new(db, impl_loc.id.file_id, module_id); | ||
147 | |||
148 | let items = collect_items( | ||
149 | db, | ||
150 | module_id, | ||
151 | &mut expander, | ||
152 | impl_def.items.iter().copied(), | ||
153 | impl_loc.id.file_id, | ||
154 | container, | ||
155 | 100, | ||
156 | ); | ||
157 | let items = items.into_iter().map(|(_, item)| item).collect(); | ||
158 | |||
159 | Arc::new(ImplData { target_trait, target_type, items, is_negative }) | ||
160 | } | ||
161 | } | ||
162 | |||
163 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
164 | pub struct ConstData { | ||
165 | /// const _: () = (); | ||
166 | pub name: Option<Name>, | ||
167 | pub type_ref: TypeRef, | ||
168 | pub visibility: RawVisibility, | ||
169 | } | ||
170 | |||
171 | impl ConstData { | ||
172 | pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { | ||
173 | let loc = konst.lookup(db); | ||
174 | let item_tree = db.item_tree(loc.id.file_id); | ||
175 | let konst = &item_tree[loc.id.value]; | ||
176 | |||
177 | Arc::new(ConstData { | ||
178 | name: konst.name.clone(), | ||
179 | type_ref: konst.type_ref.clone(), | ||
180 | visibility: item_tree[konst.visibility].clone(), | ||
181 | }) | ||
182 | } | ||
183 | } | ||
184 | |||
185 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
186 | pub struct StaticData { | ||
187 | pub name: Option<Name>, | ||
188 | pub type_ref: TypeRef, | ||
189 | pub visibility: RawVisibility, | ||
190 | pub mutable: bool, | ||
191 | } | ||
192 | |||
193 | impl StaticData { | ||
194 | pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { | ||
195 | let node = konst.lookup(db); | ||
196 | let item_tree = db.item_tree(node.id.file_id); | ||
197 | let statik = &item_tree[node.id.value]; | ||
198 | |||
199 | Arc::new(StaticData { | ||
200 | name: Some(statik.name.clone()), | ||
201 | type_ref: statik.type_ref.clone(), | ||
202 | visibility: item_tree[statik.visibility].clone(), | ||
203 | mutable: statik.mutable, | ||
204 | }) | ||
205 | } | ||
206 | } | ||
207 | |||
208 | fn collect_items( | ||
209 | db: &dyn DefDatabase, | ||
210 | module: ModuleId, | ||
211 | expander: &mut Expander, | ||
212 | assoc_items: impl Iterator<Item = AssocItem>, | ||
213 | file_id: crate::HirFileId, | ||
214 | container: AssocContainerId, | ||
215 | limit: usize, | ||
216 | ) -> Vec<(Name, AssocItemId)> { | ||
217 | if limit == 0 { | ||
218 | return Vec::new(); | ||
219 | } | ||
220 | |||
221 | let item_tree = db.item_tree(file_id); | ||
222 | let cfg_options = db.crate_graph()[module.krate].cfg_options.clone(); | ||
223 | |||
224 | let mut items = Vec::new(); | ||
225 | for item in assoc_items { | ||
226 | match item { | ||
227 | AssocItem::Function(id) => { | ||
228 | let item = &item_tree[id]; | ||
229 | let attrs = item_tree.attrs(ModItem::from(id).into()); | ||
230 | if !attrs.is_cfg_enabled(&cfg_options) { | ||
231 | continue; | ||
232 | } | ||
233 | let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); | ||
234 | items.push((item.name.clone(), def.into())); | ||
235 | } | ||
236 | // FIXME: cfg? | ||
237 | AssocItem::Const(id) => { | ||
238 | let item = &item_tree[id]; | ||
239 | let name = match item.name.clone() { | ||
240 | Some(name) => name, | ||
241 | None => continue, | ||
242 | }; | ||
243 | let def = ConstLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); | ||
244 | items.push((name, def.into())); | ||
245 | } | ||
246 | AssocItem::TypeAlias(id) => { | ||
247 | let item = &item_tree[id]; | ||
248 | let def = TypeAliasLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); | ||
249 | items.push((item.name.clone(), def.into())); | ||
250 | } | ||
251 | AssocItem::MacroCall(call) => { | ||
252 | let call = &item_tree[call]; | ||
253 | let ast_id_map = db.ast_id_map(file_id); | ||
254 | let root = db.parse_or_expand(file_id).unwrap(); | ||
255 | let call = ast_id_map.get(call.ast_id).to_node(&root); | ||
256 | |||
257 | if let Some((mark, mac)) = expander.enter_expand(db, None, call) { | ||
258 | let src: InFile<ast::MacroItems> = expander.to_source(mac); | ||
259 | let item_tree = db.item_tree(src.file_id); | ||
260 | let iter = | ||
261 | item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); | ||
262 | items.extend(collect_items( | ||
263 | db, | ||
264 | module, | ||
265 | expander, | ||
266 | iter, | ||
267 | src.file_id, | ||
268 | container, | ||
269 | limit - 1, | ||
270 | )); | ||
271 | |||
272 | expander.exit(db, mark); | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | |||
278 | items | ||
279 | } | ||