2012-12-03 18:48:01 -06:00
|
|
|
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2011-07-08 01:29:09 -05:00
|
|
|
// Decoding metadata from a single crate's metadata
|
2011-06-27 18:03:01 -05:00
|
|
|
|
2013-05-17 17:28:44 -05:00
|
|
|
use core::prelude::*;
|
|
|
|
|
2013-02-19 01:40:42 -06:00
|
|
|
use metadata::cstore::crate_metadata;
|
2012-12-13 15:05:22 -06:00
|
|
|
use metadata::common::*;
|
2013-06-19 14:50:12 -05:00
|
|
|
use metadata::csearch::StaticMethodInfo;
|
2012-12-23 16:41:37 -06:00
|
|
|
use metadata::csearch;
|
|
|
|
use metadata::cstore;
|
|
|
|
use metadata::decoder;
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
use metadata::tydecode::{parse_ty_data, parse_def_id,
|
|
|
|
parse_type_param_def_data,
|
2013-03-27 05:16:28 -05:00
|
|
|
parse_bare_fn_ty_data, parse_trait_ref_data};
|
2013-02-19 01:40:42 -06:00
|
|
|
use middle::{ty, resolve};
|
2012-12-13 15:05:22 -06:00
|
|
|
|
2013-03-26 15:38:07 -05:00
|
|
|
use core::hash::HashUtil;
|
2012-12-23 16:41:37 -06:00
|
|
|
use core::int;
|
2013-03-01 12:44:43 -06:00
|
|
|
use core::io::WriterUtil;
|
2012-12-23 16:41:37 -06:00
|
|
|
use core::io;
|
|
|
|
use core::option;
|
|
|
|
use core::str;
|
|
|
|
use core::vec;
|
2013-05-18 14:39:17 -05:00
|
|
|
use extra::ebml::reader;
|
|
|
|
use extra::ebml;
|
|
|
|
use extra::serialize::Decodable;
|
2012-09-04 13:54:36 -05:00
|
|
|
use syntax::ast_map;
|
2012-12-13 15:05:22 -06:00
|
|
|
use syntax::attr;
|
2013-06-12 12:02:55 -05:00
|
|
|
use syntax::parse::token::{ident_interner, special_idents};
|
2012-12-13 15:05:22 -06:00
|
|
|
use syntax::print::pprust;
|
|
|
|
use syntax::{ast, ast_util};
|
2013-01-30 11:56:33 -06:00
|
|
|
use syntax::codemap;
|
2013-06-04 14:34:25 -05:00
|
|
|
use syntax::parse::token;
|
2011-06-27 17:53:27 -05:00
|
|
|
|
2013-02-19 01:40:42 -06:00
|
|
|
type cmd = @crate_metadata;
|
|
|
|
|
2011-07-08 16:53:25 -05:00
|
|
|
// A function that takes a def_id relative to the crate being searched and
|
|
|
|
// returns a def_id relative to the compilation environment, i.e. if we hit a
|
|
|
|
// def_id for an item defined in another crate, somebody needs to figure out
|
|
|
|
// what crate that's in and give us a def_id that makes sense for the current
|
|
|
|
// build.
|
2011-07-27 07:19:39 -05:00
|
|
|
|
2013-03-07 16:38:38 -06:00
|
|
|
fn lookup_hash(d: ebml::Doc, eq_fn: &fn(x:&[u8]) -> bool, hash: uint) ->
|
2012-10-07 18:33:20 -05:00
|
|
|
Option<ebml::Doc> {
|
2012-12-06 18:13:54 -06:00
|
|
|
let index = reader::get_doc(d, tag_index);
|
|
|
|
let table = reader::get_doc(index, tag_index_table);
|
2011-07-27 07:19:39 -05:00
|
|
|
let hash_pos = table.start + hash % 256u * 4u;
|
2012-02-14 17:21:53 -06:00
|
|
|
let pos = io::u64_from_be_bytes(*d.data, hash_pos, 4u) as uint;
|
2012-12-06 18:13:54 -06:00
|
|
|
let tagged_doc = reader::doc_at(d.data, pos);
|
2011-06-27 17:53:27 -05:00
|
|
|
|
2011-07-27 07:19:39 -05:00
|
|
|
let belt = tag_index_buckets_bucket_elt;
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(tagged_doc.doc, belt) |elt| {
|
2012-02-14 17:21:53 -06:00
|
|
|
let pos = io::u64_from_be_bytes(*elt.data, elt.start, 4u) as uint;
|
2013-06-27 04:48:50 -05:00
|
|
|
if eq_fn(elt.data.slice(elt.start + 4u, elt.end)) {
|
2012-12-06 18:13:54 -06:00
|
|
|
return Some(reader::doc_at(d.data, pos).doc);
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-08-20 14:23:37 -05:00
|
|
|
None
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-03-25 15:21:04 -05:00
|
|
|
pub type GetCrateDataCb<'self> = &'self fn(ast::crate_num) -> cmd;
|
2012-11-08 18:52:21 -06:00
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn maybe_find_item(item_id: int, items: ebml::Doc) -> Option<ebml::Doc> {
|
2012-07-03 18:37:38 -05:00
|
|
|
fn eq_item(bytes: &[u8], item_id: int) -> bool {
|
2013-02-08 13:28:20 -06:00
|
|
|
return io::u64_from_be_bytes(
|
2013-06-27 04:48:50 -05:00
|
|
|
bytes.slice(0u, 4u), 0u, 4u) as int
|
2012-07-03 18:37:38 -05:00
|
|
|
== item_id;
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
2012-07-26 15:43:27 -05:00
|
|
|
lookup_hash(items,
|
|
|
|
|a| eq_item(a, item_id),
|
2012-09-19 15:13:24 -05:00
|
|
|
item_id.hash() as uint)
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn find_item(item_id: int, items: ebml::Doc) -> ebml::Doc {
|
2013-06-11 04:40:10 -05:00
|
|
|
match maybe_find_item(item_id, items) {
|
|
|
|
None => fail!("lookup_item: id not found: %d", item_id),
|
|
|
|
Some(d) => d
|
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
// Looks up an item in the given metadata and returns an ebml doc pointing
|
2011-06-27 17:53:27 -05:00
|
|
|
// to the item data.
|
2012-10-07 18:33:20 -05:00
|
|
|
fn lookup_item(item_id: int, data: @~[u8]) -> ebml::Doc {
|
2012-12-06 18:13:54 -06:00
|
|
|
let items = reader::get_doc(reader::Doc(data), tag_items);
|
2013-06-11 04:40:10 -05:00
|
|
|
find_item(item_id, items)
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-03-20 10:40:02 -05:00
|
|
|
#[deriving(Eq)]
|
2012-08-22 19:58:05 -05:00
|
|
|
enum Family {
|
2013-06-21 20:46:34 -05:00
|
|
|
ImmStatic, // c
|
|
|
|
MutStatic, // b
|
2012-08-22 19:58:05 -05:00
|
|
|
Fn, // f
|
|
|
|
UnsafeFn, // u
|
|
|
|
StaticMethod, // F
|
|
|
|
UnsafeStaticMethod, // U
|
|
|
|
ForeignFn, // e
|
|
|
|
Type, // y
|
|
|
|
ForeignType, // T
|
|
|
|
Mod, // m
|
|
|
|
ForeignMod, // n
|
|
|
|
Enum, // t
|
|
|
|
Variant, // v
|
|
|
|
Impl, // i
|
|
|
|
Trait, // I
|
|
|
|
Struct, // S
|
|
|
|
PublicField, // g
|
|
|
|
PrivateField, // j
|
|
|
|
InheritedField // N
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_family(item: ebml::Doc) -> Family {
|
2012-12-06 18:13:54 -06:00
|
|
|
let fam = reader::get_doc(item, tag_items_data_item_family);
|
|
|
|
match reader::doc_as_u8(fam) as char {
|
2013-06-21 20:46:34 -05:00
|
|
|
'c' => ImmStatic,
|
|
|
|
'b' => MutStatic,
|
2012-08-22 19:58:05 -05:00
|
|
|
'f' => Fn,
|
|
|
|
'u' => UnsafeFn,
|
|
|
|
'F' => StaticMethod,
|
|
|
|
'U' => UnsafeStaticMethod,
|
|
|
|
'e' => ForeignFn,
|
|
|
|
'y' => Type,
|
|
|
|
'T' => ForeignType,
|
|
|
|
'm' => Mod,
|
|
|
|
'n' => ForeignMod,
|
|
|
|
't' => Enum,
|
|
|
|
'v' => Variant,
|
|
|
|
'i' => Impl,
|
|
|
|
'I' => Trait,
|
|
|
|
'S' => Struct,
|
|
|
|
'g' => PublicField,
|
|
|
|
'j' => PrivateField,
|
|
|
|
'N' => InheritedField,
|
2013-05-05 17:18:51 -05:00
|
|
|
c => fail!("unexpected family char: %c", c)
|
2012-08-22 19:58:05 -05:00
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-02-27 15:45:37 -06:00
|
|
|
fn item_visibility(item: ebml::Doc) -> ast::visibility {
|
2013-03-20 16:38:57 -05:00
|
|
|
match reader::maybe_get_doc(item, tag_items_data_item_visibility) {
|
|
|
|
None => ast::public,
|
|
|
|
Some(visibility_doc) => {
|
|
|
|
match reader::doc_as_u8(visibility_doc) as char {
|
|
|
|
'y' => ast::public,
|
|
|
|
'n' => ast::private,
|
|
|
|
'i' => ast::inherited,
|
2013-05-05 17:18:51 -05:00
|
|
|
_ => fail!("unknown visibility character")
|
2013-03-20 16:38:57 -05:00
|
|
|
}
|
|
|
|
}
|
2013-02-27 15:45:37 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-08 14:39:30 -05:00
|
|
|
fn item_method_sort(item: ebml::Doc) -> char {
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_trait_method_sort) |doc| {
|
2013-06-07 19:37:17 -05:00
|
|
|
return doc.as_str_slice()[0] as char;
|
2012-10-08 14:39:30 -05:00
|
|
|
}
|
|
|
|
return 'r';
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_symbol(item: ebml::Doc) -> ~str {
|
2013-06-07 19:37:17 -05:00
|
|
|
reader::get_doc(item, tag_items_data_item_symbol).as_str()
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_parent_item(d: ebml::Doc) -> Option<ast::def_id> {
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(d, tag_items_data_parent_item) |did| {
|
2013-06-07 19:32:25 -05:00
|
|
|
return Some(reader::with_doc_data(did, parse_def_id));
|
2012-03-08 16:13:57 -06:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
None
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-18 15:29:34 -05:00
|
|
|
fn translated_parent_item_opt(cnum: ast::crate_num, d: ebml::Doc) ->
|
|
|
|
Option<ast::def_id> {
|
|
|
|
let trait_did_opt = item_parent_item(d);
|
2013-01-13 13:05:40 -06:00
|
|
|
do trait_did_opt.map |trait_did| {
|
|
|
|
ast::def_id { crate: cnum, node: trait_did.node }
|
|
|
|
}
|
2012-10-18 15:29:34 -05:00
|
|
|
}
|
|
|
|
|
2012-10-12 19:00:08 -05:00
|
|
|
fn item_reqd_and_translated_parent_item(cnum: ast::crate_num,
|
|
|
|
d: ebml::Doc) -> ast::def_id {
|
2013-05-19 00:07:44 -05:00
|
|
|
let trait_did = item_parent_item(d).expect("item without parent");
|
2013-01-13 13:05:40 -06:00
|
|
|
ast::def_id { crate: cnum, node: trait_did.node }
|
2012-10-12 19:00:08 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_def_id(d: ebml::Doc, cdata: cmd) -> ast::def_id {
|
2012-12-06 18:13:54 -06:00
|
|
|
let tagdoc = reader::get_doc(d, tag_def_id);
|
2013-06-07 19:32:25 -05:00
|
|
|
return translate_def_id(cdata, reader::with_doc_data(tagdoc, parse_def_id));
|
2012-03-06 10:02:13 -06:00
|
|
|
}
|
|
|
|
|
2013-05-03 12:08:08 -05:00
|
|
|
fn each_reexport(d: ebml::Doc, f: &fn(ebml::Doc) -> bool) -> bool {
|
|
|
|
for reader::tagged_docs(d, tag_items_data_item_reexport) |reexport_doc| {
|
|
|
|
if !f(reexport_doc) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2012-08-17 14:41:34 -05:00
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn variant_disr_val(d: ebml::Doc) -> Option<int> {
|
2013-03-16 14:49:12 -05:00
|
|
|
do reader::maybe_get_doc(d, tag_disr_val).chain |val_doc| {
|
2013-06-07 19:37:17 -05:00
|
|
|
do reader::with_doc_data(val_doc) |data| { int::parse_bytes(data, 10u) }
|
2012-01-10 15:50:40 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn doc_type(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::t {
|
2012-12-06 18:13:54 -06:00
|
|
|
let tp = reader::get_doc(doc, tag_items_data_item_type);
|
2013-06-07 19:24:11 -05:00
|
|
|
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
2013-01-17 08:13:26 -06:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
|
|
|
|
2013-03-27 09:26:57 -05:00
|
|
|
fn doc_method_fty(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::BareFnTy {
|
|
|
|
let tp = reader::get_doc(doc, tag_item_method_fty);
|
2013-06-07 19:24:11 -05:00
|
|
|
parse_bare_fn_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
2013-03-27 09:26:57 -05:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
|
|
|
}
|
|
|
|
|
2013-03-29 15:02:55 -05:00
|
|
|
fn doc_transformed_self_ty(doc: ebml::Doc,
|
|
|
|
tcx: ty::ctxt,
|
|
|
|
cdata: cmd) -> Option<ty::t>
|
|
|
|
{
|
|
|
|
do reader::maybe_get_doc(doc, tag_item_method_transformed_self_ty).map |tp| {
|
2013-06-07 19:24:11 -05:00
|
|
|
parse_ty_data(*tp.data, cdata.cnum, tp.start, tcx,
|
2013-03-29 15:02:55 -05:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-15 14:24:24 -05:00
|
|
|
pub fn item_type(_item_id: ast::def_id, item: ebml::Doc,
|
|
|
|
tcx: ty::ctxt, cdata: cmd) -> ty::t {
|
2013-04-02 15:41:18 -05:00
|
|
|
doc_type(item, tcx, cdata)
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-03-27 05:16:28 -05:00
|
|
|
fn doc_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
|
2013-06-07 19:24:11 -05:00
|
|
|
parse_trait_ref_data(*doc.data, cdata.cnum, doc.start, tcx,
|
2013-03-27 05:16:28 -05:00
|
|
|
|_, did| translate_def_id(cdata, did))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn item_trait_ref(doc: ebml::Doc, tcx: ty::ctxt, cdata: cmd) -> ty::TraitRef {
|
|
|
|
let tp = reader::get_doc(doc, tag_item_trait_ref);
|
|
|
|
doc_trait_ref(tp, tcx, cdata)
|
2012-01-05 03:57:19 -06:00
|
|
|
}
|
|
|
|
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
fn item_ty_param_defs(item: ebml::Doc, tcx: ty::ctxt, cdata: cmd,
|
|
|
|
tag: uint)
|
|
|
|
-> @~[ty::TypeParameterDef] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut bounds = ~[];
|
2013-03-27 09:26:57 -05:00
|
|
|
for reader::tagged_docs(item, tag) |p| {
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
let bd = parse_type_param_def_data(
|
2013-06-07 19:24:11 -05:00
|
|
|
*p.data, p.start, cdata.cnum, tcx,
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
|_, did| translate_def_id(cdata, did));
|
2012-09-26 19:33:34 -05:00
|
|
|
bounds.push(bd);
|
2011-12-28 10:50:12 -06:00
|
|
|
}
|
2012-01-02 05:09:26 -06:00
|
|
|
@bounds
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_ty_region_param(item: ebml::Doc) -> Option<ty::region_variance> {
|
2012-12-06 18:13:54 -06:00
|
|
|
reader::maybe_get_doc(item, tag_region_param).map(|doc| {
|
2013-05-01 19:54:54 -05:00
|
|
|
let mut decoder = reader::Decoder(*doc);
|
|
|
|
Decodable::decode(&mut decoder)
|
2012-08-09 11:59:50 -05:00
|
|
|
})
|
2012-04-18 23:26:25 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_ty_param_count(item: ebml::Doc) -> uint {
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut n = 0u;
|
2012-12-06 18:13:54 -06:00
|
|
|
reader::tagged_docs(item, tag_items_data_item_ty_param_bounds,
|
2012-07-26 15:43:27 -05:00
|
|
|
|_p| { n += 1u; true } );
|
2011-12-16 07:41:12 -06:00
|
|
|
n
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn enum_variant_ids(item: ebml::Doc, cdata: cmd) -> ~[ast::def_id] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut ids: ~[ast::def_id] = ~[];
|
2011-07-27 07:19:39 -05:00
|
|
|
let v = tag_items_data_item_variant;
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, v) |p| {
|
2013-06-07 19:32:25 -05:00
|
|
|
let ext = reader::with_doc_data(p, parse_def_id);
|
2013-01-13 13:05:40 -06:00
|
|
|
ids.push(ast::def_id { crate: cdata.cnum, node: ext.node });
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-08-01 19:30:05 -05:00
|
|
|
return ids;
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:14:56 -05:00
|
|
|
fn item_path(item_doc: ebml::Doc) -> ast_map::path {
|
2012-12-06 18:13:54 -06:00
|
|
|
let path_doc = reader::get_doc(item_doc, tag_path);
|
2012-02-10 08:01:32 -06:00
|
|
|
|
2012-12-06 18:13:54 -06:00
|
|
|
let len_doc = reader::get_doc(path_doc, tag_path_len);
|
|
|
|
let len = reader::doc_as_u32(len_doc) as uint;
|
2012-02-10 08:01:32 -06:00
|
|
|
|
2012-09-21 20:43:30 -05:00
|
|
|
let mut result = vec::with_capacity(len);
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::docs(path_doc) |tag, elt_doc| {
|
2012-02-10 08:01:32 -06:00
|
|
|
if tag == tag_path_elt_mod {
|
2013-06-07 19:37:17 -05:00
|
|
|
let str = elt_doc.as_str_slice();
|
2013-06-04 14:34:25 -05:00
|
|
|
result.push(ast_map::path_mod(token::str_to_ident(str)));
|
2012-02-10 08:01:32 -06:00
|
|
|
} else if tag == tag_path_elt_name {
|
2013-06-07 19:37:17 -05:00
|
|
|
let str = elt_doc.as_str_slice();
|
2013-06-04 14:34:25 -05:00
|
|
|
result.push(ast_map::path_name(token::str_to_ident(str)));
|
2012-02-10 08:01:32 -06:00
|
|
|
} else {
|
|
|
|
// ignore tag_path_len element
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-01 19:30:05 -05:00
|
|
|
return result;
|
2012-02-10 08:01:32 -06:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_name(intr: @ident_interner, item: ebml::Doc) -> ast::ident {
|
2012-12-06 18:13:54 -06:00
|
|
|
let name = reader::get_doc(item, tag_paths_data_name);
|
2013-06-07 19:37:17 -05:00
|
|
|
let string = name.as_str_slice();
|
2013-06-12 12:02:55 -05:00
|
|
|
match intr.find_equiv(&string) {
|
2013-06-07 19:37:17 -05:00
|
|
|
None => token::str_to_ident(string),
|
|
|
|
Some(val) => ast::new_ident(val),
|
2013-04-02 18:20:02 -05:00
|
|
|
}
|
2011-12-16 07:41:12 -06:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_to_def_like(item: ebml::Doc, did: ast::def_id, cnum: ast::crate_num)
|
2013-05-16 17:37:52 -05:00
|
|
|
-> def_like {
|
2012-08-22 19:58:05 -05:00
|
|
|
let fam = item_family(item);
|
|
|
|
match fam {
|
2013-06-21 20:46:34 -05:00
|
|
|
ImmStatic => dl_def(ast::def_static(did, false)),
|
|
|
|
MutStatic => dl_def(ast::def_static(did, true)),
|
2012-12-10 15:47:54 -06:00
|
|
|
Struct => dl_def(ast::def_struct(did)),
|
2012-10-12 19:00:08 -05:00
|
|
|
UnsafeFn => dl_def(ast::def_fn(did, ast::unsafe_fn)),
|
|
|
|
Fn => dl_def(ast::def_fn(did, ast::impure_fn)),
|
|
|
|
ForeignFn => dl_def(ast::def_fn(did, ast::extern_fn)),
|
|
|
|
UnsafeStaticMethod => {
|
2012-10-18 15:29:34 -05:00
|
|
|
let trait_did_opt = translated_parent_item_opt(cnum, item);
|
|
|
|
dl_def(ast::def_static_method(did, trait_did_opt, ast::unsafe_fn))
|
2012-10-12 19:00:08 -05:00
|
|
|
}
|
|
|
|
StaticMethod => {
|
2012-10-18 15:29:34 -05:00
|
|
|
let trait_did_opt = translated_parent_item_opt(cnum, item);
|
|
|
|
dl_def(ast::def_static_method(did, trait_did_opt, ast::impure_fn))
|
2012-10-12 19:00:08 -05:00
|
|
|
}
|
|
|
|
Type | ForeignType => dl_def(ast::def_ty(did)),
|
|
|
|
Mod => dl_def(ast::def_mod(did)),
|
|
|
|
ForeignMod => dl_def(ast::def_foreign_mod(did)),
|
|
|
|
Variant => {
|
|
|
|
let enum_did = item_reqd_and_translated_parent_item(cnum, item);
|
|
|
|
dl_def(ast::def_variant(enum_did, did))
|
|
|
|
}
|
2013-03-27 09:26:57 -05:00
|
|
|
Trait => dl_def(ast::def_trait(did)),
|
|
|
|
Enum => dl_def(ast::def_ty(did)),
|
2012-10-12 19:00:08 -05:00
|
|
|
Impl => dl_impl(did),
|
|
|
|
PublicField | PrivateField | InheritedField => dl_field,
|
2012-02-13 13:55:23 -06:00
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn lookup_def(cnum: ast::crate_num, data: @~[u8], did_: ast::def_id) ->
|
2012-05-22 12:54:12 -05:00
|
|
|
ast::def {
|
|
|
|
let item = lookup_item(did_.node, data);
|
2013-01-13 13:05:40 -06:00
|
|
|
let did = ast::def_id { crate: cnum, node: did_.node };
|
2012-05-22 12:54:12 -05:00
|
|
|
// We treat references to enums as references to types.
|
2012-08-01 19:30:05 -05:00
|
|
|
return def_like_to_def(item_to_def_like(item, did, cnum));
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
|
|
|
|
2013-03-27 05:16:28 -05:00
|
|
|
pub fn get_trait_def(cdata: cmd,
|
|
|
|
item_id: ast::node_id,
|
|
|
|
tcx: ty::ctxt) -> ty::TraitDef
|
|
|
|
{
|
|
|
|
let item_doc = lookup_item(item_id, cdata.data);
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
let tp_defs = item_ty_param_defs(item_doc, tcx, cdata,
|
|
|
|
tag_items_data_item_ty_param_bounds);
|
2013-03-27 05:16:28 -05:00
|
|
|
let rp = item_ty_region_param(item_doc);
|
|
|
|
ty::TraitDef {
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
generics: ty::Generics {type_param_defs: tp_defs,
|
2013-03-27 05:16:28 -05:00
|
|
|
region_param: rp},
|
|
|
|
trait_ref: @item_trait_ref(item_doc, tcx, cdata)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_type(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
|
2012-01-05 09:04:59 -06:00
|
|
|
-> ty::ty_param_bounds_and_ty {
|
2012-04-18 23:26:25 -05:00
|
|
|
|
2012-01-05 09:04:59 -06:00
|
|
|
let item = lookup_item(id, cdata.data);
|
2013-01-13 13:05:40 -06:00
|
|
|
let t = item_type(ast::def_id { crate: cdata.cnum, node: id }, item, tcx,
|
|
|
|
cdata);
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
let tp_defs = if family_has_type_params(item_family(item)) {
|
|
|
|
item_ty_param_defs(item, tcx, cdata, tag_items_data_item_ty_param_bounds)
|
2012-06-29 18:26:56 -05:00
|
|
|
} else { @~[] };
|
2012-04-18 23:26:25 -05:00
|
|
|
let rp = item_ty_region_param(item);
|
2013-02-19 01:40:42 -06:00
|
|
|
ty::ty_param_bounds_and_ty {
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
generics: ty::Generics {type_param_defs: tp_defs,
|
2013-03-27 05:16:28 -05:00
|
|
|
region_param: rp},
|
2013-02-19 01:40:42 -06:00
|
|
|
ty: t
|
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_region_param(cdata: cmd, id: ast::node_id)
|
2012-08-20 14:23:37 -05:00
|
|
|
-> Option<ty::region_variance> {
|
2012-08-09 11:59:50 -05:00
|
|
|
|
2012-07-11 12:28:30 -05:00
|
|
|
let item = lookup_item(id, cdata.data);
|
2012-08-01 19:30:05 -05:00
|
|
|
return item_ty_region_param(item);
|
2012-07-11 12:28:30 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_type_param_count(data: @~[u8], id: ast::node_id) -> uint {
|
2011-12-16 07:41:12 -06:00
|
|
|
item_ty_param_count(lookup_item(id, data))
|
2011-07-29 18:40:23 -05:00
|
|
|
}
|
|
|
|
|
2013-05-16 17:54:51 -05:00
|
|
|
pub fn get_impl_trait(cdata: cmd,
|
2013-03-27 05:16:28 -05:00
|
|
|
id: ast::node_id,
|
2013-05-16 17:54:51 -05:00
|
|
|
tcx: ty::ctxt) -> Option<@ty::TraitRef>
|
2013-03-27 05:16:28 -05:00
|
|
|
{
|
|
|
|
let item_doc = lookup_item(id, cdata.data);
|
2013-06-07 19:24:11 -05:00
|
|
|
do reader::maybe_get_doc(item_doc, tag_item_trait_ref).map |&tp| {
|
|
|
|
@doc_trait_ref(tp, tcx, cdata)
|
|
|
|
}
|
2012-01-05 03:57:19 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_impl_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
2013-06-12 16:22:17 -05:00
|
|
|
name: ast::ident) -> Option<ast::def_id> {
|
2012-12-06 18:13:54 -06:00
|
|
|
let items = reader::get_doc(reader::Doc(cdata.data), tag_items);
|
2012-08-20 14:23:37 -05:00
|
|
|
let mut found = None;
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(find_item(id, items), tag_item_impl_method)
|
2012-11-24 15:38:23 -06:00
|
|
|
|mid| {
|
2013-06-07 19:32:25 -05:00
|
|
|
let m_did = reader::with_doc_data(mid, parse_def_id);
|
2012-11-24 15:38:23 -06:00
|
|
|
if item_name(intr, find_item(m_did.node, items)) == name {
|
|
|
|
found = Some(translate_def_id(cdata, m_did));
|
|
|
|
}
|
2012-03-08 05:15:02 -06:00
|
|
|
}
|
2013-06-12 16:22:17 -05:00
|
|
|
found
|
2012-03-08 05:15:02 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_symbol(data: @~[u8], id: ast::node_id) -> ~str {
|
2012-08-01 19:30:05 -05:00
|
|
|
return item_symbol(lookup_item(id, data));
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-05-22 12:54:12 -05:00
|
|
|
// Something that a name can resolve to.
|
2013-01-29 18:51:16 -06:00
|
|
|
pub enum def_like {
|
2012-05-22 12:54:12 -05:00
|
|
|
dl_def(ast::def),
|
|
|
|
dl_impl(ast::def_id),
|
|
|
|
dl_field
|
|
|
|
}
|
|
|
|
|
|
|
|
fn def_like_to_def(def_like: def_like) -> ast::def {
|
2012-08-06 14:34:08 -05:00
|
|
|
match def_like {
|
2012-08-03 21:59:04 -05:00
|
|
|
dl_def(def) => return def,
|
2013-05-05 17:18:51 -05:00
|
|
|
dl_impl(*) => fail!("found impl in def_like_to_def"),
|
|
|
|
dl_field => fail!("found field in def_like_to_def")
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-07 12:51:53 -06:00
|
|
|
/// Iterates over the language items in the given crate.
|
2013-05-03 12:08:08 -05:00
|
|
|
pub fn each_lang_item(cdata: cmd, f: &fn(ast::node_id, uint) -> bool) -> bool {
|
|
|
|
let root = reader::Doc(cdata.data);
|
|
|
|
let lang_items = reader::get_doc(root, tag_lang_items);
|
|
|
|
for reader::tagged_docs(lang_items, tag_lang_items_item) |item_doc| {
|
|
|
|
let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
|
|
|
|
let id = reader::doc_as_u32(id_doc) as uint;
|
|
|
|
let node_id_doc = reader::get_doc(item_doc,
|
|
|
|
tag_lang_items_item_node_id);
|
|
|
|
let node_id = reader::doc_as_u32(node_id_doc) as ast::node_id;
|
|
|
|
|
|
|
|
if !f(node_id, id) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2013-01-07 12:51:53 -06:00
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
struct EachItemContext<'self> {
|
|
|
|
intr: @ident_interner,
|
|
|
|
cdata: cmd,
|
|
|
|
get_crate_data: GetCrateDataCb<'self>,
|
|
|
|
path_builder: &'self mut ~str,
|
|
|
|
callback: &'self fn(&str, def_like, ast::visibility) -> bool,
|
|
|
|
}
|
2013-06-05 06:29:22 -05:00
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
impl<'self> EachItemContext<'self> {
|
|
|
|
// Pushes the given name and returns the old length.
|
|
|
|
fn push_name(&mut self, string: &str) -> uint {
|
|
|
|
let path_len = self.path_builder.len();
|
|
|
|
if path_len != 0 {
|
|
|
|
self.path_builder.push_str("::")
|
|
|
|
}
|
|
|
|
self.path_builder.push_str(string);
|
|
|
|
path_len
|
|
|
|
}
|
|
|
|
|
|
|
|
// Pops the given name.
|
|
|
|
fn pop_name(&mut self, old_len: uint) {
|
|
|
|
// XXX(pcwalton): There's no safe function to do this. :(
|
|
|
|
unsafe {
|
|
|
|
str::raw::set_len(self.path_builder, old_len)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn process_item_and_pop_name(&mut self,
|
|
|
|
doc: ebml::Doc,
|
|
|
|
def_id: ast::def_id,
|
|
|
|
old_len: uint)
|
|
|
|
-> bool {
|
|
|
|
let def_like = item_to_def_like(doc, def_id, self.cdata.cnum);
|
|
|
|
match def_like {
|
|
|
|
dl_def(def) => {
|
|
|
|
debug!("(iterating over each item of a module) processing \
|
|
|
|
`%s` (def %?)",
|
|
|
|
*self.path_builder,
|
|
|
|
def);
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
debug!("(iterating over each item of a module) processing \
|
|
|
|
`%s` (%d:%d)",
|
|
|
|
*self.path_builder,
|
|
|
|
def_id.crate,
|
|
|
|
def_id.node);
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
2013-06-05 06:29:22 -05:00
|
|
|
}
|
2012-07-03 20:30:11 -05:00
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
let vis = item_visibility(doc);
|
|
|
|
|
|
|
|
let mut continue = (self.callback)(*self.path_builder, def_like, vis);
|
|
|
|
|
|
|
|
let family = item_family(doc);
|
|
|
|
if family == ForeignMod {
|
|
|
|
// These are unnamed; pop the name now.
|
|
|
|
self.pop_name(old_len)
|
|
|
|
}
|
|
|
|
|
|
|
|
if continue {
|
|
|
|
// Recurse if necessary.
|
|
|
|
match family {
|
|
|
|
Mod | ForeignMod | Trait | Impl => {
|
|
|
|
continue = self.each_item_of_module(def_id);
|
|
|
|
}
|
2013-06-25 21:19:38 -05:00
|
|
|
ImmStatic | MutStatic | Struct | UnsafeFn | Fn | PureFn |
|
|
|
|
ForeignFn | UnsafeStaticMethod | StaticMethod |
|
|
|
|
PureStaticMethod | Type | ForeignType | Variant | Enum |
|
|
|
|
PublicField | PrivateField | InheritedField => {}
|
2013-06-18 11:39:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if family != ForeignMod {
|
|
|
|
self.pop_name(old_len)
|
|
|
|
}
|
|
|
|
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
fn each_item_of_module(&mut self, def_id: ast::def_id) -> bool {
|
|
|
|
// This item might not be in this crate. If it's not, look it up.
|
|
|
|
let (cdata, items) = if def_id.crate == self.cdata.cnum {
|
|
|
|
let items = reader::get_doc(reader::Doc(self.cdata.data),
|
|
|
|
tag_items);
|
|
|
|
(self.cdata, items)
|
|
|
|
} else {
|
|
|
|
let crate_data = (self.get_crate_data)(def_id.crate);
|
|
|
|
let root = reader::Doc(crate_data.data);
|
|
|
|
(crate_data, reader::get_doc(root, tag_items))
|
|
|
|
};
|
|
|
|
|
|
|
|
// Look up the item.
|
|
|
|
let item_doc = match maybe_find_item(def_id.node, items) {
|
|
|
|
None => return false,
|
|
|
|
Some(item_doc) => item_doc,
|
|
|
|
};
|
|
|
|
|
|
|
|
self.each_child_of_module_or_crate(item_doc)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn each_child_of_module_or_crate(&mut self, item_doc: ebml::Doc) -> bool {
|
|
|
|
let mut continue = true;
|
|
|
|
|
|
|
|
// Iterate over all children.
|
|
|
|
for reader::tagged_docs(item_doc, tag_mod_child) |child_info_doc| {
|
|
|
|
let child_def_id = reader::with_doc_data(child_info_doc,
|
|
|
|
parse_def_id);
|
|
|
|
let child_def_id = translate_def_id(self.cdata, child_def_id);
|
|
|
|
|
|
|
|
// This item may be in yet another crate, if it was the child of
|
|
|
|
// a reexport.
|
|
|
|
let other_crates_items = if child_def_id.crate ==
|
|
|
|
self.cdata.cnum {
|
|
|
|
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
2013-06-05 06:29:22 -05:00
|
|
|
} else {
|
2013-06-18 11:39:16 -05:00
|
|
|
let crate_data = (self.get_crate_data)(child_def_id.crate);
|
|
|
|
let root = reader::Doc(crate_data.data);
|
|
|
|
reader::get_doc(root, tag_items)
|
|
|
|
};
|
|
|
|
|
|
|
|
debug!("(iterating over each item of a module) looking up item \
|
|
|
|
%d:%d in `%s`, crate %d",
|
|
|
|
child_def_id.crate,
|
|
|
|
child_def_id.node,
|
|
|
|
*self.path_builder,
|
|
|
|
self.cdata.cnum);
|
|
|
|
|
|
|
|
// Get the item.
|
|
|
|
match maybe_find_item(child_def_id.node, other_crates_items) {
|
|
|
|
None => {}
|
|
|
|
Some(child_item_doc) => {
|
|
|
|
// Push the name.
|
|
|
|
let child_name = item_name(self.intr, child_item_doc);
|
|
|
|
debug!("(iterating over each item of a module) pushing \
|
|
|
|
name `%s` onto `%s`",
|
|
|
|
token::ident_to_str(&child_name),
|
|
|
|
*self.path_builder);
|
|
|
|
let old_len =
|
|
|
|
self.push_name(token::ident_to_str(&child_name));
|
|
|
|
|
|
|
|
// Process this item.
|
|
|
|
continue = self.process_item_and_pop_name(child_item_doc,
|
|
|
|
child_def_id,
|
|
|
|
old_len);
|
|
|
|
|
|
|
|
if !continue {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2013-06-05 06:29:22 -05:00
|
|
|
}
|
2013-06-18 11:39:16 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if !continue {
|
|
|
|
return false
|
|
|
|
}
|
2012-05-22 12:54:12 -05:00
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
// Iterate over reexports.
|
|
|
|
for each_reexport(item_doc) |reexport_doc| {
|
|
|
|
let def_id_doc = reader::get_doc(
|
|
|
|
reexport_doc,
|
|
|
|
tag_items_data_item_reexport_def_id);
|
|
|
|
let orig_def_id = reader::with_doc_data(def_id_doc, parse_def_id);
|
|
|
|
|
|
|
|
// NB: was "cdata"
|
|
|
|
let def_id = translate_def_id(self.cdata, orig_def_id);
|
|
|
|
|
|
|
|
let name_doc = reader::get_doc(reexport_doc,
|
|
|
|
tag_items_data_item_reexport_name);
|
|
|
|
let name = name_doc.as_str_slice();
|
|
|
|
|
|
|
|
// Push the name.
|
|
|
|
debug!("(iterating over each item of a module) pushing \
|
|
|
|
reexported name `%s` onto `%s` (crate %d, orig %d, \
|
|
|
|
in crate %d)",
|
|
|
|
name,
|
|
|
|
*self.path_builder,
|
|
|
|
def_id.crate,
|
|
|
|
orig_def_id.crate,
|
|
|
|
self.cdata.cnum);
|
|
|
|
let old_len = self.push_name(name);
|
|
|
|
|
|
|
|
// This reexport may be in yet another crate.
|
|
|
|
let other_crates_items = if def_id.crate == self.cdata.cnum {
|
|
|
|
reader::get_doc(reader::Doc(self.cdata.data), tag_items)
|
2013-06-05 06:29:22 -05:00
|
|
|
} else {
|
2013-06-18 11:39:16 -05:00
|
|
|
let crate_data = (self.get_crate_data)(def_id.crate);
|
2013-06-05 06:29:22 -05:00
|
|
|
let root = reader::Doc(crate_data.data);
|
|
|
|
reader::get_doc(root, tag_items)
|
|
|
|
};
|
|
|
|
|
|
|
|
// Get the item.
|
|
|
|
match maybe_find_item(def_id.node, other_crates_items) {
|
|
|
|
None => {}
|
2013-06-18 11:39:16 -05:00
|
|
|
Some(reexported_item_doc) => {
|
|
|
|
continue = self.process_item_and_pop_name(
|
|
|
|
reexported_item_doc,
|
|
|
|
def_id,
|
|
|
|
old_len);
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
|
|
|
}
|
2013-06-18 11:39:16 -05:00
|
|
|
|
|
|
|
if !continue {
|
|
|
|
break
|
|
|
|
}
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
2013-06-18 11:39:16 -05:00
|
|
|
|
|
|
|
continue
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
2013-06-18 11:39:16 -05:00
|
|
|
}
|
2012-07-09 19:43:36 -05:00
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
/// Iterates over all the paths in the given crate.
|
|
|
|
pub fn each_path(intr: @ident_interner,
|
|
|
|
cdata: cmd,
|
|
|
|
get_crate_data: GetCrateDataCb,
|
|
|
|
f: &fn(&str, def_like, ast::visibility) -> bool)
|
|
|
|
-> bool {
|
|
|
|
// FIXME #4572: This function needs to be nuked, as it's impossible to
|
|
|
|
// make fast. It's the source of most of the performance problems when
|
|
|
|
// compiling small crates.
|
|
|
|
|
|
|
|
let root_doc = reader::Doc(cdata.data);
|
|
|
|
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);
|
|
|
|
let crate_items_doc = reader::get_doc(misc_info_doc,
|
|
|
|
tag_misc_info_crate_items);
|
|
|
|
|
|
|
|
let mut path_builder = ~"";
|
|
|
|
|
|
|
|
let mut context = EachItemContext {
|
|
|
|
intr: intr,
|
|
|
|
cdata: cdata,
|
|
|
|
get_crate_data: get_crate_data,
|
|
|
|
path_builder: &mut path_builder,
|
|
|
|
callback: f,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Iterate over all top-level crate items.
|
|
|
|
context.each_child_of_module_or_crate(crate_items_doc)
|
2012-05-22 12:54:12 -05:00
|
|
|
}
|
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
pub fn get_item_path(cdata: cmd, id: ast::node_id) -> ast_map::path {
|
2013-06-04 17:14:56 -05:00
|
|
|
item_path(lookup_item(id, cdata.data))
|
2012-02-10 08:01:32 -06:00
|
|
|
}
|
|
|
|
|
2013-03-25 15:21:04 -05:00
|
|
|
pub type decode_inlined_item<'self> = &'self fn(
|
2013-02-19 01:40:42 -06:00
|
|
|
cdata: @cstore::crate_metadata,
|
2012-05-14 19:46:45 -05:00
|
|
|
tcx: ty::ctxt,
|
|
|
|
path: ast_map::path,
|
2012-10-07 18:33:20 -05:00
|
|
|
par_doc: ebml::Doc) -> Option<ast::inlined_item>;
|
2012-05-14 19:46:45 -05:00
|
|
|
|
2013-06-04 17:14:56 -05:00
|
|
|
pub fn maybe_get_item_ast(cdata: cmd, tcx: ty::ctxt,
|
2013-01-29 18:51:16 -06:00
|
|
|
id: ast::node_id,
|
|
|
|
decode_inlined_item: decode_inlined_item)
|
|
|
|
-> csearch::found_ast {
|
2012-08-22 19:24:52 -05:00
|
|
|
debug!("Looking up item: %d", id);
|
2012-02-14 17:21:53 -06:00
|
|
|
let item_doc = lookup_item(id, cdata.data);
|
2013-03-03 10:06:31 -06:00
|
|
|
let path = {
|
2013-06-04 17:14:56 -05:00
|
|
|
let item_path = item_path(item_doc);
|
2013-06-13 21:06:47 -05:00
|
|
|
vec::to_owned(item_path.init())
|
2013-03-03 10:06:31 -06:00
|
|
|
};
|
2013-03-10 10:02:16 -05:00
|
|
|
match decode_inlined_item(cdata, tcx, copy path, item_doc) {
|
2013-01-07 16:16:52 -06:00
|
|
|
Some(ref ii) => csearch::found((/*bad*/copy *ii)),
|
2012-08-20 14:23:37 -05:00
|
|
|
None => {
|
2012-08-06 14:34:08 -05:00
|
|
|
match item_parent_item(item_doc) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(did) => {
|
2012-03-08 16:13:57 -06:00
|
|
|
let did = translate_def_id(cdata, did);
|
|
|
|
let parent_item = lookup_item(did.node, cdata.data);
|
2013-03-03 10:06:31 -06:00
|
|
|
match decode_inlined_item(cdata, tcx, path, parent_item) {
|
2013-01-07 16:16:52 -06:00
|
|
|
Some(ref ii) => csearch::found_parent(did, (/*bad*/copy *ii)),
|
2012-08-20 14:23:37 -05:00
|
|
|
None => csearch::not_found
|
2012-03-08 16:13:57 -06:00
|
|
|
}
|
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
None => csearch::not_found
|
2012-03-08 16:13:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-02-14 17:21:53 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_enum_variants(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
2012-11-30 13:24:16 -06:00
|
|
|
tcx: ty::ctxt) -> ~[ty::VariantInfo] {
|
2012-01-05 09:04:59 -06:00
|
|
|
let data = cdata.data;
|
2012-12-06 18:13:54 -06:00
|
|
|
let items = reader::get_doc(reader::Doc(data), tag_items);
|
2012-01-05 09:04:59 -06:00
|
|
|
let item = find_item(id, items);
|
2012-11-30 13:24:16 -06:00
|
|
|
let mut infos: ~[ty::VariantInfo] = ~[];
|
2012-01-25 07:34:31 -06:00
|
|
|
let variant_ids = enum_variant_ids(item, cdata);
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut disr_val = 0;
|
2013-06-21 07:29:53 -05:00
|
|
|
for variant_ids.iter().advance |did| {
|
2011-07-27 07:19:39 -05:00
|
|
|
let item = find_item(did.node, items);
|
2013-01-13 13:05:40 -06:00
|
|
|
let ctor_ty = item_type(ast::def_id { crate: cdata.cnum, node: id},
|
|
|
|
item, tcx, cdata);
|
2012-07-18 18:18:02 -05:00
|
|
|
let name = item_name(intr, item);
|
2012-10-18 11:14:11 -05:00
|
|
|
let arg_tys = match ty::get(ctor_ty).sty {
|
2013-04-26 21:13:38 -05:00
|
|
|
ty::ty_bare_fn(ref f) => copy f.sig.inputs,
|
2013-01-31 19:12:29 -06:00
|
|
|
_ => ~[], // Nullary enum variant.
|
2012-10-18 11:14:11 -05:00
|
|
|
};
|
2012-08-06 14:34:08 -05:00
|
|
|
match variant_disr_val(item) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(val) => { disr_val = val; }
|
2012-08-03 21:59:04 -05:00
|
|
|
_ => { /* empty */ }
|
2012-01-10 15:50:40 -06:00
|
|
|
}
|
2012-11-30 13:24:16 -06:00
|
|
|
infos.push(@ty::VariantInfo_{args: arg_tys,
|
|
|
|
ctor_ty: ctor_ty, name: name,
|
|
|
|
// I'm not even sure if we encode visibility
|
|
|
|
// for variants -- TEST -- tjc
|
|
|
|
id: *did, disr_val: disr_val, vis: ast::inherited});
|
2012-01-10 15:50:40 -06:00
|
|
|
disr_val += 1;
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
2012-08-01 19:30:05 -05:00
|
|
|
return infos;
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2013-04-30 10:49:48 -05:00
|
|
|
fn get_explicit_self(item: ebml::Doc) -> ast::explicit_self_ {
|
2012-07-31 18:32:37 -05:00
|
|
|
fn get_mutability(ch: u8) -> ast::mutability {
|
2012-08-06 14:34:08 -05:00
|
|
|
match ch as char {
|
2012-07-31 18:32:37 -05:00
|
|
|
'i' => { ast::m_imm }
|
|
|
|
'm' => { ast::m_mutbl }
|
|
|
|
'c' => { ast::m_const }
|
|
|
|
_ => {
|
2013-05-05 17:18:51 -05:00
|
|
|
fail!("unknown mutability character: `%c`", ch as char)
|
2012-07-31 18:32:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-30 10:49:48 -05:00
|
|
|
let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self);
|
2013-06-07 19:37:17 -05:00
|
|
|
let string = explicit_self_doc.as_str_slice();
|
2012-07-31 18:32:37 -05:00
|
|
|
|
2013-04-30 10:49:48 -05:00
|
|
|
let explicit_self_kind = string[0];
|
|
|
|
match explicit_self_kind as char {
|
2012-08-02 18:01:38 -05:00
|
|
|
's' => { return ast::sty_static; }
|
2012-08-01 19:30:05 -05:00
|
|
|
'v' => { return ast::sty_value; }
|
|
|
|
'@' => { return ast::sty_box(get_mutability(string[1])); }
|
|
|
|
'~' => { return ast::sty_uniq(get_mutability(string[1])); }
|
2013-03-09 18:43:53 -06:00
|
|
|
'&' => {
|
|
|
|
// FIXME(#4846) expl. region
|
|
|
|
return ast::sty_region(None, get_mutability(string[1]));
|
|
|
|
}
|
2012-07-31 18:32:37 -05:00
|
|
|
_ => {
|
2013-04-30 10:49:48 -05:00
|
|
|
fail!("unknown self type code: `%c`", explicit_self_kind as char);
|
2012-07-31 18:32:37 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn item_impl_methods(intr: @ident_interner, cdata: cmd, item: ebml::Doc,
|
2013-02-19 01:40:42 -06:00
|
|
|
base_tps: uint) -> ~[@resolve::MethodInfo] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut rslt = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_impl_method) |doc| {
|
2013-06-07 19:32:25 -05:00
|
|
|
let m_did = reader::with_doc_data(doc, parse_def_id);
|
2012-01-11 10:11:56 -06:00
|
|
|
let mth_item = lookup_item(m_did.node, cdata.data);
|
2013-04-30 10:49:48 -05:00
|
|
|
let explicit_self = get_explicit_self(mth_item);
|
2013-02-19 01:40:42 -06:00
|
|
|
rslt.push(@resolve::MethodInfo {
|
|
|
|
did: translate_def_id(cdata, m_did),
|
|
|
|
n_tps: item_ty_param_count(mth_item) - base_tps,
|
|
|
|
ident: item_name(intr, mth_item),
|
2013-04-30 10:49:48 -05:00
|
|
|
explicit_self: explicit_self});
|
2011-12-16 07:41:12 -06:00
|
|
|
}
|
|
|
|
rslt
|
|
|
|
}
|
|
|
|
|
2013-06-18 11:39:16 -05:00
|
|
|
/// Returns information about the given implementation.
|
|
|
|
pub fn get_impl(intr: @ident_interner, cdata: cmd, impl_id: ast::node_id)
|
|
|
|
-> resolve::Impl {
|
2012-01-05 09:04:59 -06:00
|
|
|
let data = cdata.data;
|
2013-06-18 11:39:16 -05:00
|
|
|
let impl_item = lookup_item(impl_id, data);
|
|
|
|
let base_tps = item_ty_param_count(impl_item);
|
|
|
|
resolve::Impl {
|
|
|
|
did: ast::def_id {
|
|
|
|
crate: cdata.cnum,
|
|
|
|
node: impl_id,
|
|
|
|
},
|
|
|
|
ident: item_name(intr, impl_item),
|
|
|
|
methods: item_impl_methods(intr, cdata, impl_item, base_tps),
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-30 10:49:48 -05:00
|
|
|
pub fn get_method_name_and_explicit_self(
|
2013-03-27 09:26:57 -05:00
|
|
|
intr: @ident_interner,
|
|
|
|
cdata: cmd,
|
2013-04-30 10:49:48 -05:00
|
|
|
id: ast::node_id) -> (ast::ident, ast::explicit_self_)
|
2013-03-27 09:26:57 -05:00
|
|
|
{
|
|
|
|
let method_doc = lookup_item(id, cdata.data);
|
|
|
|
let name = item_name(intr, method_doc);
|
2013-04-30 10:49:48 -05:00
|
|
|
let explicit_self = get_explicit_self(method_doc);
|
|
|
|
(name, explicit_self)
|
2013-03-27 09:26:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_method(intr: @ident_interner, cdata: cmd, id: ast::node_id,
|
2013-05-02 10:11:15 -05:00
|
|
|
tcx: ty::ctxt) -> ty::Method
|
2013-03-27 09:26:57 -05:00
|
|
|
{
|
|
|
|
let method_doc = lookup_item(id, cdata.data);
|
2013-03-28 13:27:54 -05:00
|
|
|
let def_id = item_def_id(method_doc, cdata);
|
|
|
|
let name = item_name(intr, method_doc);
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
let type_param_defs = item_ty_param_defs(method_doc, tcx, cdata,
|
|
|
|
tag_item_method_tps);
|
2013-03-29 15:02:55 -05:00
|
|
|
let transformed_self_ty = doc_transformed_self_ty(method_doc, tcx, cdata);
|
2013-03-27 09:26:57 -05:00
|
|
|
let fty = doc_method_fty(method_doc, tcx, cdata);
|
2013-03-28 13:27:54 -05:00
|
|
|
let vis = item_visibility(method_doc);
|
2013-04-30 10:49:48 -05:00
|
|
|
let explicit_self = get_explicit_self(method_doc);
|
2013-05-02 10:11:15 -05:00
|
|
|
|
|
|
|
ty::Method::new(
|
|
|
|
name,
|
|
|
|
ty::Generics {
|
Cleanup substitutions and treatment of generics around traits in a number of ways.
- In a TraitRef, use the self type consistently to refer to the Self type:
- trait ref in `impl Trait<A,B,C> for S` has a self type of `S`.
- trait ref in `A:Trait` has the self type `A`
- trait ref associated with a trait decl has self type `Self`
- trait ref associated with a supertype has self type `Self`
- trait ref in an object type `@Trait` has no self type
- Rewrite `each_bound_traits_and_supertraits` to perform
substitutions as it goes, and thus yield a series of trait refs
that are always in the same 'namespace' as the type parameter
bound given as input. Before, we left this to the caller, but
this doesn't work because the caller lacks adequare information
to perform the type substitutions correctly.
- For provided methods, substitute the generics involved in the provided
method correctly.
- Introduce TypeParameterDef, which tracks the bounds declared on a type
parameter and brings them together with the def_id and (in the future)
other information (maybe even the parameter's name!).
- Introduce Subst trait, which helps to cleanup a lot of the
repetitive code involved with doing type substitution.
- Introduce Repr trait, which makes debug printouts far more convenient.
Fixes #4183. Needed for #5656.
2013-04-09 00:54:49 -05:00
|
|
|
type_param_defs: type_param_defs,
|
2013-03-27 05:16:28 -05:00
|
|
|
region_param: None
|
|
|
|
},
|
2013-05-02 10:11:15 -05:00
|
|
|
transformed_self_ty,
|
|
|
|
fty,
|
|
|
|
explicit_self,
|
|
|
|
vis,
|
|
|
|
def_id
|
|
|
|
)
|
2013-03-27 09:26:57 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn get_trait_method_def_ids(cdata: cmd,
|
|
|
|
id: ast::node_id) -> ~[ast::def_id] {
|
2012-01-05 09:04:59 -06:00
|
|
|
let data = cdata.data;
|
2012-03-15 08:47:03 -05:00
|
|
|
let item = lookup_item(id, data);
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_trait_method) |mth| {
|
2013-03-27 09:26:57 -05:00
|
|
|
result.push(item_def_id(mth, cdata));
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
2013-03-27 09:26:57 -05:00
|
|
|
result
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_provided_trait_methods(intr: @ident_interner, cdata: cmd,
|
|
|
|
id: ast::node_id, tcx: ty::ctxt) ->
|
2013-06-19 14:50:12 -05:00
|
|
|
~[@ty::Method] {
|
2012-10-08 14:39:30 -05:00
|
|
|
let data = cdata.data;
|
|
|
|
let item = lookup_item(id, data);
|
|
|
|
let mut result = ~[];
|
|
|
|
|
2013-06-12 16:22:17 -05:00
|
|
|
for reader::tagged_docs(item, tag_item_trait_method) |mth_id| {
|
|
|
|
let did = item_def_id(mth_id, cdata);
|
|
|
|
let mth = lookup_item(did.node, data);
|
2012-10-08 14:39:30 -05:00
|
|
|
|
2013-06-12 16:22:17 -05:00
|
|
|
if item_method_sort(mth) != 'p' { loop; }
|
2012-10-08 14:39:30 -05:00
|
|
|
|
2013-06-27 08:53:37 -05:00
|
|
|
result.push(@get_method(intr, cdata, did.node, tcx));
|
2012-10-08 14:39:30 -05:00
|
|
|
}
|
|
|
|
|
2013-02-15 03:14:34 -06:00
|
|
|
return result;
|
2012-10-08 14:39:30 -05:00
|
|
|
}
|
|
|
|
|
2012-10-19 23:27:01 -05:00
|
|
|
/// Returns the supertraits of the given trait.
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_supertraits(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
|
2013-03-27 05:16:28 -05:00
|
|
|
-> ~[@ty::TraitRef] {
|
2013-03-07 17:37:14 -06:00
|
|
|
let mut results = ~[];
|
2012-10-19 23:27:01 -05:00
|
|
|
let item_doc = lookup_item(id, cdata.data);
|
2013-03-27 05:16:28 -05:00
|
|
|
for reader::tagged_docs(item_doc, tag_item_super_trait_ref) |trait_doc| {
|
|
|
|
results.push(@doc_trait_ref(trait_doc, tcx, cdata));
|
2012-10-19 23:27:01 -05:00
|
|
|
}
|
2013-03-07 17:37:14 -06:00
|
|
|
return results;
|
2012-10-19 23:27:01 -05:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:14:56 -05:00
|
|
|
pub fn get_type_name_if_impl(cdata: cmd,
|
2013-01-29 18:51:16 -06:00
|
|
|
node_id: ast::node_id) -> Option<ast::ident> {
|
2012-10-18 15:29:34 -05:00
|
|
|
let item = lookup_item(node_id, cdata.data);
|
|
|
|
if item_family(item) != Impl {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_impl_type_basename) |doc| {
|
2013-06-07 19:37:17 -05:00
|
|
|
return Some(token::str_to_ident(doc.as_str_slice()));
|
2012-10-18 15:29:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_static_methods_if_impl(intr: @ident_interner,
|
|
|
|
cdata: cmd,
|
|
|
|
node_id: ast::node_id)
|
|
|
|
-> Option<~[StaticMethodInfo]> {
|
2012-10-18 15:29:34 -05:00
|
|
|
let item = lookup_item(node_id, cdata.data);
|
|
|
|
if item_family(item) != Impl {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2013-03-27 05:16:28 -05:00
|
|
|
// If this impl implements a trait, don't consider it.
|
|
|
|
for reader::tagged_docs(item, tag_item_trait_ref) |_doc| {
|
2012-10-18 15:29:34 -05:00
|
|
|
return None;
|
|
|
|
}
|
|
|
|
|
2013-03-07 17:37:14 -06:00
|
|
|
let mut impl_method_ids = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_impl_method) |impl_method_doc| {
|
2013-06-07 19:37:17 -05:00
|
|
|
impl_method_ids.push(reader::with_doc_data(impl_method_doc, parse_def_id));
|
2012-10-18 15:29:34 -05:00
|
|
|
}
|
|
|
|
|
2013-03-07 17:37:14 -06:00
|
|
|
let mut static_impl_methods = ~[];
|
2013-06-21 07:29:53 -05:00
|
|
|
for impl_method_ids.iter().advance |impl_method_id| {
|
2012-10-18 15:29:34 -05:00
|
|
|
let impl_method_doc = lookup_item(impl_method_id.node, cdata.data);
|
|
|
|
let family = item_family(impl_method_doc);
|
|
|
|
match family {
|
2013-06-21 17:10:23 -05:00
|
|
|
StaticMethod | UnsafeStaticMethod => {
|
2012-10-18 15:29:34 -05:00
|
|
|
let purity;
|
|
|
|
match item_family(impl_method_doc) {
|
|
|
|
StaticMethod => purity = ast::impure_fn,
|
|
|
|
UnsafeStaticMethod => purity = ast::unsafe_fn,
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => fail!()
|
2012-10-18 15:29:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
static_impl_methods.push(StaticMethodInfo {
|
|
|
|
ident: item_name(intr, impl_method_doc),
|
|
|
|
def_id: item_def_id(impl_method_doc, cdata),
|
|
|
|
purity: purity
|
|
|
|
});
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-07 17:37:14 -06:00
|
|
|
return Some(static_impl_methods);
|
2012-10-18 15:29:34 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_item_attrs(cdata: cmd,
|
|
|
|
node_id: ast::node_id,
|
2013-03-07 16:38:38 -06:00
|
|
|
f: &fn(~[@ast::meta_item])) {
|
2012-07-25 20:36:18 -05:00
|
|
|
|
|
|
|
let item = lookup_item(node_id, cdata.data);
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_attributes) |attributes| {
|
|
|
|
for reader::tagged_docs(attributes, tag_attribute) |attribute| {
|
2012-07-25 20:36:18 -05:00
|
|
|
f(get_meta_items(attribute));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-22 13:09:13 -05:00
|
|
|
fn struct_field_family_to_visibility(family: Family) -> ast::visibility {
|
2012-12-10 15:47:54 -06:00
|
|
|
match family {
|
|
|
|
PublicField => ast::public,
|
|
|
|
PrivateField => ast::private,
|
|
|
|
InheritedField => ast::inherited,
|
2013-02-11 21:26:38 -06:00
|
|
|
_ => fail!()
|
2012-12-10 15:47:54 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_struct_fields(intr: @ident_interner, cdata: cmd, id: ast::node_id)
|
2012-12-10 15:47:54 -06:00
|
|
|
-> ~[ty::field_ty] {
|
2012-03-06 10:02:13 -06:00
|
|
|
let data = cdata.data;
|
2012-03-15 08:47:03 -05:00
|
|
|
let item = lookup_item(id, data);
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut result = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_field) |an_item| {
|
2013-01-16 21:24:10 -06:00
|
|
|
let f = item_family(an_item);
|
|
|
|
if f == PublicField || f == PrivateField || f == InheritedField {
|
|
|
|
let name = item_name(intr, an_item);
|
|
|
|
let did = item_def_id(an_item, cdata);
|
|
|
|
result.push(ty::field_ty {
|
|
|
|
ident: name,
|
|
|
|
id: did, vis:
|
2013-02-27 15:45:37 -06:00
|
|
|
struct_field_family_to_visibility(f),
|
2013-01-16 21:24:10 -06:00
|
|
|
});
|
|
|
|
}
|
2012-03-06 10:02:13 -06:00
|
|
|
}
|
2013-02-11 18:28:39 -06:00
|
|
|
for reader::tagged_docs(item, tag_item_unnamed_field) |an_item| {
|
|
|
|
let did = item_def_id(an_item, cdata);
|
|
|
|
result.push(ty::field_ty {
|
|
|
|
ident: special_idents::unnamed_field,
|
|
|
|
id: did,
|
|
|
|
vis: ast::inherited,
|
|
|
|
});
|
|
|
|
}
|
2012-03-06 10:02:13 -06:00
|
|
|
result
|
|
|
|
}
|
|
|
|
|
2013-03-20 16:38:57 -05:00
|
|
|
pub fn get_item_visibility(cdata: cmd, id: ast::node_id)
|
|
|
|
-> ast::visibility {
|
2013-02-27 15:45:37 -06:00
|
|
|
item_visibility(lookup_item(id, cdata.data))
|
|
|
|
}
|
|
|
|
|
2012-08-22 19:58:05 -05:00
|
|
|
fn family_has_type_params(fam: Family) -> bool {
|
|
|
|
match fam {
|
2013-06-21 20:46:34 -05:00
|
|
|
ImmStatic | ForeignType | Mod | ForeignMod | PublicField | PrivateField
|
|
|
|
| ForeignFn | MutStatic => false,
|
2012-08-22 19:58:05 -05:00
|
|
|
_ => true
|
2012-01-05 06:57:27 -06:00
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:58:05 -05:00
|
|
|
fn family_names_type(fam: Family) -> bool {
|
|
|
|
match fam { Type | Mod | Trait => true, _ => false }
|
2011-12-19 06:52:58 -06:00
|
|
|
}
|
|
|
|
|
2013-02-19 01:40:42 -06:00
|
|
|
fn read_path(d: ebml::Doc) -> (~str, uint) {
|
2013-06-07 19:37:17 -05:00
|
|
|
do reader::with_doc_data(d) |desc| {
|
|
|
|
let pos = io::u64_from_be_bytes(desc, 0u, 4u) as uint;
|
|
|
|
let pathbytes = desc.slice(4u, desc.len());
|
|
|
|
let path = str::from_bytes(pathbytes);
|
2013-02-19 01:40:42 -06:00
|
|
|
|
2013-06-07 19:37:17 -05:00
|
|
|
(path, pos)
|
|
|
|
}
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn describe_def(items: ebml::Doc, id: ast::def_id) -> ~str {
|
2012-08-01 19:30:05 -05:00
|
|
|
if id.crate != ast::local_crate { return ~"external"; }
|
2012-08-06 14:34:08 -05:00
|
|
|
let it = match maybe_find_item(id.node, items) {
|
2012-08-20 14:23:37 -05:00
|
|
|
Some(it) => it,
|
2013-05-05 17:18:51 -05:00
|
|
|
None => fail!("describe_def: item not found %?", id)
|
2012-06-25 18:49:14 -05:00
|
|
|
};
|
2012-08-01 19:30:05 -05:00
|
|
|
return item_family_to_str(item_family(it));
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-08-22 19:58:05 -05:00
|
|
|
fn item_family_to_str(fam: Family) -> ~str {
|
|
|
|
match fam {
|
2013-06-21 20:46:34 -05:00
|
|
|
ImmStatic => ~"static",
|
|
|
|
MutStatic => ~"static mut",
|
2012-08-22 19:58:05 -05:00
|
|
|
Fn => ~"fn",
|
|
|
|
UnsafeFn => ~"unsafe fn",
|
|
|
|
StaticMethod => ~"static method",
|
|
|
|
UnsafeStaticMethod => ~"unsafe static method",
|
|
|
|
ForeignFn => ~"foreign fn",
|
|
|
|
Type => ~"type",
|
|
|
|
ForeignType => ~"foreign type",
|
|
|
|
Mod => ~"mod",
|
|
|
|
ForeignMod => ~"foreign mod",
|
|
|
|
Enum => ~"enum",
|
|
|
|
Variant => ~"variant",
|
|
|
|
Impl => ~"impl",
|
|
|
|
Trait => ~"trait",
|
|
|
|
Struct => ~"struct",
|
|
|
|
PublicField => ~"public field",
|
|
|
|
PrivateField => ~"private field",
|
|
|
|
InheritedField => ~"inherited field",
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn get_meta_items(md: ebml::Doc) -> ~[@ast::meta_item] {
|
2012-09-20 20:15:39 -05:00
|
|
|
let mut items: ~[@ast::meta_item] = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(md, tag_meta_item_word) |meta_item_doc| {
|
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
2013-06-12 12:02:55 -05:00
|
|
|
let n = nd.as_str_slice().to_managed();
|
|
|
|
items.push(attr::mk_word_item(n));
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(md, tag_meta_item_name_value) |meta_item_doc| {
|
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
|
|
|
let vd = reader::get_doc(meta_item_doc, tag_meta_item_value);
|
2013-06-12 12:02:55 -05:00
|
|
|
let n = nd.as_str_slice().to_managed();
|
|
|
|
let v = vd.as_str_slice().to_managed();
|
2012-05-17 18:17:11 -05:00
|
|
|
// FIXME (#623): Should be able to decode meta_name_value variants,
|
|
|
|
// but currently the encoder just drops them
|
2013-06-12 12:02:55 -05:00
|
|
|
items.push(attr::mk_name_value_item_str(n, v));
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(md, tag_meta_item_list) |meta_item_doc| {
|
|
|
|
let nd = reader::get_doc(meta_item_doc, tag_meta_item_name);
|
2013-06-12 12:02:55 -05:00
|
|
|
let n = nd.as_str_slice().to_managed();
|
2011-07-27 07:19:39 -05:00
|
|
|
let subitems = get_meta_items(meta_item_doc);
|
2013-06-12 12:02:55 -05:00
|
|
|
items.push(attr::mk_list_item(n, subitems));
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-08-01 19:30:05 -05:00
|
|
|
return items;
|
2011-06-27 20:32:15 -05:00
|
|
|
}
|
|
|
|
|
2012-10-07 18:33:20 -05:00
|
|
|
fn get_attributes(md: ebml::Doc) -> ~[ast::attribute] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut attrs: ~[ast::attribute] = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
match reader::maybe_get_doc(md, tag_attributes) {
|
2012-08-20 14:23:37 -05:00
|
|
|
option::Some(attrs_d) => {
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(attrs_d, tag_attribute) |attr_doc| {
|
2011-07-27 07:19:39 -05:00
|
|
|
let meta_items = get_meta_items(attr_doc);
|
|
|
|
// Currently it's only possible to have a single meta item on
|
|
|
|
// an attribute
|
2013-05-18 21:02:45 -05:00
|
|
|
assert_eq!(meta_items.len(), 1u);
|
2011-08-19 17:16:48 -05:00
|
|
|
let meta_item = meta_items[0];
|
2012-09-26 19:33:34 -05:00
|
|
|
attrs.push(
|
2013-01-30 11:56:33 -06:00
|
|
|
codemap::spanned {
|
2013-01-13 18:51:48 -06:00
|
|
|
node: ast::attribute_ {
|
|
|
|
style: ast::attr_outer,
|
2013-02-25 08:19:44 -06:00
|
|
|
value: meta_item,
|
2013-01-13 18:51:48 -06:00
|
|
|
is_sugared_doc: false,
|
|
|
|
},
|
2013-01-30 11:56:33 -06:00
|
|
|
span: codemap::dummy_sp()
|
2013-01-13 18:51:48 -06:00
|
|
|
});
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2011-07-27 07:19:39 -05:00
|
|
|
}
|
2012-08-20 14:23:37 -05:00
|
|
|
option::None => ()
|
2011-06-27 21:41:48 -05:00
|
|
|
}
|
2012-08-01 19:30:05 -05:00
|
|
|
return attrs;
|
2011-06-27 21:41:48 -05:00
|
|
|
}
|
|
|
|
|
2012-09-19 20:50:24 -05:00
|
|
|
fn list_meta_items(intr: @ident_interner,
|
2013-03-12 15:00:50 -05:00
|
|
|
meta_items: ebml::Doc,
|
|
|
|
out: @io::Writer) {
|
2013-06-21 07:29:53 -05:00
|
|
|
let r = get_meta_items(meta_items);
|
|
|
|
for r.iter().advance |mi| {
|
2012-09-19 18:55:01 -05:00
|
|
|
out.write_str(fmt!("%s\n", pprust::meta_item_to_str(*mi, intr)));
|
2011-06-27 20:32:15 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-02-16 12:16:32 -06:00
|
|
|
fn list_crate_attributes(intr: @ident_interner, md: ebml::Doc, hash: &str,
|
2013-03-12 15:00:50 -05:00
|
|
|
out: @io::Writer) {
|
2012-08-22 19:24:52 -05:00
|
|
|
out.write_str(fmt!("=Crate Attributes (%s)=\n", hash));
|
2011-06-27 21:41:48 -05:00
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let r = get_attributes(md);
|
|
|
|
for r.iter().advance |attr| {
|
2012-09-19 18:55:01 -05:00
|
|
|
out.write_str(fmt!("%s\n", pprust::attribute_to_str(*attr, intr)));
|
2011-06-27 21:41:48 -05:00
|
|
|
}
|
|
|
|
|
2013-05-19 00:07:44 -05:00
|
|
|
out.write_str("\n\n");
|
2011-06-27 20:32:15 -05:00
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn get_crate_attributes(data: @~[u8]) -> ~[ast::attribute] {
|
2012-12-06 18:13:54 -06:00
|
|
|
return get_attributes(reader::Doc(data));
|
2011-06-28 13:24:24 -05:00
|
|
|
}
|
|
|
|
|
2013-02-19 01:40:42 -06:00
|
|
|
pub struct crate_dep {
|
|
|
|
cnum: ast::crate_num,
|
|
|
|
name: ast::ident,
|
2013-06-12 12:02:55 -05:00
|
|
|
vers: @str,
|
|
|
|
hash: @str
|
2013-02-19 01:40:42 -06:00
|
|
|
}
|
2011-07-27 07:19:39 -05:00
|
|
|
|
2013-06-04 17:14:56 -05:00
|
|
|
pub fn get_crate_deps(data: @~[u8]) -> ~[crate_dep] {
|
2012-06-29 18:26:56 -05:00
|
|
|
let mut deps: ~[crate_dep] = ~[];
|
2012-12-06 18:13:54 -06:00
|
|
|
let cratedoc = reader::Doc(data);
|
|
|
|
let depsdoc = reader::get_doc(cratedoc, tag_crate_deps);
|
2012-03-15 08:47:03 -05:00
|
|
|
let mut crate_num = 1;
|
2013-06-12 12:02:55 -05:00
|
|
|
fn docstr(doc: ebml::Doc, tag_: uint) -> @str {
|
|
|
|
let d = reader::get_doc(doc, tag_);
|
|
|
|
d.as_str_slice().to_managed()
|
2012-04-07 12:59:37 -05:00
|
|
|
}
|
2012-12-06 18:13:54 -06:00
|
|
|
for reader::tagged_docs(depsdoc, tag_crate_dep) |depdoc| {
|
2013-02-19 01:40:42 -06:00
|
|
|
deps.push(crate_dep {cnum: crate_num,
|
2013-06-04 14:34:25 -05:00
|
|
|
name: token::str_to_ident(docstr(depdoc, tag_crate_dep_name)),
|
2013-06-12 12:02:55 -05:00
|
|
|
vers: docstr(depdoc, tag_crate_dep_vers),
|
|
|
|
hash: docstr(depdoc, tag_crate_dep_hash)});
|
2011-07-08 13:29:56 -05:00
|
|
|
crate_num += 1;
|
2011-10-21 05:31:48 -05:00
|
|
|
};
|
2012-08-01 19:30:05 -05:00
|
|
|
return deps;
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
|
|
|
|
2013-06-04 17:14:56 -05:00
|
|
|
fn list_crate_deps(data: @~[u8], out: @io::Writer) {
|
2013-05-19 00:07:44 -05:00
|
|
|
out.write_str("=External Dependencies=\n");
|
2011-07-08 13:29:56 -05:00
|
|
|
|
2013-06-21 07:29:53 -05:00
|
|
|
let r = get_crate_deps(data);
|
|
|
|
for r.iter().advance |dep| {
|
2012-07-18 18:18:02 -05:00
|
|
|
out.write_str(
|
2012-08-22 19:24:52 -05:00
|
|
|
fmt!("%d %s-%s-%s\n",
|
2013-06-12 12:02:55 -05:00
|
|
|
dep.cnum, token::ident_to_str(&dep.name), dep.hash, dep.vers));
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
|
|
|
|
2013-05-19 00:07:44 -05:00
|
|
|
out.write_str("\n");
|
2011-07-08 13:29:56 -05:00
|
|
|
}
|
|
|
|
|
2013-06-12 12:02:55 -05:00
|
|
|
pub fn get_crate_hash(data: @~[u8]) -> @str {
|
2012-12-06 18:13:54 -06:00
|
|
|
let cratedoc = reader::Doc(data);
|
|
|
|
let hashdoc = reader::get_doc(cratedoc, tag_crate_hash);
|
2013-06-12 12:02:55 -05:00
|
|
|
hashdoc.as_str_slice().to_managed()
|
2011-12-11 09:23:38 -06:00
|
|
|
}
|
|
|
|
|
2013-06-12 12:02:55 -05:00
|
|
|
pub fn get_crate_vers(data: @~[u8]) -> @str {
|
2012-04-07 12:59:37 -05:00
|
|
|
let attrs = decoder::get_crate_attributes(data);
|
2013-02-16 11:48:28 -06:00
|
|
|
let linkage_attrs = attr::find_linkage_metas(attrs);
|
|
|
|
|
2013-05-19 00:07:44 -05:00
|
|
|
match attr::last_meta_item_value_str_by_name(linkage_attrs, "vers") {
|
2013-02-16 12:16:32 -06:00
|
|
|
Some(ver) => ver,
|
2013-06-12 12:02:55 -05:00
|
|
|
None => @"0.0"
|
2013-02-16 11:48:28 -06:00
|
|
|
}
|
2012-04-07 12:59:37 -05:00
|
|
|
}
|
|
|
|
|
2012-11-08 18:52:21 -06:00
|
|
|
fn iter_crate_items(intr: @ident_interner, cdata: cmd,
|
|
|
|
get_crate_data: GetCrateDataCb,
|
2013-03-07 16:38:38 -06:00
|
|
|
proc: &fn(path: &str, ast::def_id)) {
|
2013-05-16 17:37:52 -05:00
|
|
|
for each_path(intr, cdata, get_crate_data) |path_string, def_like, _| {
|
2013-01-21 22:32:13 -06:00
|
|
|
match def_like {
|
2012-08-17 16:54:28 -05:00
|
|
|
dl_impl(*) | dl_field => {}
|
|
|
|
dl_def(def) => {
|
2013-01-21 22:32:13 -06:00
|
|
|
proc(path_string,
|
2013-01-07 16:16:52 -06:00
|
|
|
ast_util::def_id_of_def(def))
|
2012-08-17 16:54:28 -05:00
|
|
|
}
|
|
|
|
}
|
2012-01-20 12:45:25 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn list_crate_metadata(intr: @ident_interner, bytes: @~[u8],
|
2013-03-12 15:00:50 -05:00
|
|
|
out: @io::Writer) {
|
2011-12-11 09:23:38 -06:00
|
|
|
let hash = get_crate_hash(bytes);
|
2012-12-06 18:13:54 -06:00
|
|
|
let md = reader::Doc(bytes);
|
2013-06-12 12:02:55 -05:00
|
|
|
list_crate_attributes(intr, md, hash, out);
|
2013-06-04 17:14:56 -05:00
|
|
|
list_crate_deps(bytes, out);
|
2011-06-27 17:53:27 -05:00
|
|
|
}
|
|
|
|
|
2012-01-05 09:04:59 -06:00
|
|
|
// Translates a def_id from an external crate to a def_id for the current
|
|
|
|
// compilation environment. We use this when trying to load types from
|
|
|
|
// external crates - if those types further refer to types in other crates
|
|
|
|
// then we must translate the crate number from that encoded in the external
|
|
|
|
// crate to the correct local crate number.
|
2013-01-29 18:51:16 -06:00
|
|
|
pub fn translate_def_id(cdata: cmd, did: ast::def_id) -> ast::def_id {
|
2012-01-05 09:04:59 -06:00
|
|
|
if did.crate == ast::local_crate {
|
2013-01-13 13:05:40 -06:00
|
|
|
return ast::def_id { crate: cdata.cnum, node: did.node };
|
2012-01-05 09:04:59 -06:00
|
|
|
}
|
|
|
|
|
2013-02-05 21:41:45 -06:00
|
|
|
match cdata.cnum_map.find(&did.crate) {
|
2013-03-22 21:26:41 -05:00
|
|
|
option::Some(&n) => ast::def_id { crate: n, node: did.node },
|
2013-05-05 17:18:51 -05:00
|
|
|
option::None => fail!("didn't find a crate in the cnum_map")
|
2012-01-05 09:04:59 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-07 00:06:53 -06:00
|
|
|
pub fn get_link_args_for_crate(cdata: cmd) -> ~[~str] {
|
|
|
|
let link_args = reader::get_doc(reader::Doc(cdata.data), tag_link_args);
|
|
|
|
let mut result = ~[];
|
|
|
|
for reader::tagged_docs(link_args, tag_link_args_arg) |arg_doc| {
|
2013-06-07 19:37:17 -05:00
|
|
|
result.push(arg_doc.as_str());
|
2013-03-07 00:06:53 -06:00
|
|
|
}
|
|
|
|
result
|
|
|
|
}
|