Store and use crate-local paths to extern crates
This commit is contained in:
parent
a98fd11228
commit
2b4124684e
3 changed files with 39 additions and 7 deletions
|
|
@ -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 => ()
|
||||
|
|
|
|||
|
|
@ -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> {
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue