aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/data.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/data.rs')
-rw-r--r--crates/ra_hir_def/src/data.rs279
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
3use std::sync::Arc;
4
5use hir_expand::{name::Name, InFile};
6use ra_prof::profile;
7use ra_syntax::ast;
8
9use 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)]
21pub 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
34impl 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)]
54pub 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
62impl 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)]
81pub struct TraitData {
82 pub name: Name,
83 pub items: Vec<(Name, AssocItemId)>,
84 pub auto: bool,
85}
86
87impl 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)]
127pub 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
134impl 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)]
164pub struct ConstData {
165 /// const _: () = ();
166 pub name: Option<Name>,
167 pub type_ref: TypeRef,
168 pub visibility: RawVisibility,
169}
170
171impl 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)]
186pub struct StaticData {
187 pub name: Option<Name>,
188 pub type_ref: TypeRef,
189 pub visibility: RawVisibility,
190 pub mutable: bool,
191}
192
193impl 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
208fn 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}