summary refs log tree commit diff
path: root/src/rustc/metadata/csearch.rs
blob: 03b3fdcba86fb43187b44eadb8b1e234d2309b03 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
// Searching for information from the cstore

import std::{ebml};
import syntax::ast;
import syntax::ast_util;
import syntax::ast_map;
import middle::ty;
import option::{some, none};
import syntax::diagnostic::span_handler;
import syntax::diagnostic::expect;
import common::*;
import std::map::hashmap;

export class_dtor;
export get_symbol;
export get_class_fields;
export get_class_method;
export get_field_type;
export get_type_param_count;
export lookup_defs;
export lookup_method_purity;
export get_enum_variants;
export get_impls_for_mod;
export get_trait_methods;
export each_path;
export get_type;
export get_impl_trait;
export get_impl_method;
export get_item_path;
export maybe_get_item_ast, found_ast, found, found_parent, not_found;

fn get_symbol(cstore: cstore::cstore, def: ast::def_id) -> str {
    let cdata = cstore::get_crate_data(cstore, def.crate).data;
    ret decoder::get_symbol(cdata, def.node);
}

fn get_type_param_count(cstore: cstore::cstore, def: ast::def_id) -> uint {
    let cdata = cstore::get_crate_data(cstore, def.crate).data;
    ret decoder::get_type_param_count(cdata, def.node);
}

fn lookup_defs(cstore: cstore::cstore, cnum: ast::crate_num,
               path: ~[ast::ident]) -> ~[ast::def] {
    let mut result = ~[];
    #debug("lookup_defs: path = %? cnum = %?", path, cnum);
    for resolve_path(cstore, cnum, path).each |elt| {
        let (c, data, def) = elt;
        vec::push(result, decoder::lookup_def(c, data, def));
    }
    ret result;
}

fn lookup_method_purity(cstore: cstore::cstore, did: ast::def_id)
    -> ast::purity {
    let cdata = cstore::get_crate_data(cstore, did.crate).data;
    alt check decoder::lookup_def(did.crate, cdata, did) {
      ast::def_fn(_, p) { p }
    }
}

/* Returns a vector of possible def IDs for a given path,
   in a given crate */
fn resolve_path(cstore: cstore::cstore, cnum: ast::crate_num,
                path: ~[ast::ident]) ->
    ~[(ast::crate_num, @~[u8], ast::def_id)] {
    let cm = cstore::get_crate_data(cstore, cnum);
    #debug("resolve_path %s in crates[%d]:%s",
           ast_util::path_name_i(path), cnum, cm.name);
    let mut result = ~[];
    for decoder::resolve_path(path, cm.data).each |def| {
        if def.crate == ast::local_crate {
            vec::push(result, (cnum, cm.data, def));
        } else {
            if cm.cnum_map.contains_key(def.crate) {
                // This reexport is itself a reexport from another crate
                let next_cnum = cm.cnum_map.get(def.crate);
                let next_cm_data = cstore::get_crate_data(cstore, next_cnum);
                vec::push(result, (next_cnum, next_cm_data.data, def));
            }
        }
    }
    ret result;
}

/// Iterates over all the paths in the given crate.
fn each_path(cstore: cstore::cstore, cnum: ast::crate_num,
             f: fn(decoder::path_entry) -> bool) {
    let crate_data = cstore::get_crate_data(cstore, cnum);
    decoder::each_path(crate_data, f);
}

fn get_item_path(tcx: ty::ctxt, def: ast::def_id) -> ast_map::path {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    let path = decoder::get_item_path(cdata, def.node);

    // FIXME #1920: This path is not always correct if the crate is not linked
    // into the root namespace.
    vec::append(~[ast_map::path_mod(@cdata.name)], path)
}

enum found_ast {
    found(ast::inlined_item),
    found_parent(ast::def_id, ast::inlined_item),
    not_found,
}

// Finds the AST for this item in the crate metadata, if any.  If the item was
// not marked for inlining, then the AST will not be present and hence none
// will be returned.
fn maybe_get_item_ast(tcx: ty::ctxt, def: ast::def_id,
                      decode_inlined_item: decoder::decode_inlined_item)
    -> found_ast {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::maybe_get_item_ast(cdata, tcx, def.node,
                                decode_inlined_item)
}

fn get_enum_variants(tcx: ty::ctxt, def: ast::def_id)
    -> ~[ty::variant_info] {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    ret decoder::get_enum_variants(cdata, def.node, tcx)
}

fn get_impls_for_mod(cstore: cstore::cstore, def: ast::def_id,
                     name: option<ast::ident>)
    -> @~[@decoder::_impl] {
    let cdata = cstore::get_crate_data(cstore, def.crate);
    do decoder::get_impls_for_mod(cdata, def.node, name) |cnum| {
        cstore::get_crate_data(cstore, cnum)
    }
}

fn get_trait_methods(tcx: ty::ctxt, def: ast::def_id) -> @~[ty::method] {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_trait_methods(cdata, def.node, tcx)
}

fn get_class_fields(tcx: ty::ctxt, def: ast::def_id) -> ~[ty::field_ty] {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_class_fields(cdata, def.node)
}

fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_type(cdata, def.node, tcx)
}

fn get_field_type(tcx: ty::ctxt, class_id: ast::def_id,
                  def: ast::def_id) -> ty::ty_param_bounds_and_ty {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, class_id.crate);
    let all_items = ebml::get_doc(ebml::doc(cdata.data), tag_items);
    #debug("Looking up %?", class_id);
    let class_doc = expect(tcx.diag,
                           decoder::maybe_find_item(class_id.node, all_items),
                           || #fmt("get_field_type: class ID %? not found",
                                   class_id) );
    #debug("looking up %? : %?", def, class_doc);
    let the_field = expect(tcx.diag,
        decoder::maybe_find_item(def.node, class_doc),
        || #fmt("get_field_type: in class %?, field ID %? not found",
                 class_id, def) );
    #debug("got field data %?", the_field);
    let ty = decoder::item_type(def, the_field, tcx, cdata);
    ret {bounds: @~[], rp: ast::rp_none, ty: ty};
}

// Given a def_id for an impl or class, return the trait it implements,
// or none if it's not for an impl or for a class that implements traits
fn get_impl_trait(tcx: ty::ctxt, def: ast::def_id) -> option<ty::t> {
    let cstore = tcx.cstore;
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_impl_trait(cdata, def.node, tcx)
}

fn get_impl_method(cstore: cstore::cstore,
                   def: ast::def_id, mname: ast::ident)
    -> ast::def_id {
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_impl_method(cdata, def.node, mname)
}

/* Because classes use the trait format rather than the impl format
   for their methods (so that get_trait_methods can be reused to get
   class methods), classes require a slightly different version of
   get_impl_method. Sigh. */
fn get_class_method(cstore: cstore::cstore,
                    def: ast::def_id, mname: ast::ident)
    -> ast::def_id {
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::get_class_method(cdata, def.node, mname)
}

/* If def names a class with a dtor, return it. Otherwise, return none. */
fn class_dtor(cstore: cstore::cstore, def: ast::def_id)
    -> option<ast::def_id> {
    let cdata = cstore::get_crate_data(cstore, def.crate);
    decoder::class_dtor(cdata, def.node)
}
// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// End: