Store and use crate-local paths to extern crates

This commit is contained in:
mitaa 2015-08-01 16:14:45 +02:00
parent a98fd11228
commit 2b4124684e
3 changed files with 39 additions and 7 deletions

View file

@ -34,6 +34,7 @@ use syntax::codemap::{self, Span, mk_sp, Pos};
use syntax::parse;
use syntax::parse::token::InternedString;
use syntax::visit;
use syntax::util::small_vector::SmallVector;
use ast_map;
use log;
@ -263,6 +264,7 @@ impl<'a> CrateReader<'a> {
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,
@ -520,12 +522,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
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 => ()

View file

@ -24,7 +24,6 @@ use syntax::ast;
use syntax::attr;
use syntax::attr::AttrMetaMethods;
use syntax::diagnostic::expect;
use syntax::parse::token;
use std::collections::hash_map::HashMap;
@ -89,11 +88,12 @@ pub fn get_item_path(tcx: &ty::ctxt, def: ast::DefId) -> Vec<ast_map::PathElem>
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> {

View file

@ -28,7 +28,10 @@ use std::path::PathBuf;
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
@ -54,6 +57,7 @@ pub struct ImportedFileMap {
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,
@ -255,6 +259,30 @@ impl crate_metadata {
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 {