diff options
Diffstat (limited to 'crates/hir_def/src/data.rs')
-rw-r--r-- | crates/hir_def/src/data.rs | 62 |
1 files changed, 41 insertions, 21 deletions
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index 1a27f7bf2..0be868ba2 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -9,7 +9,7 @@ use crate::{ | |||
9 | attr::Attrs, | 9 | attr::Attrs, |
10 | body::Expander, | 10 | body::Expander, |
11 | db::DefDatabase, | 11 | db::DefDatabase, |
12 | item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem}, | 12 | item_tree::{AssocItem, FunctionQualifier, ItemTreeId, ModItem, Param}, |
13 | type_ref::{TypeBound, TypeRef}, | 13 | type_ref::{TypeBound, TypeRef}, |
14 | visibility::RawVisibility, | 14 | visibility::RawVisibility, |
15 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, | 15 | AssocContainerId, AssocItemId, ConstId, ConstLoc, FunctionId, FunctionLoc, HasModule, ImplId, |
@@ -36,19 +36,38 @@ impl FunctionData { | |||
36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { | 36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { |
37 | let loc = func.lookup(db); | 37 | let loc = func.lookup(db); |
38 | let krate = loc.container.module(db).krate; | 38 | let krate = loc.container.module(db).krate; |
39 | let item_tree = db.item_tree(loc.id.file_id); | 39 | let crate_graph = db.crate_graph(); |
40 | let cfg_options = &crate_graph[krate].cfg_options; | ||
41 | let item_tree = loc.id.item_tree(db); | ||
40 | let func = &item_tree[loc.id.value]; | 42 | let func = &item_tree[loc.id.value]; |
41 | 43 | ||
44 | let enabled_params = func | ||
45 | .params | ||
46 | .clone() | ||
47 | .filter(|¶m| item_tree.attrs(db, krate, param.into()).is_cfg_enabled(cfg_options)); | ||
48 | |||
49 | // If last cfg-enabled param is a `...` param, it's a varargs function. | ||
50 | let is_varargs = enabled_params | ||
51 | .clone() | ||
52 | .next_back() | ||
53 | .map_or(false, |param| matches!(item_tree[param], Param::Varargs)); | ||
54 | |||
42 | Arc::new(FunctionData { | 55 | Arc::new(FunctionData { |
43 | name: func.name.clone(), | 56 | name: func.name.clone(), |
44 | params: func.params.iter().map(|id| item_tree[*id].clone()).collect(), | 57 | params: enabled_params |
58 | .clone() | ||
59 | .filter_map(|id| match &item_tree[id] { | ||
60 | Param::Normal(ty) => Some(item_tree[*ty].clone()), | ||
61 | Param::Varargs => None, | ||
62 | }) | ||
63 | .collect(), | ||
45 | ret_type: item_tree[func.ret_type].clone(), | 64 | ret_type: item_tree[func.ret_type].clone(), |
46 | attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), | 65 | attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()), |
47 | has_self_param: func.has_self_param, | 66 | has_self_param: func.has_self_param, |
48 | has_body: func.has_body, | 67 | has_body: func.has_body, |
49 | qualifier: func.qualifier.clone(), | 68 | qualifier: func.qualifier.clone(), |
50 | is_in_extern_block: func.is_in_extern_block, | 69 | is_in_extern_block: func.is_in_extern_block, |
51 | is_varargs: func.is_varargs, | 70 | is_varargs, |
52 | visibility: item_tree[func.visibility].clone(), | 71 | visibility: item_tree[func.visibility].clone(), |
53 | }) | 72 | }) |
54 | } | 73 | } |
@@ -70,7 +89,7 @@ impl TypeAliasData { | |||
70 | typ: TypeAliasId, | 89 | typ: TypeAliasId, |
71 | ) -> Arc<TypeAliasData> { | 90 | ) -> Arc<TypeAliasData> { |
72 | let loc = typ.lookup(db); | 91 | let loc = typ.lookup(db); |
73 | let item_tree = db.item_tree(loc.id.file_id); | 92 | let item_tree = loc.id.item_tree(db); |
74 | let typ = &item_tree[loc.id.value]; | 93 | let typ = &item_tree[loc.id.value]; |
75 | 94 | ||
76 | Arc::new(TypeAliasData { | 95 | Arc::new(TypeAliasData { |
@@ -96,23 +115,23 @@ pub struct TraitData { | |||
96 | impl TraitData { | 115 | impl TraitData { |
97 | pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> { | 116 | pub(crate) fn trait_data_query(db: &dyn DefDatabase, tr: TraitId) -> Arc<TraitData> { |
98 | let tr_loc = tr.lookup(db); | 117 | let tr_loc = tr.lookup(db); |
99 | let item_tree = db.item_tree(tr_loc.id.file_id); | 118 | let item_tree = tr_loc.id.item_tree(db); |
100 | let tr_def = &item_tree[tr_loc.id.value]; | 119 | let tr_def = &item_tree[tr_loc.id.value]; |
101 | let name = tr_def.name.clone(); | 120 | let name = tr_def.name.clone(); |
102 | let is_auto = tr_def.is_auto; | 121 | let is_auto = tr_def.is_auto; |
103 | let is_unsafe = tr_def.is_unsafe; | 122 | let is_unsafe = tr_def.is_unsafe; |
104 | let module_id = tr_loc.container; | 123 | let module_id = tr_loc.container; |
105 | let container = AssocContainerId::TraitId(tr); | 124 | let container = AssocContainerId::TraitId(tr); |
106 | let mut expander = Expander::new(db, tr_loc.id.file_id, module_id); | ||
107 | let visibility = item_tree[tr_def.visibility].clone(); | 125 | let visibility = item_tree[tr_def.visibility].clone(); |
108 | let bounds = tr_def.bounds.clone(); | 126 | let bounds = tr_def.bounds.clone(); |
127 | let mut expander = Expander::new(db, tr_loc.id.file_id(), module_id); | ||
109 | 128 | ||
110 | let items = collect_items( | 129 | let items = collect_items( |
111 | db, | 130 | db, |
112 | module_id, | 131 | module_id, |
113 | &mut expander, | 132 | &mut expander, |
114 | tr_def.items.iter().copied(), | 133 | tr_def.items.iter().copied(), |
115 | tr_loc.id.file_id, | 134 | tr_loc.id.file_id(), |
116 | container, | 135 | container, |
117 | 100, | 136 | 100, |
118 | ); | 137 | ); |
@@ -148,21 +167,21 @@ impl ImplData { | |||
148 | let _p = profile::span("impl_data_query"); | 167 | let _p = profile::span("impl_data_query"); |
149 | let impl_loc = id.lookup(db); | 168 | let impl_loc = id.lookup(db); |
150 | 169 | ||
151 | let item_tree = db.item_tree(impl_loc.id.file_id); | 170 | let item_tree = impl_loc.id.item_tree(db); |
152 | let impl_def = &item_tree[impl_loc.id.value]; | 171 | let impl_def = &item_tree[impl_loc.id.value]; |
153 | let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone()); | 172 | let target_trait = impl_def.target_trait.map(|id| item_tree[id].clone()); |
154 | let target_type = item_tree[impl_def.target_type].clone(); | 173 | let target_type = item_tree[impl_def.target_type].clone(); |
155 | let is_negative = impl_def.is_negative; | 174 | let is_negative = impl_def.is_negative; |
156 | let module_id = impl_loc.container; | 175 | let module_id = impl_loc.container; |
157 | let container = AssocContainerId::ImplId(id); | 176 | let container = AssocContainerId::ImplId(id); |
158 | let mut expander = Expander::new(db, impl_loc.id.file_id, module_id); | 177 | let mut expander = Expander::new(db, impl_loc.id.file_id(), module_id); |
159 | 178 | ||
160 | let items = collect_items( | 179 | let items = collect_items( |
161 | db, | 180 | db, |
162 | module_id, | 181 | module_id, |
163 | &mut expander, | 182 | &mut expander, |
164 | impl_def.items.iter().copied(), | 183 | impl_def.items.iter().copied(), |
165 | impl_loc.id.file_id, | 184 | impl_loc.id.file_id(), |
166 | container, | 185 | container, |
167 | 100, | 186 | 100, |
168 | ); | 187 | ); |
@@ -183,7 +202,7 @@ pub struct ConstData { | |||
183 | impl ConstData { | 202 | impl ConstData { |
184 | pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { | 203 | pub(crate) fn const_data_query(db: &dyn DefDatabase, konst: ConstId) -> Arc<ConstData> { |
185 | let loc = konst.lookup(db); | 204 | let loc = konst.lookup(db); |
186 | let item_tree = db.item_tree(loc.id.file_id); | 205 | let item_tree = loc.id.item_tree(db); |
187 | let konst = &item_tree[loc.id.value]; | 206 | let konst = &item_tree[loc.id.value]; |
188 | 207 | ||
189 | Arc::new(ConstData { | 208 | Arc::new(ConstData { |
@@ -206,7 +225,7 @@ pub struct StaticData { | |||
206 | impl StaticData { | 225 | impl StaticData { |
207 | pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { | 226 | pub(crate) fn static_data_query(db: &dyn DefDatabase, konst: StaticId) -> Arc<StaticData> { |
208 | let node = konst.lookup(db); | 227 | let node = konst.lookup(db); |
209 | let item_tree = db.item_tree(node.id.file_id); | 228 | let item_tree = node.id.item_tree(db); |
210 | let statik = &item_tree[node.id.value]; | 229 | let statik = &item_tree[node.id.value]; |
211 | 230 | ||
212 | Arc::new(StaticData { | 231 | Arc::new(StaticData { |
@@ -232,22 +251,23 @@ fn collect_items( | |||
232 | return Vec::new(); | 251 | return Vec::new(); |
233 | } | 252 | } |
234 | 253 | ||
235 | let item_tree = db.item_tree(file_id); | 254 | let item_tree = db.file_item_tree(file_id); |
236 | let cfg_options = db.crate_graph()[module.krate].cfg_options.clone(); | 255 | let crate_graph = db.crate_graph(); |
256 | let cfg_options = &crate_graph[module.krate].cfg_options; | ||
237 | 257 | ||
238 | let mut items = Vec::new(); | 258 | let mut items = Vec::new(); |
239 | for item in assoc_items { | 259 | for item in assoc_items { |
260 | let attrs = item_tree.attrs(db, module.krate, ModItem::from(item).into()); | ||
261 | if !attrs.is_cfg_enabled(cfg_options) { | ||
262 | continue; | ||
263 | } | ||
264 | |||
240 | match item { | 265 | match item { |
241 | AssocItem::Function(id) => { | 266 | AssocItem::Function(id) => { |
242 | let item = &item_tree[id]; | 267 | let item = &item_tree[id]; |
243 | let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into()); | ||
244 | if !attrs.is_cfg_enabled(&cfg_options) { | ||
245 | continue; | ||
246 | } | ||
247 | let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); | 268 | let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); |
248 | items.push((item.name.clone(), def.into())); | 269 | items.push((item.name.clone(), def.into())); |
249 | } | 270 | } |
250 | // FIXME: cfg? | ||
251 | AssocItem::Const(id) => { | 271 | AssocItem::Const(id) => { |
252 | let item = &item_tree[id]; | 272 | let item = &item_tree[id]; |
253 | let name = match item.name.clone() { | 273 | let name = match item.name.clone() { |
@@ -272,7 +292,7 @@ fn collect_items( | |||
272 | if let Ok(res) = res { | 292 | if let Ok(res) = res { |
273 | if let Some((mark, mac)) = res.value { | 293 | if let Some((mark, mac)) = res.value { |
274 | let src: InFile<ast::MacroItems> = expander.to_source(mac); | 294 | let src: InFile<ast::MacroItems> = expander.to_source(mac); |
275 | let item_tree = db.item_tree(src.file_id); | 295 | let item_tree = db.file_item_tree(src.file_id); |
276 | let iter = | 296 | let iter = |
277 | item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); | 297 | item_tree.top_level_items().iter().filter_map(ModItem::as_assoc_item); |
278 | items.extend(collect_items( | 298 | items.extend(collect_items( |