use syntax::parse;
use syntax::parse::token::InternedString;
use syntax::visit;
+use syntax::util::small_vector::SmallVector;
use ast_map;
use log;
let cmeta = Rc::new( cstore::crate_metadata {
name: name.to_string(),
+ local_path: RefCell::new(SmallVector::zero()),
data: metadata,
cnum_map: cnum_map,
cnum: cnum,
match self.creader.extract_crate_info(i) {
Some(info) => {
- let (cnum, _, _) = self.creader.resolve_crate(&None,
+ let (cnum, cmeta, _) = self.creader.resolve_crate(&None,
&info.ident,
&info.name,
None,
i.span,
PathKind::Crate);
+ self.ast_map.with_path(i.id, |path|
+ cmeta.update_local_path(path));
self.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
}
None => ()
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::expect;
-use syntax::parse::token;
use std::collections::hash_map::HashMap;
let cdata = cstore.get_crate_data(def.krate);
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.
- let mut r = vec![ast_map::PathMod(token::intern(&cdata.name))];
- r.push_all(&path);
- r
+ cdata.with_local_path(|cpath| {
+ let mut r = Vec::with_capacity(cpath.len() + path.len());
+ r.push_all(cpath);
+ r.push_all(&path);
+ r
+ })
}
pub enum FoundAst<'ast> {
use flate::Bytes;
use syntax::ast;
use syntax::codemap;
+use syntax::parse::token;
use syntax::parse::token::IdentInterner;
+use syntax::util::small_vector::SmallVector;
+use ast_map;
// A map from external crate numbers (as decoded from some crate file) to
// local crate numbers (as generated during this session). Each external
pub struct crate_metadata {
pub name: String,
+ pub local_path: RefCell<SmallVector<ast_map::PathElem>>,
pub data: MetadataBlob,
pub cnum_map: cnum_map,
pub cnum: ast::CrateNum,
filemaps
}
}
+ pub fn with_local_path<T, F>(&self, f: F) -> T
+ where F: Fn(&[ast_map::PathElem]) -> T {
+ let cpath = self.local_path.borrow();
+ if cpath.is_empty() {
+ let name = ast_map::PathMod(token::intern(&self.name));
+ f(&[name])
+ } else {
+ f(cpath.as_slice())
+ }
+ }
+ pub fn update_local_path<'a, 'b>(&self, candidate: ast_map::PathElems<'a, 'b>) {
+ let mut cpath = self.local_path.borrow_mut();
+ let cap = cpath.len();
+ match cap {
+ 0 => *cpath = candidate.collect(),
+ 1 => (),
+ _ => {
+ let candidate: SmallVector<_> = candidate.collect();
+ if candidate.len() < cap {
+ *cpath = candidate;
+ }
+ },
+ }
+ }
}
impl MetadataBlob {