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.
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.
11 // Decoding metadata from a single crate's metadata
13 #![allow(non_camel_case_types)]
15 pub use self::DefLike
::*;
20 use metadata
::cstore
::crate_metadata
;
21 use metadata
::common
::*;
22 use metadata
::csearch
::MethodInfo
;
23 use metadata
::csearch
;
25 use metadata
::encoder
::def_to_u64
;
26 use metadata
::tydecode
::{parse_ty_data
, parse_region_data
,
27 parse_type_param_def_data
, parse_bare_fn_ty_data
,
28 parse_trait_ref_data
, parse_predicate_data
};
30 use middle
::lang_items
;
32 use middle
::ty
::{ImplContainer, TraitContainer}
;
33 use middle
::ty
::{self, Ty}
;
34 use util
::nodemap
::FnvHashMap
;
36 use std
::cell
::{Cell, RefCell}
;
37 use std
::collections
::HashMap
;
38 use std
::hash
::{Hash, SipHasher, Hasher}
;
39 use std
::io
::prelude
::*;
42 use std
::slice
::bytes
;
47 use serialize
::Decodable
;
49 use syntax
::parse
::token
::{IdentInterner, special_idents}
;
50 use syntax
::parse
::token
;
51 use syntax
::print
::pprust
;
56 pub type Cmd
<'a
> = &'a crate_metadata
;
58 // A function that takes a def_id relative to the crate being searched and
59 // returns a def_id relative to the compilation environment, i.e. if we hit a
60 // def_id for an item defined in another crate, somebody needs to figure out
61 // what crate that's in and give us a def_id that makes sense for the current
64 fn u32_from_be_bytes(bytes
: &[u8]) -> u32 {
66 bytes
::copy_memory(&bytes
[..4], &mut b
);
67 unsafe { (*(b.as_ptr() as *const u32)).to_be() }
70 fn lookup_hash
<'a
, F
>(d
: rbml
::Doc
<'a
>, mut eq_fn
: F
, hash
: u64) -> Option
<rbml
::Doc
<'a
>> where
71 F
: FnMut(&[u8]) -> bool
,
73 let index
= reader
::get_doc(d
, tag_index
);
74 let table
= reader
::get_doc(index
, tag_index_table
);
75 let hash_pos
= table
.start
+ (hash
% 256 * 4) as usize;
76 let pos
= u32_from_be_bytes(&d
.data
[hash_pos
..]) as usize;
77 let tagged_doc
= reader
::doc_at(d
.data
, pos
).unwrap();
79 reader
::tagged_docs(tagged_doc
.doc
, tag_index_buckets_bucket_elt
).find(|elt
| {
80 eq_fn(&elt
.data
[elt
.start
+ 4 .. elt
.end
])
82 let pos
= u32_from_be_bytes(&elt
.data
[elt
.start
..]) as usize;
83 reader
::doc_at(d
.data
, pos
).unwrap().doc
87 pub fn maybe_find_item
<'a
>(item_id
: ast
::NodeId
,
88 items
: rbml
::Doc
<'a
>) -> Option
<rbml
::Doc
<'a
>> {
89 fn eq_item(bytes
: &[u8], item_id
: ast
::NodeId
) -> bool
{
90 u32_from_be_bytes(bytes
) == item_id
92 let mut s
= SipHasher
::new_with_keys(0, 0);
93 (item_id
as i64).hash(&mut s
);
94 lookup_hash(items
, |a
| eq_item(a
, item_id
), s
.finish())
97 fn find_item
<'a
>(item_id
: ast
::NodeId
, items
: rbml
::Doc
<'a
>) -> rbml
::Doc
<'a
> {
98 match maybe_find_item(item_id
, items
) {
99 None
=> panic
!("lookup_item: id not found: {}", item_id
),
104 // Looks up an item in the given metadata and returns an rbml doc pointing
106 fn lookup_item
<'a
>(item_id
: ast
::NodeId
, data
: &'a
[u8]) -> rbml
::Doc
<'a
> {
107 let items
= reader
::get_doc(rbml
::Doc
::new(data
), tag_items
);
108 find_item(item_id
, items
)
134 fn item_family(item
: rbml
::Doc
) -> Family
{
135 let fam
= reader
::get_doc(item
, tag_items_data_item_family
);
136 match reader
::doc_as_u8(fam
) as char {
149 'V'
=> StructVariant
,
155 'N'
=> InheritedField
,
156 c
=> panic
!("unexpected family char: {}", c
)
160 fn item_visibility(item
: rbml
::Doc
) -> ast
::Visibility
{
161 match reader
::maybe_get_doc(item
, tag_items_data_item_visibility
) {
163 Some(visibility_doc
) => {
164 match reader
::doc_as_u8(visibility_doc
) as char {
166 'i'
=> ast
::Inherited
,
167 _
=> panic
!("unknown visibility character")
173 fn fn_constness(item
: rbml
::Doc
) -> ast
::Constness
{
174 match reader
::maybe_get_doc(item
, tag_items_data_item_constness
) {
175 None
=> ast
::Constness
::NotConst
,
176 Some(constness_doc
) => {
177 match reader
::doc_as_u8(constness_doc
) as char {
178 'c'
=> ast
::Constness
::Const
,
179 'n'
=> ast
::Constness
::NotConst
,
180 _
=> panic
!("unknown constness character")
186 fn item_sort(item
: rbml
::Doc
) -> Option
<char> {
187 reader
::tagged_docs(item
, tag_item_trait_item_sort
).nth(0).map(|doc
| {
188 doc
.as_str_slice().as_bytes()[0] as char
192 fn item_symbol(item
: rbml
::Doc
) -> String
{
193 reader
::get_doc(item
, tag_items_data_item_symbol
).as_str().to_string()
196 fn translated_def_id(cdata
: Cmd
, d
: rbml
::Doc
) -> ast
::DefId
{
197 let id
= reader
::doc_as_u64(d
);
198 let def_id
= ast
::DefId { krate: (id >> 32) as u32, node: id as u32 }
;
199 translate_def_id(cdata
, def_id
)
202 fn item_parent_item(cdata
: Cmd
, d
: rbml
::Doc
) -> Option
<ast
::DefId
> {
203 reader
::tagged_docs(d
, tag_items_data_parent_item
).nth(0).map(|did
| {
204 translated_def_id(cdata
, did
)
208 fn item_require_parent_item(cdata
: Cmd
, d
: rbml
::Doc
) -> ast
::DefId
{
209 translated_def_id(cdata
, reader
::get_doc(d
, tag_items_data_parent_item
))
212 fn item_def_id(d
: rbml
::Doc
, cdata
: Cmd
) -> ast
::DefId
{
213 translated_def_id(cdata
, reader
::get_doc(d
, tag_def_id
))
216 fn get_provided_source(d
: rbml
::Doc
, cdata
: Cmd
) -> Option
<ast
::DefId
> {
217 reader
::maybe_get_doc(d
, tag_item_method_provided_source
).map(|doc
| {
218 translated_def_id(cdata
, doc
)
222 fn reexports
<'a
>(d
: rbml
::Doc
<'a
>) -> reader
::TaggedDocsIterator
<'a
> {
223 reader
::tagged_docs(d
, tag_items_data_item_reexport
)
226 fn variant_disr_val(d
: rbml
::Doc
) -> Option
<ty
::Disr
> {
227 reader
::maybe_get_doc(d
, tag_disr_val
).and_then(|val_doc
| {
228 reader
::with_doc_data(val_doc
, |data
| {
229 str::from_utf8(data
).ok().and_then(|s
| s
.parse().ok())
234 fn doc_type
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Ty
<'tcx
> {
235 let tp
= reader
::get_doc(doc
, tag_items_data_item_type
);
236 parse_ty_data(tp
.data
, cdata
.cnum
, tp
.start
, tcx
,
237 |_
, did
| translate_def_id(cdata
, did
))
240 fn maybe_doc_type
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Option
<Ty
<'tcx
>> {
241 reader
::maybe_get_doc(doc
, tag_items_data_item_type
).map(|tp
| {
242 parse_ty_data(tp
.data
, cdata
.cnum
, tp
.start
, tcx
,
243 |_
, did
| translate_def_id(cdata
, did
))
247 fn doc_method_fty
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>,
248 cdata
: Cmd
) -> ty
::BareFnTy
<'tcx
> {
249 let tp
= reader
::get_doc(doc
, tag_item_method_fty
);
250 parse_bare_fn_ty_data(tp
.data
, cdata
.cnum
, tp
.start
, tcx
,
251 |_
, did
| translate_def_id(cdata
, did
))
254 pub fn item_type
<'tcx
>(_item_id
: ast
::DefId
, item
: rbml
::Doc
,
255 tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
) -> Ty
<'tcx
> {
256 doc_type(item
, tcx
, cdata
)
259 fn doc_trait_ref
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
)
260 -> ty
::TraitRef
<'tcx
> {
261 parse_trait_ref_data(doc
.data
, cdata
.cnum
, doc
.start
, tcx
,
262 |_
, did
| translate_def_id(cdata
, did
))
265 fn item_trait_ref
<'tcx
>(doc
: rbml
::Doc
, tcx
: &ty
::ctxt
<'tcx
>, cdata
: Cmd
)
266 -> ty
::TraitRef
<'tcx
> {
267 let tp
= reader
::get_doc(doc
, tag_item_trait_ref
);
268 doc_trait_ref(tp
, tcx
, cdata
)
271 fn item_path(item_doc
: rbml
::Doc
) -> Vec
<ast_map
::PathElem
> {
272 let path_doc
= reader
::get_doc(item_doc
, tag_path
);
273 reader
::docs(path_doc
).filter_map(|(tag
, elt_doc
)| {
274 if tag
== tag_path_elem_mod
{
275 let s
= elt_doc
.as_str_slice();
276 Some(ast_map
::PathMod(token
::intern(s
)))
277 } else if tag
== tag_path_elem_name
{
278 let s
= elt_doc
.as_str_slice();
279 Some(ast_map
::PathName(token
::intern(s
)))
281 // ignore tag_path_len element
287 fn item_name(intr
: &IdentInterner
, item
: rbml
::Doc
) -> ast
::Name
{
288 let name
= reader
::get_doc(item
, tag_paths_data_name
);
289 let string
= name
.as_str_slice();
290 match intr
.find(string
) {
291 None
=> token
::intern(string
),
296 fn item_to_def_like(cdata
: Cmd
, item
: rbml
::Doc
, did
: ast
::DefId
) -> DefLike
{
297 let fam
= item_family(item
);
300 // Check whether we have an associated const item.
301 if item_sort(item
) == Some('C'
) {
302 DlDef(def
::DefAssociatedConst(did
))
304 // Regular const item.
305 DlDef(def
::DefConst(did
))
308 ImmStatic
=> DlDef(def
::DefStatic(did
, false)),
309 MutStatic
=> DlDef(def
::DefStatic(did
, true)),
310 Struct
=> DlDef(def
::DefStruct(did
)),
311 Fn
=> DlDef(def
::DefFn(did
, false)),
312 CtorFn
=> DlDef(def
::DefFn(did
, true)),
313 Method
| StaticMethod
=> {
314 DlDef(def
::DefMethod(did
))
317 if item_sort(item
) == Some('t'
) {
318 let trait_did
= item_require_parent_item(cdata
, item
);
319 DlDef(def
::DefAssociatedTy(trait_did
, did
))
321 DlDef(def
::DefTy(did
, false))
324 Mod
=> DlDef(def
::DefMod(did
)),
325 ForeignMod
=> DlDef(def
::DefForeignMod(did
)),
327 let enum_did
= item_require_parent_item(cdata
, item
);
328 DlDef(def
::DefVariant(enum_did
, did
, true))
331 let enum_did
= item_require_parent_item(cdata
, item
);
332 DlDef(def
::DefVariant(enum_did
, did
, false))
334 Trait
=> DlDef(def
::DefTrait(did
)),
335 Enum
=> DlDef(def
::DefTy(did
, true)),
336 Impl
| DefaultImpl
=> DlImpl(did
),
337 PublicField
| InheritedField
=> DlField
,
341 fn parse_unsafety(item_doc
: rbml
::Doc
) -> ast
::Unsafety
{
342 let unsafety_doc
= reader
::get_doc(item_doc
, tag_unsafety
);
343 if reader
::doc_as_u8(unsafety_doc
) != 0 {
344 ast
::Unsafety
::Unsafe
346 ast
::Unsafety
::Normal
350 fn parse_paren_sugar(item_doc
: rbml
::Doc
) -> bool
{
351 let paren_sugar_doc
= reader
::get_doc(item_doc
, tag_paren_sugar
);
352 reader
::doc_as_u8(paren_sugar_doc
) != 0
355 fn parse_polarity(item_doc
: rbml
::Doc
) -> ast
::ImplPolarity
{
356 let polarity_doc
= reader
::get_doc(item_doc
, tag_polarity
);
357 if reader
::doc_as_u8(polarity_doc
) != 0 {
358 ast
::ImplPolarity
::Negative
360 ast
::ImplPolarity
::Positive
364 fn parse_associated_type_names(item_doc
: rbml
::Doc
) -> Vec
<ast
::Name
> {
365 let names_doc
= reader
::get_doc(item_doc
, tag_associated_type_names
);
366 reader
::tagged_docs(names_doc
, tag_associated_type_name
)
367 .map(|name_doc
| token
::intern(name_doc
.as_str_slice()))
371 pub fn get_trait_def
<'tcx
>(cdata
: Cmd
,
372 item_id
: ast
::NodeId
,
373 tcx
: &ty
::ctxt
<'tcx
>) -> ty
::TraitDef
<'tcx
>
375 let item_doc
= lookup_item(item_id
, cdata
.data());
376 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_item_generics
);
377 let unsafety
= parse_unsafety(item_doc
);
378 let associated_type_names
= parse_associated_type_names(item_doc
);
379 let paren_sugar
= parse_paren_sugar(item_doc
);
382 paren_sugar
: paren_sugar
,
385 trait_ref
: item_trait_ref(item_doc
, tcx
, cdata
),
386 associated_type_names
: associated_type_names
,
387 nonblanket_impls
: RefCell
::new(FnvHashMap()),
388 blanket_impls
: RefCell
::new(vec
![]),
389 flags
: Cell
::new(ty
::TraitFlags
::NO_TRAIT_FLAGS
)
393 pub fn get_predicates
<'tcx
>(cdata
: Cmd
,
394 item_id
: ast
::NodeId
,
395 tcx
: &ty
::ctxt
<'tcx
>)
396 -> ty
::GenericPredicates
<'tcx
>
398 let item_doc
= lookup_item(item_id
, cdata
.data());
399 doc_predicates(item_doc
, tcx
, cdata
, tag_item_generics
)
402 pub fn get_super_predicates
<'tcx
>(cdata
: Cmd
,
403 item_id
: ast
::NodeId
,
404 tcx
: &ty
::ctxt
<'tcx
>)
405 -> ty
::GenericPredicates
<'tcx
>
407 let item_doc
= lookup_item(item_id
, cdata
.data());
408 doc_predicates(item_doc
, tcx
, cdata
, tag_item_super_predicates
)
411 pub fn get_type
<'tcx
>(cdata
: Cmd
, id
: ast
::NodeId
, tcx
: &ty
::ctxt
<'tcx
>)
412 -> ty
::TypeScheme
<'tcx
>
414 let item_doc
= lookup_item(id
, cdata
.data());
415 let t
= item_type(ast
::DefId { krate: cdata.cnum, node: id }
, item_doc
, tcx
,
417 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_item_generics
);
424 pub fn get_stability(cdata
: Cmd
, id
: ast
::NodeId
) -> Option
<attr
::Stability
> {
425 let item
= lookup_item(id
, cdata
.data());
426 reader
::maybe_get_doc(item
, tag_items_data_item_stability
).map(|doc
| {
427 let mut decoder
= reader
::Decoder
::new(doc
);
428 Decodable
::decode(&mut decoder
).unwrap()
432 pub fn get_repr_attrs(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<attr
::ReprAttr
> {
433 let item
= lookup_item(id
, cdata
.data());
434 match reader
::maybe_get_doc(item
, tag_items_data_item_repr
).map(|doc
| {
435 let mut decoder
= reader
::Decoder
::new(doc
);
436 Decodable
::decode(&mut decoder
).unwrap()
438 Some(attrs
) => attrs
,
443 pub fn get_impl_polarity
<'tcx
>(cdata
: Cmd
,
445 -> Option
<ast
::ImplPolarity
>
447 let item_doc
= lookup_item(id
, cdata
.data());
448 let fam
= item_family(item_doc
);
451 Some(parse_polarity(item_doc
))
457 pub fn get_custom_coerce_unsized_kind
<'tcx
>(cdata
: Cmd
,
459 -> Option
<ty
::CustomCoerceUnsized
> {
460 let item_doc
= lookup_item(id
, cdata
.data());
461 reader
::maybe_get_doc(item_doc
, tag_impl_coerce_unsized_kind
).map(|kind_doc
| {
462 let mut decoder
= reader
::Decoder
::new(kind_doc
);
463 Decodable
::decode(&mut decoder
).unwrap()
467 pub fn get_impl_trait
<'tcx
>(cdata
: Cmd
,
469 tcx
: &ty
::ctxt
<'tcx
>)
470 -> Option
<ty
::TraitRef
<'tcx
>>
472 let item_doc
= lookup_item(id
, cdata
.data());
473 let fam
= item_family(item_doc
);
475 Family
::Impl
| Family
::DefaultImpl
=> {
476 reader
::maybe_get_doc(item_doc
, tag_item_trait_ref
).map(|tp
| {
477 doc_trait_ref(tp
, tcx
, cdata
)
484 pub fn get_symbol(data
: &[u8], id
: ast
::NodeId
) -> String
{
485 return item_symbol(lookup_item(id
, data
));
488 // Something that a name can resolve to.
489 #[derive(Copy, Clone, Debug)]
496 /// Iterates over the language items in the given crate.
497 pub fn each_lang_item
<F
>(cdata
: Cmd
, mut f
: F
) -> bool
where
498 F
: FnMut(ast
::NodeId
, usize) -> bool
,
500 let root
= rbml
::Doc
::new(cdata
.data());
501 let lang_items
= reader
::get_doc(root
, tag_lang_items
);
502 reader
::tagged_docs(lang_items
, tag_lang_items_item
).all(|item_doc
| {
503 let id_doc
= reader
::get_doc(item_doc
, tag_lang_items_item_id
);
504 let id
= reader
::doc_as_u32(id_doc
) as usize;
505 let node_id_doc
= reader
::get_doc(item_doc
,
506 tag_lang_items_item_node_id
);
507 let node_id
= reader
::doc_as_u32(node_id_doc
) as ast
::NodeId
;
513 fn each_child_of_item_or_crate
<F
, G
>(intr
: Rc
<IdentInterner
>,
516 mut get_crate_data
: G
,
517 mut callback
: F
) where
518 F
: FnMut(DefLike
, ast
::Name
, ast
::Visibility
),
519 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
521 // Iterate over all children.
522 for child_info_doc
in reader
::tagged_docs(item_doc
, tag_mod_child
) {
523 let child_def_id
= translated_def_id(cdata
, child_info_doc
);
525 // This item may be in yet another crate if it was the child of a
527 let crate_data
= if child_def_id
.krate
== cdata
.cnum
{
530 Some(get_crate_data(child_def_id
.krate
))
532 let crate_data
= match crate_data
{
533 Some(ref cdata
) => &**cdata
,
537 let other_crates_items
= reader
::get_doc(rbml
::Doc
::new(crate_data
.data()), tag_items
);
540 match maybe_find_item(child_def_id
.node
, other_crates_items
) {
542 Some(child_item_doc
) => {
543 // Hand off the item to the callback.
544 let child_name
= item_name(&*intr
, child_item_doc
);
545 let def_like
= item_to_def_like(crate_data
, child_item_doc
, child_def_id
);
546 let visibility
= item_visibility(child_item_doc
);
547 callback(def_like
, child_name
, visibility
);
552 // As a special case, iterate over all static methods of
553 // associated implementations too. This is a bit of a botch.
555 for inherent_impl_def_id_doc
in reader
::tagged_docs(item_doc
,
556 tag_items_data_item_inherent_impl
) {
557 let inherent_impl_def_id
= item_def_id(inherent_impl_def_id_doc
, cdata
);
558 let items
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()), tag_items
);
559 if let Some(inherent_impl_doc
) = maybe_find_item(inherent_impl_def_id
.node
, items
) {
560 for impl_item_def_id_doc
in reader
::tagged_docs(inherent_impl_doc
,
561 tag_item_impl_item
) {
562 let impl_item_def_id
= item_def_id(impl_item_def_id_doc
,
564 if let Some(impl_method_doc
) = maybe_find_item(impl_item_def_id
.node
, items
) {
565 if let StaticMethod
= item_family(impl_method_doc
) {
566 // Hand off the static method to the callback.
567 let static_method_name
= item_name(&*intr
, impl_method_doc
);
568 let static_method_def_like
= item_to_def_like(cdata
, impl_method_doc
,
570 callback(static_method_def_like
,
572 item_visibility(impl_method_doc
));
579 for reexport_doc
in reexports(item_doc
) {
580 let def_id_doc
= reader
::get_doc(reexport_doc
,
581 tag_items_data_item_reexport_def_id
);
582 let child_def_id
= translated_def_id(cdata
, def_id_doc
);
584 let name_doc
= reader
::get_doc(reexport_doc
,
585 tag_items_data_item_reexport_name
);
586 let name
= name_doc
.as_str_slice();
588 // This reexport may be in yet another crate.
589 let crate_data
= if child_def_id
.krate
== cdata
.cnum
{
592 Some(get_crate_data(child_def_id
.krate
))
594 let crate_data
= match crate_data
{
595 Some(ref cdata
) => &**cdata
,
599 let other_crates_items
= reader
::get_doc(rbml
::Doc
::new(crate_data
.data()), tag_items
);
602 if let Some(child_item_doc
) = maybe_find_item(child_def_id
.node
, other_crates_items
) {
603 // Hand off the item to the callback.
604 let def_like
= item_to_def_like(crate_data
, child_item_doc
, child_def_id
);
605 // These items have a public visibility because they're part of
606 // a public re-export.
607 callback(def_like
, token
::intern(name
), ast
::Public
);
612 /// Iterates over each child of the given item.
613 pub fn each_child_of_item
<F
, G
>(intr
: Rc
<IdentInterner
>,
618 F
: FnMut(DefLike
, ast
::Name
, ast
::Visibility
),
619 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
622 let root_doc
= rbml
::Doc
::new(cdata
.data());
623 let items
= reader
::get_doc(root_doc
, tag_items
);
624 let item_doc
= match maybe_find_item(id
, items
) {
626 Some(item_doc
) => item_doc
,
629 each_child_of_item_or_crate(intr
,
636 /// Iterates over all the top-level crate items.
637 pub fn each_top_level_item_of_crate
<F
, G
>(intr
: Rc
<IdentInterner
>,
641 F
: FnMut(DefLike
, ast
::Name
, ast
::Visibility
),
642 G
: FnMut(ast
::CrateNum
) -> Rc
<crate_metadata
>,
644 let root_doc
= rbml
::Doc
::new(cdata
.data());
645 let misc_info_doc
= reader
::get_doc(root_doc
, tag_misc_info
);
646 let crate_items_doc
= reader
::get_doc(misc_info_doc
,
647 tag_misc_info_crate_items
);
649 each_child_of_item_or_crate(intr
,
656 pub fn get_item_path(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<ast_map
::PathElem
> {
657 item_path(lookup_item(id
, cdata
.data()))
660 pub type DecodeInlinedItem
<'a
> =
661 Box
<for<'tcx
> FnMut(Cmd
,
663 Vec
<ast_map
::PathElem
>,
665 -> Result
<&'tcx ast
::InlinedItem
, Vec
<ast_map
::PathElem
>> + 'a
>;
667 pub fn maybe_get_item_ast
<'tcx
>(cdata
: Cmd
, tcx
: &ty
::ctxt
<'tcx
>, id
: ast
::NodeId
,
668 mut decode_inlined_item
: DecodeInlinedItem
)
669 -> csearch
::FoundAst
<'tcx
> {
670 debug
!("Looking up item: {}", id
);
671 let item_doc
= lookup_item(id
, cdata
.data());
672 let path
= item_path(item_doc
).split_last().unwrap().1.to_vec();
673 match decode_inlined_item(cdata
, tcx
, path
, item_doc
) {
674 Ok(ii
) => csearch
::FoundAst
::Found(ii
),
676 match item_parent_item(cdata
, item_doc
) {
678 let parent_item
= lookup_item(did
.node
, cdata
.data());
679 match decode_inlined_item(cdata
, tcx
, path
, parent_item
) {
680 Ok(ii
) => csearch
::FoundAst
::FoundParent(did
, ii
),
681 Err(_
) => csearch
::FoundAst
::NotFound
684 None
=> csearch
::FoundAst
::NotFound
690 pub fn get_enum_variants
<'tcx
>(intr
: Rc
<IdentInterner
>, cdata
: Cmd
, id
: ast
::NodeId
,
691 tcx
: &ty
::ctxt
<'tcx
>) -> Vec
<Rc
<ty
::VariantInfo
<'tcx
>>> {
692 let data
= cdata
.data();
693 let items
= reader
::get_doc(rbml
::Doc
::new(data
), tag_items
);
694 let item
= find_item(id
, items
);
695 let mut disr_val
= 0;
696 reader
::tagged_docs(item
, tag_items_data_item_variant
).map(|p
| {
697 let did
= translated_def_id(cdata
, p
);
698 let item
= find_item(did
.node
, items
);
699 let ctor_ty
= item_type(ast
::DefId { krate: cdata.cnum, node: id}
,
701 let name
= item_name(&*intr
, item
);
702 let (ctor_ty
, arg_tys
, arg_names
) = match ctor_ty
.sty
{
703 ty
::TyBareFn(_
, ref f
) =>
704 (Some(ctor_ty
), f
.sig
.0.inputs
.clone(), None
),
705 _
=> { // Nullary or struct enum variant.
706 let mut arg_names
= Vec
::new();
707 let arg_tys
= get_struct_fields(intr
.clone(), cdata
, did
.node
)
710 arg_names
.push(field_ty
.name
);
711 get_type(cdata
, field_ty
.id
.node
, tcx
).ty
714 let arg_names
= if arg_names
.is_empty() { None }
else { Some(arg_names) }
;
716 (None
, arg_tys
, arg_names
)
719 match variant_disr_val(item
) {
720 Some(val
) => { disr_val = val; }
723 let old_disr_val
= disr_val
;
724 disr_val
= disr_val
.wrapping_add(1);
725 Rc
::new(ty
::VariantInfo
{
727 arg_names
: arg_names
,
730 // I'm not even sure if we encode visibility
731 // for variants -- TEST -- tjc
733 disr_val
: old_disr_val
,
739 fn get_explicit_self(item
: rbml
::Doc
) -> ty
::ExplicitSelfCategory
{
740 fn get_mutability(ch
: u8) -> ast
::Mutability
{
742 'i'
=> ast
::MutImmutable
,
743 'm'
=> ast
::MutMutable
,
744 _
=> panic
!("unknown mutability character: `{}`", ch
as char),
748 let explicit_self_doc
= reader
::get_doc(item
, tag_item_trait_method_explicit_self
);
749 let string
= explicit_self_doc
.as_str_slice();
751 let explicit_self_kind
= string
.as_bytes()[0];
752 match explicit_self_kind
as char {
753 's'
=> ty
::StaticExplicitSelfCategory
,
754 'v'
=> ty
::ByValueExplicitSelfCategory
,
755 '
~'
=> ty
::ByBoxExplicitSelfCategory
,
756 // FIXME(#4846) expl. region
758 ty
::ByReferenceExplicitSelfCategory(
760 get_mutability(string
.as_bytes()[1]))
762 _
=> panic
!("unknown self type code: `{}`", explicit_self_kind
as char)
766 /// Returns the def IDs of all the items in the given implementation.
767 pub fn get_impl_items(cdata
: Cmd
, impl_id
: ast
::NodeId
)
768 -> Vec
<ty
::ImplOrTraitItemId
> {
769 reader
::tagged_docs(lookup_item(impl_id
, cdata
.data()), tag_item_impl_item
).map(|doc
| {
770 let def_id
= item_def_id(doc
, cdata
);
771 match item_sort(doc
) {
772 Some('C'
) => ty
::ConstTraitItemId(def_id
),
773 Some('r'
) | Some('p'
) => ty
::MethodTraitItemId(def_id
),
774 Some('t'
) => ty
::TypeTraitItemId(def_id
),
775 _
=> panic
!("unknown impl item sort"),
780 pub fn get_trait_name(intr
: Rc
<IdentInterner
>,
784 let doc
= lookup_item(id
, cdata
.data());
785 item_name(&*intr
, doc
)
788 pub fn is_static_method(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
789 let doc
= lookup_item(id
, cdata
.data());
790 match item_sort(doc
) {
791 Some('r'
) | Some('p'
) => {
792 get_explicit_self(doc
) == ty
::StaticExplicitSelfCategory
798 pub fn get_impl_or_trait_item
<'tcx
>(intr
: Rc
<IdentInterner
>,
801 tcx
: &ty
::ctxt
<'tcx
>)
802 -> ty
::ImplOrTraitItem
<'tcx
> {
803 let item_doc
= lookup_item(id
, cdata
.data());
805 let def_id
= item_def_id(item_doc
, cdata
);
807 let container_id
= item_require_parent_item(cdata
, item_doc
);
808 let container_doc
= lookup_item(container_id
.node
, cdata
.data());
809 let container
= match item_family(container_doc
) {
810 Trait
=> TraitContainer(container_id
),
811 _
=> ImplContainer(container_id
),
814 let name
= item_name(&*intr
, item_doc
);
815 let vis
= item_visibility(item_doc
);
817 match item_sort(item_doc
) {
819 let ty
= doc_type(item_doc
, tcx
, cdata
);
820 let default = get_provided_source(item_doc
, cdata
);
821 ty
::ConstTraitItem(Rc
::new(ty
::AssociatedConst
{
826 container
: container
,
830 Some('r'
) | Some('p'
) => {
831 let generics
= doc_generics(item_doc
, tcx
, cdata
, tag_method_ty_generics
);
832 let predicates
= doc_predicates(item_doc
, tcx
, cdata
, tag_method_ty_generics
);
833 let fty
= doc_method_fty(item_doc
, tcx
, cdata
);
834 let explicit_self
= get_explicit_self(item_doc
);
835 let provided_source
= get_provided_source(item_doc
, cdata
);
837 ty
::MethodTraitItem(Rc
::new(ty
::Method
::new(name
,
848 let ty
= maybe_doc_type(item_doc
, tcx
, cdata
);
849 ty
::TypeTraitItem(Rc
::new(ty
::AssociatedType
{
854 container
: container
,
857 _
=> panic
!("unknown impl/trait item sort"),
861 pub fn get_trait_item_def_ids(cdata
: Cmd
, id
: ast
::NodeId
)
862 -> Vec
<ty
::ImplOrTraitItemId
> {
863 let data
= cdata
.data();
864 let item
= lookup_item(id
, data
);
865 reader
::tagged_docs(item
, tag_item_trait_item
).map(|mth
| {
866 let def_id
= item_def_id(mth
, cdata
);
867 match item_sort(mth
) {
868 Some('C'
) => ty
::ConstTraitItemId(def_id
),
869 Some('r'
) | Some('p'
) => ty
::MethodTraitItemId(def_id
),
870 Some('t'
) => ty
::TypeTraitItemId(def_id
),
871 _
=> panic
!("unknown trait item sort"),
876 pub fn get_item_variances(cdata
: Cmd
, id
: ast
::NodeId
) -> ty
::ItemVariances
{
877 let data
= cdata
.data();
878 let item_doc
= lookup_item(id
, data
);
879 let variance_doc
= reader
::get_doc(item_doc
, tag_item_variances
);
880 let mut decoder
= reader
::Decoder
::new(variance_doc
);
881 Decodable
::decode(&mut decoder
).unwrap()
884 pub fn get_provided_trait_methods
<'tcx
>(intr
: Rc
<IdentInterner
>,
887 tcx
: &ty
::ctxt
<'tcx
>)
888 -> Vec
<Rc
<ty
::Method
<'tcx
>>> {
889 let data
= cdata
.data();
890 let item
= lookup_item(id
, data
);
892 reader
::tagged_docs(item
, tag_item_trait_item
).filter_map(|mth_id
| {
893 let did
= item_def_id(mth_id
, cdata
);
894 let mth
= lookup_item(did
.node
, data
);
896 if item_sort(mth
) == Some('p'
) {
897 let trait_item
= get_impl_or_trait_item(intr
.clone(),
901 if let ty
::MethodTraitItem(ref method
) = trait_item
{
902 Some((*method
).clone())
912 pub fn get_associated_consts
<'tcx
>(intr
: Rc
<IdentInterner
>,
915 tcx
: &ty
::ctxt
<'tcx
>)
916 -> Vec
<Rc
<ty
::AssociatedConst
<'tcx
>>> {
917 let data
= cdata
.data();
918 let item
= lookup_item(id
, data
);
920 [tag_item_trait_item
, tag_item_impl_item
].iter().flat_map(|&tag
| {
921 reader
::tagged_docs(item
, tag
).filter_map(|ac_id
| {
922 let did
= item_def_id(ac_id
, cdata
);
923 let ac_doc
= lookup_item(did
.node
, data
);
925 if item_sort(ac_doc
) == Some('C'
) {
926 let trait_item
= get_impl_or_trait_item(intr
.clone(),
930 if let ty
::ConstTraitItem(ref ac
) = trait_item
{
942 pub fn get_type_name_if_impl(cdata
: Cmd
,
943 node_id
: ast
::NodeId
) -> Option
<ast
::Name
> {
944 let item
= lookup_item(node_id
, cdata
.data());
945 if item_family(item
) != Impl
{
949 reader
::tagged_docs(item
, tag_item_impl_type_basename
).nth(0).map(|doc
| {
950 token
::intern(doc
.as_str_slice())
954 pub fn get_methods_if_impl(intr
: Rc
<IdentInterner
>,
956 node_id
: ast
::NodeId
)
957 -> Option
<Vec
<MethodInfo
> > {
958 let item
= lookup_item(node_id
, cdata
.data());
959 if item_family(item
) != Impl
{
963 // If this impl implements a trait, don't consider it.
964 if reader
::tagged_docs(item
, tag_item_trait_ref
).next().is_some() {
968 let impl_method_ids
= reader
::tagged_docs(item
, tag_item_impl_item
)
969 .map(|impl_method_doc
| item_def_id(impl_method_doc
, cdata
));
971 let mut impl_methods
= Vec
::new();
972 for impl_method_id
in impl_method_ids
{
973 let impl_method_doc
= lookup_item(impl_method_id
.node
, cdata
.data());
974 let family
= item_family(impl_method_doc
);
976 StaticMethod
| Method
=> {
977 impl_methods
.push(MethodInfo
{
978 name
: item_name(&*intr
, impl_method_doc
),
979 def_id
: item_def_id(impl_method_doc
, cdata
),
980 vis
: item_visibility(impl_method_doc
),
987 return Some(impl_methods
);
990 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
991 /// the actual type definition, otherwise, return None
992 pub fn get_tuple_struct_definition_if_ctor(cdata
: Cmd
,
993 node_id
: ast
::NodeId
)
994 -> Option
<ast
::DefId
>
996 let item
= lookup_item(node_id
, cdata
.data());
997 reader
::tagged_docs(item
, tag_items_data_item_is_tuple_struct_ctor
).next().map(|_
| {
998 item_require_parent_item(cdata
, item
)
1002 pub fn get_item_attrs(cdata
: Cmd
,
1003 orig_node_id
: ast
::NodeId
)
1004 -> Vec
<ast
::Attribute
> {
1005 // The attributes for a tuple struct are attached to the definition, not the ctor;
1006 // we assume that someone passing in a tuple struct ctor is actually wanting to
1007 // look at the definition
1008 let node_id
= get_tuple_struct_definition_if_ctor(cdata
, orig_node_id
);
1009 let node_id
= node_id
.map(|x
| x
.node
).unwrap_or(orig_node_id
);
1010 let item
= lookup_item(node_id
, cdata
.data());
1011 get_attributes(item
)
1014 pub fn get_struct_field_attrs(cdata
: Cmd
) -> HashMap
<ast
::NodeId
, Vec
<ast
::Attribute
>> {
1015 let data
= rbml
::Doc
::new(cdata
.data());
1016 let fields
= reader
::get_doc(data
, tag_struct_fields
);
1017 reader
::tagged_docs(fields
, tag_struct_field
).map(|field
| {
1018 let id
= reader
::doc_as_u32(reader
::get_doc(field
, tag_struct_field_id
));
1019 let attrs
= get_attributes(field
);
1024 fn struct_field_family_to_visibility(family
: Family
) -> ast
::Visibility
{
1026 PublicField
=> ast
::Public
,
1027 InheritedField
=> ast
::Inherited
,
1032 pub fn get_struct_fields(intr
: Rc
<IdentInterner
>, cdata
: Cmd
, id
: ast
::NodeId
)
1033 -> Vec
<ty
::FieldTy
> {
1034 let data
= cdata
.data();
1035 let item
= lookup_item(id
, data
);
1036 reader
::tagged_docs(item
, tag_item_field
).filter_map(|an_item
| {
1037 let f
= item_family(an_item
);
1038 if f
== PublicField
|| f
== InheritedField
{
1039 let name
= item_name(&*intr
, an_item
);
1040 let did
= item_def_id(an_item
, cdata
);
1041 let tagdoc
= reader
::get_doc(an_item
, tag_item_field_origin
);
1042 let origin_id
= translated_def_id(cdata
, tagdoc
);
1046 vis
: struct_field_family_to_visibility(f
),
1052 }).chain(reader
::tagged_docs(item
, tag_item_unnamed_field
).map(|an_item
| {
1053 let did
= item_def_id(an_item
, cdata
);
1054 let tagdoc
= reader
::get_doc(an_item
, tag_item_field_origin
);
1055 let f
= item_family(an_item
);
1056 let origin_id
= translated_def_id(cdata
, tagdoc
);
1058 name
: special_idents
::unnamed_field
.name
,
1060 vis
: struct_field_family_to_visibility(f
),
1066 fn get_meta_items(md
: rbml
::Doc
) -> Vec
<P
<ast
::MetaItem
>> {
1067 reader
::tagged_docs(md
, tag_meta_item_word
).map(|meta_item_doc
| {
1068 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1069 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1070 attr
::mk_word_item(n
)
1071 }).chain(reader
::tagged_docs(md
, tag_meta_item_name_value
).map(|meta_item_doc
| {
1072 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1073 let vd
= reader
::get_doc(meta_item_doc
, tag_meta_item_value
);
1074 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1075 let v
= token
::intern_and_get_ident(vd
.as_str_slice());
1076 // FIXME (#623): Should be able to decode MetaNameValue variants,
1077 // but currently the encoder just drops them
1078 attr
::mk_name_value_item_str(n
, v
)
1079 })).chain(reader
::tagged_docs(md
, tag_meta_item_list
).map(|meta_item_doc
| {
1080 let nd
= reader
::get_doc(meta_item_doc
, tag_meta_item_name
);
1081 let n
= token
::intern_and_get_ident(nd
.as_str_slice());
1082 let subitems
= get_meta_items(meta_item_doc
);
1083 attr
::mk_list_item(n
, subitems
)
1087 fn get_attributes(md
: rbml
::Doc
) -> Vec
<ast
::Attribute
> {
1088 match reader
::maybe_get_doc(md
, tag_attributes
) {
1090 reader
::tagged_docs(attrs_d
, tag_attribute
).map(|attr_doc
| {
1091 let is_sugared_doc
= reader
::doc_as_u8(
1092 reader
::get_doc(attr_doc
, tag_attribute_is_sugared_doc
)
1094 let meta_items
= get_meta_items(attr_doc
);
1095 // Currently it's only possible to have a single meta item on
1097 assert_eq
!(meta_items
.len(), 1);
1098 let meta_item
= meta_items
.into_iter().nth(0).unwrap();
1100 node
: ast
::Attribute_
{
1101 id
: attr
::mk_attr_id(),
1102 style
: ast
::AttrOuter
,
1104 is_sugared_doc
: is_sugared_doc
,
1106 span
: codemap
::DUMMY_SP
1114 fn list_crate_attributes(md
: rbml
::Doc
, hash
: &Svh
,
1115 out
: &mut io
::Write
) -> io
::Result
<()> {
1116 try
!(write
!(out
, "=Crate Attributes ({})=\n", *hash
));
1118 let r
= get_attributes(md
);
1120 try
!(write
!(out
, "{}\n", pprust
::attribute_to_string(attr
)));
1126 pub fn get_crate_attributes(data
: &[u8]) -> Vec
<ast
::Attribute
> {
1127 get_attributes(rbml
::Doc
::new(data
))
1131 pub struct CrateDep
{
1132 pub cnum
: ast
::CrateNum
,
1137 pub fn get_crate_deps(data
: &[u8]) -> Vec
<CrateDep
> {
1138 let cratedoc
= rbml
::Doc
::new(data
);
1139 let depsdoc
= reader
::get_doc(cratedoc
, tag_crate_deps
);
1141 fn docstr(doc
: rbml
::Doc
, tag_
: usize) -> String
{
1142 let d
= reader
::get_doc(doc
, tag_
);
1143 d
.as_str_slice().to_string()
1146 reader
::tagged_docs(depsdoc
, tag_crate_dep
).enumerate().map(|(crate_num
, depdoc
)| {
1147 let name
= docstr(depdoc
, tag_crate_dep_crate_name
);
1148 let hash
= Svh
::new(&docstr(depdoc
, tag_crate_dep_hash
));
1150 cnum
: crate_num
as u32 + 1,
1157 fn list_crate_deps(data
: &[u8], out
: &mut io
::Write
) -> io
::Result
<()> {
1158 try
!(write
!(out
, "=External Dependencies=\n"));
1159 for dep
in &get_crate_deps(data
) {
1160 try
!(write
!(out
, "{} {}-{}\n", dep
.cnum
, dep
.name
, dep
.hash
));
1162 try
!(write
!(out
, "\n"));
1166 pub fn maybe_get_crate_hash(data
: &[u8]) -> Option
<Svh
> {
1167 let cratedoc
= rbml
::Doc
::new(data
);
1168 reader
::maybe_get_doc(cratedoc
, tag_crate_hash
).map(|doc
| {
1169 Svh
::new(doc
.as_str_slice())
1173 pub fn get_crate_hash(data
: &[u8]) -> Svh
{
1174 let cratedoc
= rbml
::Doc
::new(data
);
1175 let hashdoc
= reader
::get_doc(cratedoc
, tag_crate_hash
);
1176 Svh
::new(hashdoc
.as_str_slice())
1179 pub fn maybe_get_crate_name(data
: &[u8]) -> Option
<String
> {
1180 let cratedoc
= rbml
::Doc
::new(data
);
1181 reader
::maybe_get_doc(cratedoc
, tag_crate_crate_name
).map(|doc
| {
1182 doc
.as_str_slice().to_string()
1186 pub fn get_crate_triple(data
: &[u8]) -> Option
<String
> {
1187 let cratedoc
= rbml
::Doc
::new(data
);
1188 let triple_doc
= reader
::maybe_get_doc(cratedoc
, tag_crate_triple
);
1189 triple_doc
.map(|s
| s
.as_str().to_string())
1192 pub fn get_crate_name(data
: &[u8]) -> String
{
1193 maybe_get_crate_name(data
).expect("no crate name in crate")
1196 pub fn list_crate_metadata(bytes
: &[u8], out
: &mut io
::Write
) -> io
::Result
<()> {
1197 let hash
= get_crate_hash(bytes
);
1198 let md
= rbml
::Doc
::new(bytes
);
1199 try
!(list_crate_attributes(md
, &hash
, out
));
1200 list_crate_deps(bytes
, out
)
1203 // Translates a def_id from an external crate to a def_id for the current
1204 // compilation environment. We use this when trying to load types from
1205 // external crates - if those types further refer to types in other crates
1206 // then we must translate the crate number from that encoded in the external
1207 // crate to the correct local crate number.
1208 pub fn translate_def_id(cdata
: Cmd
, did
: ast
::DefId
) -> ast
::DefId
{
1209 if did
.krate
== ast
::LOCAL_CRATE
{
1210 return ast
::DefId { krate: cdata.cnum, node: did.node }
;
1213 match cdata
.cnum_map
.get(&did
.krate
) {
1220 None
=> panic
!("didn't find a crate in the cnum_map")
1224 // Translate a DefId from the current compilation environment to a DefId
1225 // for an external crate.
1226 fn reverse_translate_def_id(cdata
: Cmd
, did
: ast
::DefId
) -> Option
<ast
::DefId
> {
1227 if did
.krate
== cdata
.cnum
{
1228 return Some(ast
::DefId { krate: ast::LOCAL_CRATE, node: did.node }
);
1231 for (&local
, &global
) in &cdata
.cnum_map
{
1232 if global
== did
.krate
{
1233 return Some(ast
::DefId { krate: local, node: did.node }
);
1240 pub fn each_inherent_implementation_for_type
<F
>(cdata
: Cmd
,
1243 where F
: FnMut(ast
::DefId
),
1245 let item_doc
= lookup_item(id
, cdata
.data());
1246 for impl_doc
in reader
::tagged_docs(item_doc
, tag_items_data_item_inherent_impl
) {
1247 if reader
::maybe_get_doc(impl_doc
, tag_item_trait_ref
).is_none() {
1248 callback(item_def_id(impl_doc
, cdata
));
1253 pub fn each_implementation_for_trait
<F
>(cdata
: Cmd
,
1255 mut callback
: F
) where
1256 F
: FnMut(ast
::DefId
),
1258 if cdata
.cnum
== def_id
.krate
{
1259 let item_doc
= lookup_item(def_id
.node
, cdata
.data());
1260 for impl_doc
in reader
::tagged_docs(item_doc
, tag_items_data_item_extension_impl
) {
1261 callback(item_def_id(impl_doc
, cdata
));
1266 // Do a reverse lookup beforehand to avoid touching the crate_num
1267 // hash map in the loop below.
1268 if let Some(crate_local_did
) = reverse_translate_def_id(cdata
, def_id
) {
1269 let def_id_u64
= def_to_u64(crate_local_did
);
1271 let impls_doc
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()), tag_impls
);
1272 for impl_doc
in reader
::tagged_docs(impls_doc
, tag_impls_impl
) {
1273 let impl_trait
= reader
::get_doc(impl_doc
, tag_impls_impl_trait_def_id
);
1274 if reader
::doc_as_u64(impl_trait
) == def_id_u64
{
1275 callback(item_def_id(impl_doc
, cdata
));
1281 pub fn get_trait_of_item(cdata
: Cmd
, id
: ast
::NodeId
, tcx
: &ty
::ctxt
)
1282 -> Option
<ast
::DefId
> {
1283 let item_doc
= lookup_item(id
, cdata
.data());
1284 let parent_item_id
= match item_parent_item(cdata
, item_doc
) {
1285 None
=> return None
,
1286 Some(item_id
) => item_id
,
1288 let parent_item_doc
= lookup_item(parent_item_id
.node
, cdata
.data());
1289 match item_family(parent_item_doc
) {
1290 Trait
=> Some(item_def_id(parent_item_doc
, cdata
)),
1291 Impl
| DefaultImpl
=> {
1292 reader
::maybe_get_doc(parent_item_doc
, tag_item_trait_ref
)
1293 .map(|_
| item_trait_ref(parent_item_doc
, tcx
, cdata
).def_id
)
1300 pub fn get_native_libraries(cdata
: Cmd
)
1301 -> Vec
<(cstore
::NativeLibraryKind
, String
)> {
1302 let libraries
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1303 tag_native_libraries
);
1304 reader
::tagged_docs(libraries
, tag_native_libraries_lib
).map(|lib_doc
| {
1305 let kind_doc
= reader
::get_doc(lib_doc
, tag_native_libraries_kind
);
1306 let name_doc
= reader
::get_doc(lib_doc
, tag_native_libraries_name
);
1307 let kind
: cstore
::NativeLibraryKind
=
1308 cstore
::NativeLibraryKind
::from_u32(reader
::doc_as_u32(kind_doc
)).unwrap();
1309 let name
= name_doc
.as_str().to_string();
1314 pub fn get_plugin_registrar_fn(data
: &[u8]) -> Option
<ast
::NodeId
> {
1315 reader
::maybe_get_doc(rbml
::Doc
::new(data
), tag_plugin_registrar_fn
)
1316 .map(|doc
| reader
::doc_as_u32(doc
))
1319 pub fn each_exported_macro
<F
>(data
: &[u8], intr
: &IdentInterner
, mut f
: F
) where
1320 F
: FnMut(ast
::Name
, Vec
<ast
::Attribute
>, String
) -> bool
,
1322 let macros
= reader
::get_doc(rbml
::Doc
::new(data
), tag_macro_defs
);
1323 for macro_doc
in reader
::tagged_docs(macros
, tag_macro_def
) {
1324 let name
= item_name(intr
, macro_doc
);
1325 let attrs
= get_attributes(macro_doc
);
1326 let body
= reader
::get_doc(macro_doc
, tag_macro_def_body
);
1327 if !f(name
, attrs
, body
.as_str().to_string()) {
1333 pub fn get_dylib_dependency_formats(cdata
: Cmd
)
1334 -> Vec
<(ast
::CrateNum
, cstore
::LinkagePreference
)>
1336 let formats
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1337 tag_dylib_dependency_formats
);
1338 let mut result
= Vec
::new();
1340 debug
!("found dylib deps: {}", formats
.as_str_slice());
1341 for spec
in formats
.as_str_slice().split('
,'
) {
1342 if spec
.is_empty() { continue }
1343 let cnum
= spec
.split('
:'
).nth(0).unwrap();
1344 let link
= spec
.split('
:'
).nth(1).unwrap();
1345 let cnum
: ast
::CrateNum
= cnum
.parse().unwrap();
1346 let cnum
= match cdata
.cnum_map
.get(&cnum
) {
1348 None
=> panic
!("didn't find a crate in the cnum_map")
1350 result
.push((cnum
, if link
== "d" {
1351 cstore
::RequireDynamic
1353 cstore
::RequireStatic
1359 pub fn get_missing_lang_items(cdata
: Cmd
)
1360 -> Vec
<lang_items
::LangItem
>
1362 let items
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()), tag_lang_items
);
1363 reader
::tagged_docs(items
, tag_lang_items_missing
).map(|missing_docs
| {
1364 lang_items
::LangItem
::from_u32(reader
::doc_as_u32(missing_docs
)).unwrap()
1368 pub fn get_method_arg_names(cdata
: Cmd
, id
: ast
::NodeId
) -> Vec
<String
> {
1369 let method_doc
= lookup_item(id
, cdata
.data());
1370 match reader
::maybe_get_doc(method_doc
, tag_method_argument_names
) {
1372 reader
::tagged_docs(args_doc
, tag_method_argument_name
).map(|name_doc
| {
1373 name_doc
.as_str_slice().to_string()
1380 pub fn get_reachable_extern_fns(cdata
: Cmd
) -> Vec
<ast
::DefId
> {
1381 let items
= reader
::get_doc(rbml
::Doc
::new(cdata
.data()),
1382 tag_reachable_extern_fns
);
1383 reader
::tagged_docs(items
, tag_reachable_extern_fn_id
).map(|doc
| {
1386 node
: reader
::doc_as_u32(doc
),
1391 pub fn is_typedef(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1392 let item_doc
= lookup_item(id
, cdata
.data());
1393 match item_family(item_doc
) {
1399 pub fn is_const_fn(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1400 let item_doc
= lookup_item(id
, cdata
.data());
1401 match fn_constness(item_doc
) {
1402 ast
::Constness
::Const
=> true,
1403 ast
::Constness
::NotConst
=> false,
1407 pub fn is_impl(cdata
: Cmd
, id
: ast
::NodeId
) -> bool
{
1408 let item_doc
= lookup_item(id
, cdata
.data());
1409 match item_family(item_doc
) {
1415 fn doc_generics
<'tcx
>(base_doc
: rbml
::Doc
,
1416 tcx
: &ty
::ctxt
<'tcx
>,
1419 -> ty
::Generics
<'tcx
>
1421 let doc
= reader
::get_doc(base_doc
, tag
);
1423 let mut types
= subst
::VecPerParamSpace
::empty();
1424 for p
in reader
::tagged_docs(doc
, tag_type_param_def
) {
1425 let bd
= parse_type_param_def_data(
1426 p
.data
, p
.start
, cdata
.cnum
, tcx
,
1427 |_
, did
| translate_def_id(cdata
, did
));
1428 types
.push(bd
.space
, bd
);
1431 let mut regions
= subst
::VecPerParamSpace
::empty();
1432 for rp_doc
in reader
::tagged_docs(doc
, tag_region_param_def
) {
1433 let ident_str_doc
= reader
::get_doc(rp_doc
,
1434 tag_region_param_def_ident
);
1435 let name
= item_name(&*token
::get_ident_interner(), ident_str_doc
);
1436 let def_id_doc
= reader
::get_doc(rp_doc
,
1437 tag_region_param_def_def_id
);
1438 let def_id
= translated_def_id(cdata
, def_id_doc
);
1440 let doc
= reader
::get_doc(rp_doc
, tag_region_param_def_space
);
1441 let space
= subst
::ParamSpace
::from_uint(reader
::doc_as_u64(doc
) as usize);
1443 let doc
= reader
::get_doc(rp_doc
, tag_region_param_def_index
);
1444 let index
= reader
::doc_as_u64(doc
) as u32;
1446 let bounds
= reader
::tagged_docs(rp_doc
, tag_items_data_region
).map(|p
| {
1447 parse_region_data(p
.data
, cdata
.cnum
, p
.start
, tcx
,
1448 |_
, did
| translate_def_id(cdata
, did
))
1451 regions
.push(space
, ty
::RegionParameterDef
{ name
: name
,
1458 ty
::Generics { types: types, regions: regions }
1461 fn doc_predicates
<'tcx
>(base_doc
: rbml
::Doc
,
1462 tcx
: &ty
::ctxt
<'tcx
>,
1465 -> ty
::GenericPredicates
<'tcx
>
1467 let doc
= reader
::get_doc(base_doc
, tag
);
1469 let mut predicates
= subst
::VecPerParamSpace
::empty();
1470 for predicate_doc
in reader
::tagged_docs(doc
, tag_predicate
) {
1471 let space_doc
= reader
::get_doc(predicate_doc
, tag_predicate_space
);
1472 let space
= subst
::ParamSpace
::from_uint(reader
::doc_as_u8(space_doc
) as usize);
1474 let data_doc
= reader
::get_doc(predicate_doc
, tag_predicate_data
);
1475 let data
= parse_predicate_data(data_doc
.data
, data_doc
.start
, cdata
.cnum
, tcx
,
1476 |_
, did
| translate_def_id(cdata
, did
));
1478 predicates
.push(space
, data
);
1481 ty
::GenericPredicates { predicates: predicates }
1484 pub fn is_defaulted_trait(cdata
: Cmd
, trait_id
: ast
::NodeId
) -> bool
{
1485 let trait_doc
= lookup_item(trait_id
, cdata
.data());
1486 assert
!(item_family(trait_doc
) == Family
::Trait
);
1487 let defaulted_doc
= reader
::get_doc(trait_doc
, tag_defaulted_trait
);
1488 reader
::doc_as_u8(defaulted_doc
) != 0
1491 pub fn is_default_impl(cdata
: Cmd
, impl_id
: ast
::NodeId
) -> bool
{
1492 let impl_doc
= lookup_item(impl_id
, cdata
.data());
1493 item_family(impl_doc
) == Family
::DefaultImpl
1496 pub fn get_imported_filemaps(metadata
: &[u8]) -> Vec
<codemap
::FileMap
> {
1497 let crate_doc
= rbml
::Doc
::new(metadata
);
1498 let cm_doc
= reader
::get_doc(crate_doc
, tag_codemap
);
1500 reader
::tagged_docs(cm_doc
, tag_codemap_filemap
).map(|filemap_doc
| {
1501 let mut decoder
= reader
::Decoder
::new(filemap_doc
);
1502 Decodable
::decode(&mut decoder
).unwrap()