]> git.lizzy.rs Git - rust.git/blob - src/librustc/metadata/csearch.rs
core: Fix size_hint for signed integer Range<T> iterators
[rust.git] / src / librustc / metadata / csearch.rs
1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
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
11 // Searching for information from the cstore
12
13 use metadata::common::*;
14 use metadata::cstore;
15 use metadata::decoder;
16 use middle::def;
17 use middle::lang_items;
18 use middle::ty;
19
20 use rbml;
21 use rbml::reader;
22 use std::rc::Rc;
23 use syntax::ast;
24 use syntax::ast_map;
25 use syntax::attr;
26 use syntax::attr::AttrMetaMethods;
27 use syntax::diagnostic::expect;
28 use syntax::parse::token;
29
30 use std::collections::hash_map::HashMap;
31
32 #[derive(Copy, Clone)]
33 pub struct MethodInfo {
34     pub name: ast::Name,
35     pub def_id: ast::DefId,
36     pub vis: ast::Visibility,
37 }
38
39 pub fn get_symbol(cstore: &cstore::CStore, def: ast::DefId) -> String {
40     let cdata = cstore.get_crate_data(def.krate);
41     decoder::get_symbol(cdata.data(), def.node)
42 }
43
44 /// Iterates over all the language items in the given crate.
45 pub fn each_lang_item<F>(cstore: &cstore::CStore,
46                          cnum: ast::CrateNum,
47                          f: F)
48                          -> bool where
49     F: FnMut(ast::NodeId, usize) -> bool,
50 {
51     let crate_data = cstore.get_crate_data(cnum);
52     decoder::each_lang_item(&*crate_data, f)
53 }
54
55 /// Iterates over each child of the given item.
56 pub fn each_child_of_item<F>(cstore: &cstore::CStore,
57                              def_id: ast::DefId,
58                              callback: F) where
59     F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
60 {
61     let crate_data = cstore.get_crate_data(def_id.krate);
62     let get_crate_data = |cnum| {
63         cstore.get_crate_data(cnum)
64     };
65     decoder::each_child_of_item(cstore.intr.clone(),
66                                 &*crate_data,
67                                 def_id.node,
68                                 get_crate_data,
69                                 callback)
70 }
71
72 /// Iterates over each top-level crate item.
73 pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
74                                        cnum: ast::CrateNum,
75                                        callback: F) where
76     F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
77 {
78     let crate_data = cstore.get_crate_data(cnum);
79     let get_crate_data = |cnum| {
80         cstore.get_crate_data(cnum)
81     };
82     decoder::each_top_level_item_of_crate(cstore.intr.clone(),
83                                           &*crate_data,
84                                           get_crate_data,
85                                           callback)
86 }
87
88 pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem> {
89     let cstore = &tcx.sess.cstore;
90     let cdata = cstore.get_crate_data(def.krate);
91     let path = decoder::get_item_path(&*cdata, def.node);
92
93     // FIXME #1920: This path is not always correct if the crate is not linked
94     // into the root namespace.
95     let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))];
96     r.push_all(&path);
97     r
98 }
99
100 pub enum FoundAst<'ast> {
101     Found(&'ast ast::InlinedItem),
102     FoundParent(ast::DefId, &'ast ast::InlinedItem),
103     NotFound,
104 }
105
106 // Finds the AST for this item in the crate metadata, if any.  If the item was
107 // not marked for inlining, then the AST will not be present and hence none
108 // will be returned.
109 pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
110                                 decode_inlined_item: decoder::DecodeInlinedItem)
111                                 -> FoundAst<'tcx> {
112     let cstore = &tcx.sess.cstore;
113     let cdata = cstore.get_crate_data(def.krate);
114     decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item)
115 }
116
117 pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId)
118                              -> Vec<(def::Def, ast::Name, ast::Visibility)> {
119     let cdata = cstore.get_crate_data(enum_id.krate);
120     decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node)
121 }
122
123 pub fn get_enum_variants<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
124                                -> Vec<Rc<ty::VariantInfo<'tcx>>> {
125     let cstore = &tcx.sess.cstore;
126     let cdata = cstore.get_crate_data(def.krate);
127     decoder::get_enum_variants(cstore.intr.clone(), &*cdata, def.node, tcx)
128 }
129
130 /// Returns information about the given implementation.
131 pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: ast::DefId)
132                       -> Vec<ty::ImplOrTraitItemId> {
133     let cdata = cstore.get_crate_data(impl_def_id.krate);
134     decoder::get_impl_items(&*cdata, impl_def_id.node)
135 }
136
137 pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId)
138                                     -> ty::ImplOrTraitItem<'tcx> {
139     let cdata = tcx.sess.cstore.get_crate_data(def.krate);
140     decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
141                                     &*cdata,
142                                     def.node,
143                                     tcx)
144 }
145
146 pub fn get_trait_name(cstore: &cstore::CStore, def: ast::DefId) -> ast::Name {
147     let cdata = cstore.get_crate_data(def.krate);
148     decoder::get_trait_name(cstore.intr.clone(),
149                             &*cdata,
150                             def.node)
151 }
152
153 pub fn is_static_method(cstore: &cstore::CStore, def: ast::DefId) -> bool {
154     let cdata = cstore.get_crate_data(def.krate);
155     decoder::is_static_method(&*cdata, def.node)
156 }
157
158 pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: ast::DefId)
159                               -> Vec<ty::ImplOrTraitItemId> {
160     let cdata = cstore.get_crate_data(def.krate);
161     decoder::get_trait_item_def_ids(&*cdata, def.node)
162 }
163
164 pub fn get_item_variances(cstore: &cstore::CStore,
165                           def: ast::DefId) -> ty::ItemVariances {
166     let cdata = cstore.get_crate_data(def.krate);
167     decoder::get_item_variances(&*cdata, def.node)
168 }
169
170 pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
171                                         def: ast::DefId)
172                                         -> Vec<Rc<ty::Method<'tcx>>> {
173     let cstore = &tcx.sess.cstore;
174     let cdata = cstore.get_crate_data(def.krate);
175     decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.node, tcx)
176 }
177
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)
182 }
183
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)
189 }
190
191 pub fn get_item_attrs(cstore: &cstore::CStore,
192                       def_id: ast::DefId)
193                       -> Vec<ast::Attribute> {
194     let cdata = cstore.get_crate_data(def_id.krate);
195     decoder::get_item_attrs(&*cdata, def_id.node)
196 }
197
198 pub fn get_struct_fields(cstore: &cstore::CStore,
199                          def: ast::DefId)
200                       -> Vec<ty::field_ty> {
201     let cdata = cstore.get_crate_data(def.krate);
202     decoder::get_struct_fields(cstore.intr.clone(), &*cdata, def.node)
203 }
204
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)
209 }
210
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)
217 }
218
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)
223 }
224
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
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
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(),
247                            decoder::maybe_find_item(class_id.node, all_items),
248                            || {
249         (format!("get_field_type: class ID {:?} not found",
250                  class_id)).to_string()
251     });
252     let the_field = expect(tcx.sess.diagnostic(),
253         decoder::maybe_find_item(def.node, class_doc),
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,
263     }
264 }
265
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
275 // Given a def_id for an impl, return the trait it implements,
276 // if there is one.
277 pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
278                             def: ast::DefId)
279                             -> Option<Rc<ty::TraitRef<'tcx>>> {
280     let cstore = &tcx.sess.cstore;
281     let cdata = cstore.get_crate_data(def.krate);
282     decoder::get_impl_trait(&*cdata, def.node, tcx)
283 }
284
285 // Given a def_id for an impl, return information about its vtables
286 pub fn get_impl_vtables<'tcx>(tcx: &ty::ctxt<'tcx>,
287                               def: ast::DefId)
288                               -> ty::vtable_res<'tcx> {
289     let cstore = &tcx.sess.cstore;
290     let cdata = cstore.get_crate_data(def.krate);
291     decoder::get_impl_vtables(&*cdata, def.node, tcx)
292 }
293
294 pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
295                             -> Vec<(cstore::NativeLibraryKind, String)> {
296     let cdata = cstore.get_crate_data(crate_num);
297     decoder::get_native_libraries(&*cdata)
298 }
299
300 pub fn each_impl<F>(cstore: &cstore::CStore,
301                     crate_num: ast::CrateNum,
302                     callback: F) where
303     F: FnMut(ast::DefId),
304 {
305     let cdata = cstore.get_crate_data(crate_num);
306     decoder::each_impl(&*cdata, callback)
307 }
308
309 pub fn each_implementation_for_type<F>(cstore: &cstore::CStore,
310                                        def_id: ast::DefId,
311                                        callback: F) where
312     F: FnMut(ast::DefId),
313 {
314     let cdata = cstore.get_crate_data(def_id.krate);
315     decoder::each_implementation_for_type(&*cdata, def_id.node, callback)
316 }
317
318 pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
319                                         def_id: ast::DefId,
320                                         callback: F) where
321     F: FnMut(ast::DefId),
322 {
323     let cdata = cstore.get_crate_data(def_id.krate);
324     decoder::each_implementation_for_trait(&*cdata, def_id.node, callback)
325 }
326
327 /// If the given def ID describes an item belonging to a trait (either a
328 /// default method or an implementation of a trait method), returns the ID of
329 /// the trait that the method belongs to. Otherwise, returns `None`.
330 pub fn get_trait_of_item(cstore: &cstore::CStore,
331                          def_id: ast::DefId,
332                          tcx: &ty::ctxt)
333                          -> Option<ast::DefId> {
334     let cdata = cstore.get_crate_data(def_id.krate);
335     decoder::get_trait_of_item(&*cdata, def_id.node, tcx)
336 }
337
338 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
339                                            def_id: ast::DefId)
340     -> Option<ast::DefId>
341 {
342     let cdata = cstore.get_crate_data(def_id.krate);
343     decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.node)
344 }
345
346 pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
347                                     cnum: ast::CrateNum)
348     -> Vec<(ast::CrateNum, cstore::LinkagePreference)>
349 {
350     let cdata = cstore.get_crate_data(cnum);
351     decoder::get_dylib_dependency_formats(&*cdata)
352 }
353
354 pub fn get_missing_lang_items(cstore: &cstore::CStore, cnum: ast::CrateNum)
355     -> Vec<lang_items::LangItem>
356 {
357     let cdata = cstore.get_crate_data(cnum);
358     decoder::get_missing_lang_items(&*cdata)
359 }
360
361 pub fn get_method_arg_names(cstore: &cstore::CStore, did: ast::DefId)
362     -> Vec<String>
363 {
364     let cdata = cstore.get_crate_data(did.krate);
365     decoder::get_method_arg_names(&*cdata, did.node)
366 }
367
368 pub fn get_reachable_extern_fns(cstore: &cstore::CStore, cnum: ast::CrateNum)
369     -> Vec<ast::DefId>
370 {
371     let cdata = cstore.get_crate_data(cnum);
372     decoder::get_reachable_extern_fns(&*cdata)
373 }
374
375 pub fn is_typedef(cstore: &cstore::CStore, did: ast::DefId) -> bool {
376     let cdata = cstore.get_crate_data(did.krate);
377     decoder::is_typedef(&*cdata, did.node)
378 }
379
380 pub fn get_stability(cstore: &cstore::CStore,
381                      def: ast::DefId)
382                      -> Option<attr::Stability> {
383     let cdata = cstore.get_crate_data(def.krate);
384     decoder::get_stability(&*cdata, def.node)
385 }
386
387 pub fn is_staged_api(cstore: &cstore::CStore, def: ast::DefId) -> bool {
388     let cdata = cstore.get_crate_data(def.krate);
389     let attrs = decoder::get_crate_attributes(cdata.data());
390     for attr in &attrs {
391         if &attr.name()[..] == "staged_api" {
392             match attr.node.value.node { ast::MetaWord(_) => return true, _ => (/*pass*/) }
393         }
394     }
395
396     return false;
397 }
398
399 pub fn get_repr_attrs(cstore: &cstore::CStore, def: ast::DefId)
400                       -> Vec<attr::ReprAttr> {
401     let cdata = cstore.get_crate_data(def.krate);
402     decoder::get_repr_attrs(&*cdata, def.node)
403 }
404
405 pub fn is_associated_type(cstore: &cstore::CStore, def: ast::DefId) -> bool {
406     let cdata = cstore.get_crate_data(def.krate);
407     decoder::is_associated_type(&*cdata, def.node)
408 }
409
410 pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: ast::DefId) -> bool {
411     let cdata = cstore.get_crate_data(trait_def_id.krate);
412     decoder::is_defaulted_trait(&*cdata, trait_def_id.node)
413 }
414
415 pub fn is_default_impl(cstore: &cstore::CStore, impl_did: ast::DefId) -> bool {
416     let cdata = cstore.get_crate_data(impl_did.krate);
417     decoder::is_default_impl(&*cdata, impl_did.node)
418 }