]>
Commit | Line | Data |
---|---|---|
1a4d82fc | 1 | // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT |
223e47cc LB |
2 | // file at the top-level directory of this distribution and at |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
223e47cc LB |
11 | // Searching for information from the cstore |
12 | ||
62682a34 | 13 | use ast_map; |
223e47cc LB |
14 | use metadata::common::*; |
15 | use metadata::cstore; | |
16 | use metadata::decoder; | |
1a4d82fc JJ |
17 | use middle::lang_items; |
18 | use middle::ty; | |
223e47cc | 19 | |
1a4d82fc JJ |
20 | use rbml; |
21 | use rbml::reader; | |
22 | use std::rc::Rc; | |
223e47cc | 23 | use syntax::ast; |
1a4d82fc JJ |
24 | use syntax::attr; |
25 | use syntax::attr::AttrMetaMethods; | |
223e47cc | 26 | use syntax::diagnostic::expect; |
1a4d82fc | 27 | use syntax::parse::token; |
223e47cc | 28 | |
1a4d82fc | 29 | use std::collections::hash_map::HashMap; |
223e47cc | 30 | |
c34b1796 | 31 | #[derive(Copy, Clone)] |
1a4d82fc JJ |
32 | pub struct MethodInfo { |
33 | pub name: ast::Name, | |
34 | pub def_id: ast::DefId, | |
35 | pub vis: ast::Visibility, | |
223e47cc LB |
36 | } |
37 | ||
1a4d82fc JJ |
38 | pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String { |
39 | let cdata = cstore.get_crate_data(def.krate); | |
40 | decoder::get_symbol(cdata.data(), def.node) | |
223e47cc LB |
41 | } |
42 | ||
43 | /// Iterates over all the language items in the given crate. | |
1a4d82fc JJ |
44 | pub fn each_lang_item<F>(cstore: &cstore::CStore, |
45 | cnum: ast::CrateNum, | |
46 | f: F) | |
47 | -> bool where | |
c34b1796 | 48 | F: FnMut(ast::NodeId, usize) -> bool, |
1a4d82fc JJ |
49 | { |
50 | let crate_data = cstore.get_crate_data(cnum); | |
51 | decoder::each_lang_item(&*crate_data, f) | |
52 | } | |
53 | ||
54 | /// Iterates over each child of the given item. | |
55 | pub fn each_child_of_item<F>(cstore: &cstore::CStore, | |
56 | def_id: ast::DefId, | |
57 | callback: F) where | |
58 | F: FnMut(decoder::DefLike, ast::Name, ast::Visibility), | |
59 | { | |
60 | let crate_data = cstore.get_crate_data(def_id.krate); | |
85aaf69f | 61 | let get_crate_data = |cnum| { |
1a4d82fc JJ |
62 | cstore.get_crate_data(cnum) |
63 | }; | |
64 | decoder::each_child_of_item(cstore.intr.clone(), | |
65 | &*crate_data, | |
66 | def_id.node, | |
67 | get_crate_data, | |
68 | callback) | |
69 | } | |
70 | ||
71 | /// Iterates over each top-level crate item. | |
72 | pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore, | |
73 | cnum: ast::CrateNum, | |
74 | callback: F) where | |
75 | F: FnMut(decoder::DefLike, ast::Name, ast::Visibility), | |
76 | { | |
77 | let crate_data = cstore.get_crate_data(cnum); | |
85aaf69f | 78 | let get_crate_data = |cnum| { |
1a4d82fc | 79 | cstore.get_crate_data(cnum) |
223e47cc | 80 | }; |
1a4d82fc JJ |
81 | decoder::each_top_level_item_of_crate(cstore.intr.clone(), |
82 | &*crate_data, | |
83 | get_crate_data, | |
84 | callback) | |
223e47cc LB |
85 | } |
86 | ||
1a4d82fc JJ |
87 | pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem> { |
88 | let cstore = &tcx.sess.cstore; | |
89 | let cdata = cstore.get_crate_data(def.krate); | |
90 | let path = decoder::get_item_path(&*cdata, def.node); | |
223e47cc LB |
91 | |
92 | // FIXME #1920: This path is not always correct if the crate is not linked | |
93 | // into the root namespace. | |
c34b1796 | 94 | let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))]; |
85aaf69f | 95 | r.push_all(&path); |
1a4d82fc | 96 | r |
223e47cc LB |
97 | } |
98 | ||
85aaf69f SL |
99 | pub enum FoundAst<'ast> { |
100 | Found(&'ast ast::InlinedItem), | |
101 | FoundParent(ast::DefId, &'ast ast::InlinedItem), | |
102 | NotFound, | |
223e47cc LB |
103 | } |
104 | ||
105 | // Finds the AST for this item in the crate metadata, if any. If the item was | |
106 | // not marked for inlining, then the AST will not be present and hence none | |
107 | // will be returned. | |
1a4d82fc JJ |
108 | pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId, |
109 | decode_inlined_item: decoder::DecodeInlinedItem) | |
85aaf69f | 110 | -> FoundAst<'tcx> { |
1a4d82fc JJ |
111 | let cstore = &tcx.sess.cstore; |
112 | let cdata = cstore.get_crate_data(def.krate); | |
113 | decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item) | |
223e47cc LB |
114 | } |
115 | ||
1a4d82fc JJ |
116 | pub fn get_enum_variants<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) |
117 | -> Vec<Rc<ty::VariantInfo<'tcx>>> { | |
118 | let cstore = &tcx.sess.cstore; | |
119 | let cdata = cstore.get_crate_data(def.krate); | |
120 | decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx) | |
223e47cc LB |
121 | } |
122 | ||
970d7e83 | 123 | /// Returns information about the given implementation. |
1a4d82fc JJ |
124 | pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId) |
125 | -> Vec<ty::ImplOrTraitItemId> { | |
126 | let cdata = cstore.get_crate_data(impl_def_id.krate); | |
127 | decoder::get_impl_items(&*cdata, impl_def_id.node) | |
970d7e83 LB |
128 | } |
129 | ||
1a4d82fc JJ |
130 | pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) |
131 | -> ty::ImplOrTraitItem<'tcx> { | |
132 | let cdata = tcx.sess.cstore.get_crate_data(def.krate); | |
133 | decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(), | |
134 | &*cdata, | |
135 | def.node, | |
136 | tcx) | |
970d7e83 LB |
137 | } |
138 | ||
1a4d82fc JJ |
139 | pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId) -> ast::Name { |
140 | let cdata = cstore.get_crate_data(def.krate); | |
141 | decoder::get_trait_name(cstore.intr.clone(), | |
142 | &*cdata, | |
143 | def.node) | |
144 | } | |
145 | ||
c34b1796 | 146 | pub fn is_static_method(cstore: &cstore::CStore, def: ast::DefId) -> bool { |
1a4d82fc | 147 | let cdata = cstore.get_crate_data(def.krate); |
c34b1796 | 148 | decoder::is_static_method(&*cdata, def.node) |
1a4d82fc JJ |
149 | } |
150 | ||
151 | pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId) | |
152 | -> Vec<ty::ImplOrTraitItemId> { | |
153 | let cdata = cstore.get_crate_data(def.krate); | |
154 | decoder::get_trait_item_def_ids(&*cdata, def.node) | |
223e47cc LB |
155 | } |
156 | ||
1a4d82fc JJ |
157 | pub fn get_item_variances(cstore: &cstore::CStore, |
158 | def: ast::DefId) -> ty::ItemVariances { | |
159 | let cdata = cstore.get_crate_data(def.krate); | |
160 | decoder::get_item_variances(&*cdata, def.node) | |
223e47cc LB |
161 | } |
162 | ||
1a4d82fc JJ |
163 | pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>, |
164 | def: ast::DefId) | |
165 | -> Vec<Rc<ty::Method<'tcx>>> { | |
166 | let cstore = &tcx.sess.cstore; | |
167 | let cdata = cstore.get_crate_data(def.krate); | |
168 | decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx) | |
223e47cc LB |
169 | } |
170 | ||
d9579d0f AL |
171 | pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) |
172 | -> Vec<Rc<ty::AssociatedConst<'tcx>>> { | |
173 | let cstore = &tcx.sess.cstore; | |
174 | let cdata = cstore.get_crate_data(def.krate); | |
175 | decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.node, tcx) | |
176 | } | |
177 | ||
1a4d82fc JJ |
178 | pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: ast::DefId) |
179 | -> Option<ast::Name> { | |
180 | let cdata = cstore.get_crate_data(def.krate); | |
181 | decoder::get_type_name_if_impl(&*cdata, def.node) | |
223e47cc LB |
182 | } |
183 | ||
1a4d82fc JJ |
184 | pub fn get_methods_if_impl(cstore: &cstore::CStore, |
185 | def: ast::DefId) | |
186 | -> Option<Vec<MethodInfo> > { | |
187 | let cdata = cstore.get_crate_data(def.krate); | |
188 | decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.node) | |
223e47cc LB |
189 | } |
190 | ||
85aaf69f SL |
191 | pub fn get_item_attrs(cstore: &cstore::CStore, |
192 | def_id: ast::DefId) | |
193 | -> Vec<ast::Attribute> { | |
1a4d82fc | 194 | let cdata = cstore.get_crate_data(def_id.krate); |
85aaf69f | 195 | decoder::get_item_attrs(&*cdata, def_id.node) |
223e47cc LB |
196 | } |
197 | ||
1a4d82fc JJ |
198 | pub fn get_struct_fields(cstore: &cstore::CStore, |
199 | def: ast::DefId) | |
c1a9b12d | 200 | -> Vec<ty::FieldTy> { |
1a4d82fc JJ |
201 | let cdata = cstore.get_crate_data(def.krate); |
202 | decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node) | |
223e47cc LB |
203 | } |
204 | ||
1a4d82fc JJ |
205 | pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: ast::DefId) -> HashMap<ast::NodeId, |
206 | Vec<ast::Attribute>> { | |
207 | let cdata = cstore.get_crate_data(def.krate); | |
208 | decoder::get_struct_field_attrs(&*cdata) | |
223e47cc LB |
209 | } |
210 | ||
1a4d82fc JJ |
211 | pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>, |
212 | def: ast::DefId) | |
213 | -> ty::TypeScheme<'tcx> { | |
214 | let cstore = &tcx.sess.cstore; | |
215 | let cdata = cstore.get_crate_data(def.krate); | |
216 | decoder::get_type(&*cdata, def.node, tcx) | |
970d7e83 LB |
217 | } |
218 | ||
1a4d82fc JJ |
219 | pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) -> ty::TraitDef<'tcx> { |
220 | let cstore = &tcx.sess.cstore; | |
221 | let cdata = cstore.get_crate_data(def.krate); | |
222 | decoder::get_trait_def(&*cdata, def.node, tcx) | |
223e47cc LB |
223 | } |
224 | ||
85aaf69f SL |
225 | pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) |
226 | -> ty::GenericPredicates<'tcx> | |
227 | { | |
228 | let cstore = &tcx.sess.cstore; | |
229 | let cdata = cstore.get_crate_data(def.krate); | |
230 | decoder::get_predicates(&*cdata, def.node, tcx) | |
231 | } | |
232 | ||
c34b1796 AL |
233 | pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId) |
234 | -> ty::GenericPredicates<'tcx> | |
235 | { | |
236 | let cstore = &tcx.sess.cstore; | |
237 | let cdata = cstore.get_crate_data(def.krate); | |
238 | decoder::get_super_predicates(&*cdata, def.node, tcx) | |
239 | } | |
240 | ||
1a4d82fc JJ |
241 | pub fn get_field_type<'tcx>(tcx: &ty::ctxt<'tcx>, class_id: ast::DefId, |
242 | def: ast::DefId) -> ty::TypeScheme<'tcx> { | |
243 | let cstore = &tcx.sess.cstore; | |
244 | let cdata = cstore.get_crate_data(class_id.krate); | |
245 | let all_items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_items); | |
246 | let class_doc = expect(tcx.sess.diagnostic(), | |
223e47cc | 247 | decoder::maybe_find_item(class_id.node, all_items), |
1a4d82fc JJ |
248 | || { |
249 | (format!("get_field_type: class ID {:?} not found", | |
250 | class_id)).to_string() | |
251 | }); | |
252 | let the_field = expect(tcx.sess.diagnostic(), | |
223e47cc | 253 | decoder::maybe_find_item(def.node, class_doc), |
1a4d82fc JJ |
254 | || { |
255 | (format!("get_field_type: in class {:?}, field ID {:?} not found", | |
256 | class_id, | |
257 | def)).to_string() | |
258 | }); | |
259 | let ty = decoder::item_type(def, the_field, tcx, &*cdata); | |
260 | ty::TypeScheme { | |
261 | generics: ty::Generics::empty(), | |
262 | ty: ty, | |
223e47cc LB |
263 | } |
264 | } | |
265 | ||
85aaf69f SL |
266 | pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>, |
267 | def: ast::DefId) | |
268 | -> Option<ast::ImplPolarity> | |
269 | { | |
270 | let cstore = &tcx.sess.cstore; | |
271 | let cdata = cstore.get_crate_data(def.krate); | |
272 | decoder::get_impl_polarity(&*cdata, def.node) | |
273 | } | |
274 | ||
d9579d0f AL |
275 | pub fn get_custom_coerce_unsized_kind<'tcx>(tcx: &ty::ctxt<'tcx>, |
276 | def: ast::DefId) | |
277 | -> Option<ty::CustomCoerceUnsized> { | |
278 | let cstore = &tcx.sess.cstore; | |
279 | let cdata = cstore.get_crate_data(def.krate); | |
280 | decoder::get_custom_coerce_unsized_kind(&*cdata, def.node) | |
281 | } | |
282 | ||
970d7e83 LB |
283 | // Given a def_id for an impl, return the trait it implements, |
284 | // if there is one. | |
1a4d82fc JJ |
285 | pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>, |
286 | def: ast::DefId) | |
d9579d0f | 287 | -> Option<ty::TraitRef<'tcx>> { |
1a4d82fc JJ |
288 | let cstore = &tcx.sess.cstore; |
289 | let cdata = cstore.get_crate_data(def.krate); | |
290 | decoder::get_impl_trait(&*cdata, def.node, tcx) | |
291 | } | |
292 | ||
1a4d82fc JJ |
293 | pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum) |
294 | -> Vec<(cstore::NativeLibraryKind, String)> { | |
295 | let cdata = cstore.get_crate_data(crate_num); | |
296 | decoder::get_native_libraries(&*cdata) | |
223e47cc LB |
297 | } |
298 | ||
d9579d0f AL |
299 | pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore, |
300 | def_id: ast::DefId, | |
301 | callback: F) where | |
1a4d82fc JJ |
302 | F: FnMut(ast::DefId), |
303 | { | |
304 | let cdata = cstore.get_crate_data(def_id.krate); | |
d9579d0f | 305 | decoder::each_inherent_implementation_for_type(&*cdata, def_id.node, callback) |
223e47cc LB |
306 | } |
307 | ||
1a4d82fc JJ |
308 | pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore, |
309 | def_id: ast::DefId, | |
d9579d0f | 310 | mut callback: F) where |
1a4d82fc JJ |
311 | F: FnMut(ast::DefId), |
312 | { | |
d9579d0f AL |
313 | cstore.iter_crate_data(|_, cdata| { |
314 | decoder::each_implementation_for_trait(cdata, def_id, &mut callback) | |
315 | }) | |
223e47cc | 316 | } |
1a4d82fc JJ |
317 | |
318 | /// If the given def ID describes an item belonging to a trait (either a | |
319 | /// default method or an implementation of a trait method), returns the ID of | |
320 | /// the trait that the method belongs to. Otherwise, returns `None`. | |
321 | pub fn get_trait_of_item(cstore: &cstore::CStore, | |
322 | def_id: ast::DefId, | |
323 | tcx: &ty::ctxt) | |
324 | -> Option<ast::DefId> { | |
325 | let cdata = cstore.get_crate_data(def_id.krate); | |
326 | decoder::get_trait_of_item(&*cdata, def_id.node, tcx) | |
327 | } | |
328 | ||
329 | pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore, | |
330 | def_id: ast::DefId) | |
331 | -> Option<ast::DefId> | |
332 | { | |
333 | let cdata = cstore.get_crate_data(def_id.krate); | |
334 | decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.node) | |
335 | } | |
336 | ||
337 | pub fn get_dylib_dependency_formats(cstore: &cstore::CStore, | |
338 | cnum: ast::CrateNum) | |
339 | -> Vec<(ast::CrateNum, cstore::LinkagePreference)> | |
340 | { | |
341 | let cdata = cstore.get_crate_data(cnum); | |
342 | decoder::get_dylib_dependency_formats(&*cdata) | |
343 | } | |
344 | ||
345 | pub fn get_missing_lang_items(cstore: &cstore::CStore, cnum: ast::CrateNum) | |
346 | -> Vec<lang_items::LangItem> | |
347 | { | |
348 | let cdata = cstore.get_crate_data(cnum); | |
349 | decoder::get_missing_lang_items(&*cdata) | |
350 | } | |
351 | ||
352 | pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId) | |
353 | -> Vec<String> | |
354 | { | |
355 | let cdata = cstore.get_crate_data(did.krate); | |
356 | decoder::get_method_arg_names(&*cdata, did.node) | |
357 | } | |
358 | ||
359 | pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum) | |
360 | -> Vec<ast::DefId> | |
361 | { | |
362 | let cdata = cstore.get_crate_data(cnum); | |
363 | decoder::get_reachable_extern_fns(&*cdata) | |
364 | } | |
365 | ||
366 | pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool { | |
367 | let cdata = cstore.get_crate_data(did.krate); | |
368 | decoder::is_typedef(&*cdata, did.node) | |
369 | } | |
370 | ||
62682a34 SL |
371 | pub fn is_const_fn(cstore: &cstore::CStore, did: ast::DefId) -> bool { |
372 | let cdata = cstore.get_crate_data(did.krate); | |
373 | decoder::is_const_fn(&*cdata, did.node) | |
374 | } | |
375 | ||
376 | pub fn is_impl(cstore: &cstore::CStore, did: ast::DefId) -> bool { | |
377 | let cdata = cstore.get_crate_data(did.krate); | |
378 | decoder::is_impl(&*cdata, did.node) | |
379 | } | |
380 | ||
1a4d82fc JJ |
381 | pub fn get_stability(cstore: &cstore::CStore, |
382 | def: ast::DefId) | |
383 | -> Option<attr::Stability> { | |
384 | let cdata = cstore.get_crate_data(def.krate); | |
385 | decoder::get_stability(&*cdata, def.node) | |
386 | } | |
387 | ||
62682a34 SL |
388 | pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool { |
389 | let cdata = cstore.get_crate_data(krate); | |
1a4d82fc | 390 | let attrs = decoder::get_crate_attributes(cdata.data()); |
85aaf69f | 391 | for attr in &attrs { |
c34b1796 | 392 | if &attr.name()[..] == "staged_api" { |
1a4d82fc JJ |
393 | match attr.node.value.node { ast::MetaWord(_) => return true, _ => (/*pass*/) } |
394 | } | |
395 | } | |
396 | ||
397 | return false; | |
398 | } | |
399 | ||
400 | pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId) | |
401 | -> Vec<attr::ReprAttr> { | |
402 | let cdata = cstore.get_crate_data(def.krate); | |
403 | decoder::get_repr_attrs(&*cdata, def.node) | |
404 | } | |
405 | ||
c34b1796 AL |
406 | pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) -> bool { |
407 | let cdata = cstore.get_crate_data(trait_def_id.krate); | |
408 | decoder::is_defaulted_trait(&*cdata, trait_def_id.node) | |
409 | } | |
410 | ||
411 | pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool { | |
412 | let cdata = cstore.get_crate_data(impl_did.krate); | |
413 | decoder::is_default_impl(&*cdata, impl_did.node) | |
414 | } |