rustc: Simplify crate loading constraints
The previous code passed around a {name,version} pair everywhere, but this is better expressed as a CrateId. This patch changes these paths to store and pass around crate ids instead of these pairs of name/version. This also prepares the code to change the type of hash that is stored in crates.
This commit is contained in:
parent
9b1be3d182
commit
8213e18447
|
@ -70,12 +70,12 @@ pub static tag_crate_deps: uint = 0x18;
|
|||
pub static tag_crate_dep: uint = 0x19;
|
||||
|
||||
pub static tag_crate_hash: uint = 0x1a;
|
||||
pub static tag_crate_crateid: uint = 0x1b;
|
||||
|
||||
pub static tag_parent_item: uint = 0x1b;
|
||||
pub static tag_parent_item: uint = 0x1c;
|
||||
|
||||
pub static tag_crate_dep_name: uint = 0x1c;
|
||||
pub static tag_crate_dep_hash: uint = 0x1d;
|
||||
pub static tag_crate_dep_vers: uint = 0x1e;
|
||||
pub static tag_crate_dep_crateid: uint = 0x1d;
|
||||
pub static tag_crate_dep_hash: uint = 0x1e;
|
||||
|
||||
pub static tag_mod_impl: uint = 0x1f;
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ struct cache_entry {
|
|||
cnum: ast::CrateNum,
|
||||
span: Span,
|
||||
hash: ~str,
|
||||
crateid: CrateId,
|
||||
crate_id: CrateId,
|
||||
}
|
||||
|
||||
fn dump_crates(crate_cache: &[cache_entry]) {
|
||||
|
@ -95,10 +95,10 @@ fn warn_if_multiple_versions(e: &mut Env,
|
|||
diag: @SpanHandler,
|
||||
crate_cache: &[cache_entry]) {
|
||||
if crate_cache.len() != 0u {
|
||||
let name = crate_cache[crate_cache.len() - 1].crateid.name.clone();
|
||||
let name = crate_cache[crate_cache.len() - 1].crate_id.name.clone();
|
||||
|
||||
let (matches, non_matches) = crate_cache.partitioned(|entry|
|
||||
name == entry.crateid.name);
|
||||
name == entry.crate_id.name);
|
||||
|
||||
assert!(!matches.is_empty());
|
||||
|
||||
|
@ -107,7 +107,7 @@ fn warn_if_multiple_versions(e: &mut Env,
|
|||
format!("using multiple versions of crate `{}`", name));
|
||||
for match_ in matches.iter() {
|
||||
diag.span_note(match_.span, "used here");
|
||||
loader::note_crateid_attr(diag, &match_.crateid);
|
||||
loader::note_crateid_attr(diag, &match_.crate_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,14 +146,9 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
|||
return;
|
||||
}
|
||||
|
||||
match extract_crate_info(i) {
|
||||
match extract_crate_info(e, i) {
|
||||
Some(info) => {
|
||||
let cnum = resolve_crate(e,
|
||||
None,
|
||||
info.ident.clone(),
|
||||
info.name.clone(),
|
||||
info.version.clone(),
|
||||
~"",
|
||||
let cnum = resolve_crate(e, None, info.ident, &info.crate_id, "",
|
||||
i.span);
|
||||
e.sess.cstore.add_extern_mod_stmt_cnum(info.id, cnum);
|
||||
}
|
||||
|
@ -163,38 +158,33 @@ fn visit_view_item(e: &mut Env, i: &ast::ViewItem) {
|
|||
|
||||
struct CrateInfo {
|
||||
ident: ~str,
|
||||
name: ~str,
|
||||
version: ~str,
|
||||
crate_id: CrateId,
|
||||
id: ast::NodeId,
|
||||
}
|
||||
|
||||
fn extract_crate_info(i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
|
||||
match i.node {
|
||||
ast::ViewItemExternMod(ident, ref path_opt, id) => {
|
||||
let ident = token::get_ident(ident);
|
||||
debug!("resolving extern crate stmt. ident: {:?} path_opt: {:?}",
|
||||
ident, path_opt);
|
||||
let (name, version) = match *path_opt {
|
||||
let crate_id = match *path_opt {
|
||||
Some((ref path_str, _)) => {
|
||||
let crateid: Option<CrateId> = from_str(path_str.get());
|
||||
match crateid {
|
||||
None => (~"", ~""),
|
||||
Some(crateid) => {
|
||||
let version = match crateid.version {
|
||||
None => ~"",
|
||||
Some(ref ver) => ver.to_str(),
|
||||
};
|
||||
(crateid.name.to_str(), version)
|
||||
None => {
|
||||
e.sess.span_err(i.span, "malformed crate id");
|
||||
return None
|
||||
}
|
||||
Some(id) => id
|
||||
}
|
||||
}
|
||||
None => (ident.get().to_str(), ~""),
|
||||
None => from_str(ident.get().to_str()).unwrap()
|
||||
};
|
||||
Some(CrateInfo {
|
||||
ident: ident.get().to_str(),
|
||||
name: name,
|
||||
version: version,
|
||||
id: id,
|
||||
ident: ident.get().to_str(),
|
||||
crate_id: crate_id,
|
||||
id: id,
|
||||
})
|
||||
}
|
||||
_ => None
|
||||
|
@ -285,100 +275,93 @@ fn visit_item(e: &Env, i: &ast::Item) {
|
|||
}
|
||||
}
|
||||
|
||||
fn existing_match(e: &Env, name: &str, version: &str, hash: &str) -> Option<ast::CrateNum> {
|
||||
fn existing_match(e: &Env, crate_id: &CrateId,
|
||||
hash: &str) -> Option<ast::CrateNum> {
|
||||
let crate_cache = e.crate_cache.borrow();
|
||||
for c in crate_cache.get().iter() {
|
||||
let crateid_version = match c.crateid.version {
|
||||
None => ~"0.0",
|
||||
Some(ref ver) => ver.to_str(),
|
||||
};
|
||||
if (name.is_empty() || name == c.crateid.name) &&
|
||||
(version.is_empty() || version == crateid_version) &&
|
||||
(hash.is_empty() || hash == c.hash) {
|
||||
return Some(c.cnum);
|
||||
if crate_id.matches(&c.crate_id) &&
|
||||
(hash.is_empty() || hash == c.hash.as_slice()) {
|
||||
return Some(c.cnum)
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
fn resolve_crate(e: &mut Env,
|
||||
root_ident: Option<~str>,
|
||||
ident: ~str,
|
||||
name: ~str,
|
||||
version: ~str,
|
||||
hash: ~str,
|
||||
root_ident: Option<&str>,
|
||||
ident: &str,
|
||||
crate_id: &CrateId,
|
||||
hash: &str,
|
||||
span: Span)
|
||||
-> ast::CrateNum {
|
||||
match existing_match(e, name, version, hash) {
|
||||
None => {
|
||||
let load_ctxt = loader::Context {
|
||||
sess: e.sess,
|
||||
span: span,
|
||||
ident: ident,
|
||||
name: name,
|
||||
version: version,
|
||||
hash: hash,
|
||||
os: e.os,
|
||||
intr: e.intr
|
||||
};
|
||||
let loader::Library {
|
||||
dylib, rlib, metadata
|
||||
} = load_ctxt.load_library_crate(root_ident.clone());
|
||||
|
||||
let attrs = decoder::get_crate_attributes(metadata.as_slice());
|
||||
let crateid = attr::find_crateid(attrs).unwrap();
|
||||
let hash = decoder::get_crate_hash(metadata.as_slice());
|
||||
|
||||
// Claim this crate number and cache it
|
||||
let cnum = e.next_crate_num;
|
||||
{
|
||||
let mut crate_cache = e.crate_cache.borrow_mut();
|
||||
crate_cache.get().push(cache_entry {
|
||||
cnum: cnum,
|
||||
match existing_match(e, crate_id, hash) {
|
||||
None => {
|
||||
let load_ctxt = loader::Context {
|
||||
sess: e.sess,
|
||||
span: span,
|
||||
ident: ident,
|
||||
crate_id: crate_id,
|
||||
hash: hash,
|
||||
crateid: crateid,
|
||||
os: e.os,
|
||||
intr: e.intr
|
||||
};
|
||||
let loader::Library {
|
||||
dylib, rlib, metadata
|
||||
} = load_ctxt.load_library_crate(root_ident);
|
||||
|
||||
let crate_id = decoder::get_crate_id(metadata.as_slice());
|
||||
let hash = decoder::get_crate_hash(metadata.as_slice());
|
||||
|
||||
// Claim this crate number and cache it
|
||||
let cnum = e.next_crate_num;
|
||||
{
|
||||
let mut crate_cache = e.crate_cache.borrow_mut();
|
||||
crate_cache.get().push(cache_entry {
|
||||
cnum: cnum,
|
||||
span: span,
|
||||
hash: hash,
|
||||
crate_id: crate_id,
|
||||
});
|
||||
}
|
||||
e.next_crate_num += 1;
|
||||
|
||||
// Maintain a reference to the top most crate.
|
||||
let root_crate = match root_ident {
|
||||
Some(c) => c,
|
||||
None => load_ctxt.ident.clone()
|
||||
};
|
||||
|
||||
// Now resolve the crates referenced by this crate
|
||||
let cnum_map = resolve_crate_deps(e,
|
||||
Some(root_crate),
|
||||
metadata.as_slice(),
|
||||
span);
|
||||
|
||||
let cmeta = @cstore::crate_metadata {
|
||||
name: load_ctxt.crate_id.name.to_owned(),
|
||||
data: metadata,
|
||||
cnum_map: cnum_map,
|
||||
cnum: cnum
|
||||
};
|
||||
|
||||
let cstore = e.sess.cstore;
|
||||
cstore.set_crate_data(cnum, cmeta);
|
||||
cstore.add_used_crate_source(cstore::CrateSource {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
cnum: cnum,
|
||||
});
|
||||
return cnum;
|
||||
}
|
||||
Some(cnum) => {
|
||||
return cnum;
|
||||
}
|
||||
e.next_crate_num += 1;
|
||||
|
||||
// Maintain a reference to the top most crate.
|
||||
let root_crate = match root_ident {
|
||||
Some(c) => c,
|
||||
None => load_ctxt.ident.clone()
|
||||
};
|
||||
|
||||
// Now resolve the crates referenced by this crate
|
||||
let cnum_map = resolve_crate_deps(e,
|
||||
Some(root_crate),
|
||||
metadata.as_slice(),
|
||||
span);
|
||||
|
||||
let cmeta = @cstore::crate_metadata {
|
||||
name: load_ctxt.name,
|
||||
data: metadata,
|
||||
cnum_map: cnum_map,
|
||||
cnum: cnum
|
||||
};
|
||||
|
||||
let cstore = e.sess.cstore;
|
||||
cstore.set_crate_data(cnum, cmeta);
|
||||
cstore.add_used_crate_source(cstore::CrateSource {
|
||||
dylib: dylib,
|
||||
rlib: rlib,
|
||||
cnum: cnum,
|
||||
});
|
||||
return cnum;
|
||||
}
|
||||
Some(cnum) => {
|
||||
return cnum;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Go through the crate metadata and load any crates that it references
|
||||
fn resolve_crate_deps(e: &mut Env,
|
||||
root_ident: Option<~str>,
|
||||
root_ident: Option<&str>,
|
||||
cdata: &[u8], span : Span)
|
||||
-> cstore::cnum_map {
|
||||
debug!("resolving deps of external crate");
|
||||
|
@ -388,31 +371,13 @@ fn resolve_crate_deps(e: &mut Env,
|
|||
let r = decoder::get_crate_deps(cdata);
|
||||
for dep in r.iter() {
|
||||
let extrn_cnum = dep.cnum;
|
||||
let cname_str = token::get_ident(dep.name);
|
||||
debug!("resolving dep crate {} ver: {} hash: {}",
|
||||
cname_str, dep.vers, dep.hash);
|
||||
match existing_match(e,
|
||||
cname_str.get(),
|
||||
dep.vers,
|
||||
dep.hash) {
|
||||
Some(local_cnum) => {
|
||||
debug!("already have it");
|
||||
// We've already seen this crate
|
||||
cnum_map.insert(extrn_cnum, local_cnum);
|
||||
}
|
||||
None => {
|
||||
debug!("need to load it");
|
||||
// This is a new one so we've got to load it
|
||||
let local_cnum = resolve_crate(e,
|
||||
root_ident.clone(),
|
||||
cname_str.get().to_str(),
|
||||
cname_str.get().to_str(),
|
||||
dep.vers.clone(),
|
||||
dep.hash.clone(),
|
||||
span);
|
||||
cnum_map.insert(extrn_cnum, local_cnum);
|
||||
}
|
||||
}
|
||||
debug!("resolving dep crate {} hash: `{}`", dep.crate_id, dep.hash);
|
||||
let local_cnum = resolve_crate(e, root_ident,
|
||||
dep.crate_id.name.as_slice(),
|
||||
&dep.crate_id,
|
||||
dep.hash,
|
||||
span);
|
||||
cnum_map.insert(extrn_cnum, local_cnum);
|
||||
}
|
||||
return @RefCell::new(cnum_map);
|
||||
}
|
||||
|
@ -439,14 +404,9 @@ impl Loader {
|
|||
|
||||
impl CrateLoader for Loader {
|
||||
fn load_crate(&mut self, krate: &ast::ViewItem) -> MacroCrate {
|
||||
let info = extract_crate_info(krate).unwrap();
|
||||
let cnum = resolve_crate(&mut self.env,
|
||||
None,
|
||||
info.ident.clone(),
|
||||
info.name.clone(),
|
||||
info.version.clone(),
|
||||
~"",
|
||||
krate.span);
|
||||
let info = extract_crate_info(&self.env, krate).unwrap();
|
||||
let cnum = resolve_crate(&mut self.env, None, info.ident,
|
||||
&info.crate_id, "", krate.span);
|
||||
let library = self.env.sess.cstore.get_used_crate_source(cnum).unwrap();
|
||||
MacroCrate {
|
||||
lib: library.dylib,
|
||||
|
|
|
@ -21,6 +21,7 @@ use collections::HashMap;
|
|||
use extra::c_vec::CVec;
|
||||
use syntax::ast;
|
||||
use syntax::parse::token::IdentInterner;
|
||||
use syntax::crateid::CrateId;
|
||||
|
||||
// A map from external crate numbers (as decoded from some crate file) to
|
||||
// local crate numbers (as generated during this session). Each external
|
||||
|
@ -96,9 +97,9 @@ impl CStore {
|
|||
decoder::get_crate_hash(cdata.data())
|
||||
}
|
||||
|
||||
pub fn get_crate_vers(&self, cnum: ast::CrateNum) -> ~str {
|
||||
pub fn get_crate_id(&self, cnum: ast::CrateNum) -> CrateId {
|
||||
let cdata = self.get_crate_data(cnum);
|
||||
decoder::get_crate_vers(cdata.data())
|
||||
decoder::get_crate_id(cdata.data())
|
||||
}
|
||||
|
||||
pub fn set_crate_data(&self, cnum: ast::CrateNum, data: @crate_metadata) {
|
||||
|
@ -191,41 +192,6 @@ impl CStore {
|
|||
let extern_mod_crate_map = self.extern_mod_crate_map.borrow();
|
||||
extern_mod_crate_map.get().find(&emod_id).map(|x| *x)
|
||||
}
|
||||
|
||||
// returns hashes of crates directly used by this crate. Hashes are sorted by
|
||||
// (crate name, crate version, crate hash) in lexicographic order (not semver)
|
||||
pub fn get_dep_hashes(&self) -> ~[~str] {
|
||||
let mut result = ~[];
|
||||
|
||||
let extern_mod_crate_map = self.extern_mod_crate_map.borrow();
|
||||
for (_, &cnum) in extern_mod_crate_map.get().iter() {
|
||||
let cdata = self.get_crate_data(cnum);
|
||||
let hash = decoder::get_crate_hash(cdata.data());
|
||||
let vers = decoder::get_crate_vers(cdata.data());
|
||||
debug!("Add hash[{}]: {} {}", cdata.name, vers, hash);
|
||||
result.push(crate_hash {
|
||||
name: cdata.name.clone(),
|
||||
vers: vers,
|
||||
hash: hash
|
||||
});
|
||||
}
|
||||
|
||||
result.sort();
|
||||
|
||||
debug!("sorted:");
|
||||
for x in result.iter() {
|
||||
debug!(" hash[{}]: {}", x.name, x.hash);
|
||||
}
|
||||
|
||||
result.move_iter().map(|crate_hash { hash, ..}| hash).collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(Clone, TotalEq, TotalOrd)]
|
||||
struct crate_hash {
|
||||
name: ~str,
|
||||
vers: ~str,
|
||||
hash: ~str,
|
||||
}
|
||||
|
||||
impl crate_metadata {
|
||||
|
|
|
@ -17,7 +17,6 @@ use metadata::common::*;
|
|||
use metadata::csearch::StaticMethodInfo;
|
||||
use metadata::csearch;
|
||||
use metadata::cstore;
|
||||
use metadata::decoder;
|
||||
use metadata::tydecode::{parse_ty_data, parse_def_id,
|
||||
parse_type_param_def_data,
|
||||
parse_bare_fn_ty_data, parse_trait_ref_data};
|
||||
|
@ -44,6 +43,7 @@ use syntax::parse::token;
|
|||
use syntax::print::pprust;
|
||||
use syntax::ast;
|
||||
use syntax::codemap;
|
||||
use syntax::crateid::CrateId;
|
||||
|
||||
type Cmd = @crate_metadata;
|
||||
|
||||
|
@ -1108,9 +1108,8 @@ pub fn get_crate_attributes(data: &[u8]) -> ~[ast::Attribute] {
|
|||
#[deriving(Clone)]
|
||||
pub struct CrateDep {
|
||||
cnum: ast::CrateNum,
|
||||
name: ast::Ident,
|
||||
vers: ~str,
|
||||
hash: ~str
|
||||
crate_id: CrateId,
|
||||
hash: ~str,
|
||||
}
|
||||
|
||||
pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
|
||||
|
@ -1123,10 +1122,13 @@ pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
|
|||
d.as_str_slice().to_str()
|
||||
}
|
||||
reader::tagged_docs(depsdoc, tag_crate_dep, |depdoc| {
|
||||
deps.push(CrateDep {cnum: crate_num,
|
||||
name: token::str_to_ident(docstr(depdoc, tag_crate_dep_name)),
|
||||
vers: docstr(depdoc, tag_crate_dep_vers),
|
||||
hash: docstr(depdoc, tag_crate_dep_hash)});
|
||||
let crate_id = from_str(docstr(depdoc, tag_crate_dep_crateid)).unwrap();
|
||||
let hash = docstr(depdoc, tag_crate_dep_hash);
|
||||
deps.push(CrateDep {
|
||||
cnum: crate_num,
|
||||
crate_id: crate_id,
|
||||
hash: hash,
|
||||
});
|
||||
crate_num += 1;
|
||||
true
|
||||
});
|
||||
|
@ -1135,17 +1137,9 @@ pub fn get_crate_deps(data: &[u8]) -> ~[CrateDep] {
|
|||
|
||||
fn list_crate_deps(data: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||
try!(write!(out, "=External Dependencies=\n"));
|
||||
|
||||
let r = get_crate_deps(data);
|
||||
for dep in r.iter() {
|
||||
try!(write!(out,
|
||||
"{} {}-{}-{}\n",
|
||||
dep.cnum,
|
||||
token::get_ident(dep.name),
|
||||
dep.hash,
|
||||
dep.vers));
|
||||
for dep in get_crate_deps(data).iter() {
|
||||
try!(write!(out, "{} {}-{}\n", dep.cnum, dep.crate_id, dep.hash));
|
||||
}
|
||||
|
||||
try!(write!(out, "\n"));
|
||||
Ok(())
|
||||
}
|
||||
|
@ -1156,12 +1150,10 @@ pub fn get_crate_hash(data: &[u8]) -> ~str {
|
|||
hashdoc.as_str_slice().to_str()
|
||||
}
|
||||
|
||||
pub fn get_crate_vers(data: &[u8]) -> ~str {
|
||||
let attrs = decoder::get_crate_attributes(data);
|
||||
match attr::find_crateid(attrs) {
|
||||
None => ~"0.0",
|
||||
Some(crateid) => crateid.version_or_default().to_str(),
|
||||
}
|
||||
pub fn get_crate_id(data: &[u8]) -> CrateId {
|
||||
let cratedoc = reader::Doc(data);
|
||||
let hashdoc = reader::get_doc(cratedoc, tag_crate_crateid);
|
||||
from_str(hashdoc.as_str_slice()).unwrap()
|
||||
}
|
||||
|
||||
pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Writer) -> io::IoResult<()> {
|
||||
|
|
|
@ -40,6 +40,7 @@ use syntax::ast_util::*;
|
|||
use syntax::ast_util;
|
||||
use syntax::attr::AttrMetaMethods;
|
||||
use syntax::attr;
|
||||
use syntax::crateid::CrateId;
|
||||
use syntax::diagnostic::SpanHandler;
|
||||
use syntax::parse::token::InternedString;
|
||||
use syntax::parse::token::special_idents;
|
||||
|
@ -1510,8 +1511,7 @@ fn encode_crate_deps(ebml_w: &mut writer::Encoder, cstore: &cstore::CStore) {
|
|||
cstore.iter_crate_data(|key, val| {
|
||||
let dep = decoder::CrateDep {
|
||||
cnum: key,
|
||||
name: token::str_to_ident(val.name),
|
||||
vers: decoder::get_crate_vers(val.data()),
|
||||
crate_id: decoder::get_crate_id(val.data()),
|
||||
hash: decoder::get_crate_hash(val.data())
|
||||
};
|
||||
deps.push(dep);
|
||||
|
@ -1729,12 +1729,8 @@ fn encode_misc_info(ecx: &EncodeContext,
|
|||
fn encode_crate_dep(ebml_w: &mut writer::Encoder,
|
||||
dep: decoder::CrateDep) {
|
||||
ebml_w.start_tag(tag_crate_dep);
|
||||
ebml_w.start_tag(tag_crate_dep_name);
|
||||
let s = token::get_ident(dep.name);
|
||||
ebml_w.writer.write(s.get().as_bytes());
|
||||
ebml_w.end_tag();
|
||||
ebml_w.start_tag(tag_crate_dep_vers);
|
||||
ebml_w.writer.write(dep.vers.as_bytes());
|
||||
ebml_w.start_tag(tag_crate_dep_crateid);
|
||||
ebml_w.writer.write(dep.crate_id.to_str().as_bytes());
|
||||
ebml_w.end_tag();
|
||||
ebml_w.start_tag(tag_crate_dep_hash);
|
||||
ebml_w.writer.write(dep.hash.as_bytes());
|
||||
|
@ -1748,6 +1744,12 @@ fn encode_hash(ebml_w: &mut writer::Encoder, hash: &str) {
|
|||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
fn encode_crate_id(ebml_w: &mut writer::Encoder, crate_id: &CrateId) {
|
||||
ebml_w.start_tag(tag_crate_crateid);
|
||||
ebml_w.writer.write(crate_id.to_str().as_bytes());
|
||||
ebml_w.end_tag();
|
||||
}
|
||||
|
||||
// NB: Increment this as you change the metadata encoding version.
|
||||
pub static metadata_encoding_version : &'static [u8] =
|
||||
&[0x72, //'r' as u8,
|
||||
|
@ -1806,6 +1808,7 @@ fn encode_metadata_inner(wr: &mut MemWriter, parms: EncodeParams, krate: &Crate)
|
|||
|
||||
let mut ebml_w = writer::Encoder(wr);
|
||||
|
||||
encode_crate_id(&mut ebml_w, &ecx.link_meta.crateid);
|
||||
encode_hash(&mut ebml_w, ecx.link_meta.crate_hash);
|
||||
|
||||
let mut i = ebml_w.writer.tell().unwrap();
|
||||
|
|
|
@ -44,13 +44,12 @@ pub enum Os {
|
|||
OsFreebsd
|
||||
}
|
||||
|
||||
pub struct Context {
|
||||
pub struct Context<'a> {
|
||||
sess: Session,
|
||||
span: Span,
|
||||
ident: ~str,
|
||||
name: ~str,
|
||||
version: ~str,
|
||||
hash: ~str,
|
||||
ident: &'a str,
|
||||
crate_id: &'a CrateId,
|
||||
hash: &'a str,
|
||||
os: Os,
|
||||
intr: @IdentInterner
|
||||
}
|
||||
|
@ -79,8 +78,8 @@ fn realpath(p: &Path) -> Path {
|
|||
}
|
||||
}
|
||||
|
||||
impl Context {
|
||||
pub fn load_library_crate(&self, root_ident: Option<~str>) -> Library {
|
||||
impl<'a> Context<'a> {
|
||||
pub fn load_library_crate(&self, root_ident: Option<&str>) -> Library {
|
||||
match self.find_library_crate() {
|
||||
Some(t) => t,
|
||||
None => {
|
||||
|
@ -101,8 +100,8 @@ impl Context {
|
|||
let (dyprefix, dysuffix) = self.dylibname();
|
||||
|
||||
// want: crate_name.dir_part() + prefix + crate_name.file_part + "-"
|
||||
let dylib_prefix = format!("{}{}-", dyprefix, self.name);
|
||||
let rlib_prefix = format!("lib{}-", self.name);
|
||||
let dylib_prefix = format!("{}{}-", dyprefix, self.crate_id.name);
|
||||
let rlib_prefix = format!("lib{}-", self.crate_id.name);
|
||||
|
||||
let mut candidates = HashMap::new();
|
||||
|
||||
|
@ -196,7 +195,8 @@ impl Context {
|
|||
1 => Some(libraries[0]),
|
||||
_ => {
|
||||
self.sess.span_err(self.span,
|
||||
format!("multiple matching crates for `{}`", self.name));
|
||||
format!("multiple matching crates for `{}`",
|
||||
self.crate_id.name));
|
||||
self.sess.note("candidates:");
|
||||
for lib in libraries.iter() {
|
||||
match lib.dylib {
|
||||
|
@ -243,11 +243,12 @@ impl Context {
|
|||
debug!("matching -- {}, hash: {}", file, hash);
|
||||
let vers = match parts.next() { Some(v) => v, None => return None };
|
||||
debug!("matching -- {}, vers: {}", file, vers);
|
||||
if !self.version.is_empty() && self.version.as_slice() != vers {
|
||||
return None
|
||||
match self.crate_id.version {
|
||||
Some(ref version) if version.as_slice() != vers => return None,
|
||||
Some(..) | None => {}
|
||||
}
|
||||
debug!("matching -- {}, vers ok (requested {})", file,
|
||||
self.version);
|
||||
self.crate_id.version);
|
||||
// hashes in filenames are prefixes of the "true hash"
|
||||
if self.hash.is_empty() || self.hash.starts_with(hash) {
|
||||
debug!("matching -- {}, hash ok (requested {})", file, self.hash);
|
||||
|
@ -275,7 +276,7 @@ impl Context {
|
|||
if m.len() > 1 {
|
||||
self.sess.span_err(self.span,
|
||||
format!("multiple {} candidates for `{}` \
|
||||
found", flavor, self.name));
|
||||
found", flavor, self.crate_id.name));
|
||||
for (i, path) in m.iter().enumerate() {
|
||||
self.sess.span_note(self.span,
|
||||
format!(r"candidate \#{}: {}", i + 1,
|
||||
|
@ -289,8 +290,7 @@ impl Context {
|
|||
info!("{} reading meatadata from: {}", flavor, lib.display());
|
||||
match get_metadata_section(self.os, &lib) {
|
||||
Some(blob) => {
|
||||
if crate_matches(blob.as_slice(), self.name,
|
||||
self.version, self.hash) {
|
||||
if crate_matches(blob.as_slice(), self.crate_id, self.hash){
|
||||
*slot = Some(blob);
|
||||
} else {
|
||||
info!("metadata mismatch");
|
||||
|
@ -323,23 +323,13 @@ pub fn note_crateid_attr(diag: @SpanHandler, crateid: &CrateId) {
|
|||
diag.handler().note(format!("crate_id: {}", crateid.to_str()));
|
||||
}
|
||||
|
||||
fn crate_matches(crate_data: &[u8],
|
||||
name: &str,
|
||||
version: &str,
|
||||
hash: &str) -> bool {
|
||||
let attrs = decoder::get_crate_attributes(crate_data);
|
||||
match attr::find_crateid(attrs) {
|
||||
None => false,
|
||||
Some(crateid) => {
|
||||
if !hash.is_empty() {
|
||||
let chash = decoder::get_crate_hash(crate_data);
|
||||
if chash.as_slice() != hash { return false; }
|
||||
}
|
||||
name == crateid.name &&
|
||||
(version.is_empty() ||
|
||||
crateid.version_or_default() == version)
|
||||
}
|
||||
fn crate_matches(crate_data: &[u8], crate_id: &CrateId, hash: &str) -> bool {
|
||||
let other_id = decoder::get_crate_id(crate_data);
|
||||
if !crate_id.matches(&other_id) { return false }
|
||||
if hash != "" && hash != decoder::get_crate_hash(crate_data).as_slice() {
|
||||
return false
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
impl ArchiveMetadata {
|
||||
|
|
|
@ -2488,7 +2488,7 @@ pub fn fill_crate_map(ccx: @CrateContext, map: ValueRef) {
|
|||
let cdata = cstore.get_crate_data(i);
|
||||
let nm = symname(format!("_rust_crate_map_{}", cdata.name),
|
||||
cstore.get_crate_hash(i),
|
||||
cstore.get_crate_vers(i));
|
||||
cstore.get_crate_id(i).version_or_default());
|
||||
let cr = nm.with_c_str(|buf| {
|
||||
unsafe {
|
||||
llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf)
|
||||
|
|
|
@ -107,6 +107,15 @@ impl CrateId {
|
|||
pub fn short_name_with_version(&self) -> ~str {
|
||||
format!("{}-{}", self.name, self.version_or_default())
|
||||
}
|
||||
|
||||
pub fn matches(&self, other: &CrateId) -> bool {
|
||||
// FIXME: why does this not match on `path`?
|
||||
if self.name != other.name { return false }
|
||||
match (&self.version, &other.version) {
|
||||
(&Some(ref v1), &Some(ref v2)) => v1 == v2,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Reference in New Issue