1 // Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 #[allow(non_camel_case_types)];
13 // The crate store - a central repo for information collected about external
14 // crates and libraries
17 use metadata::decoder;
20 use std::cell::RefCell;
21 use collections::HashMap;
22 use extra::c_vec::CVec;
24 use syntax::parse::token::IdentInterner;
25 use syntax::crateid::CrateId;
27 // A map from external crate numbers (as decoded from some crate file) to
28 // local crate numbers (as generated during this session). Each external
29 // crate may refer to types in other external crates, and each has their
31 pub type cnum_map = @RefCell<HashMap<ast::CrateNum, ast::CrateNum>>;
33 pub enum MetadataBlob {
34 MetadataVec(CVec<u8>),
35 MetadataArchive(loader::ArchiveMetadata),
38 pub struct crate_metadata {
46 pub enum LinkagePreference {
51 #[deriving(Eq, FromPrimitive)]
52 pub enum NativeLibaryKind {
53 NativeStatic, // native static library (.a archive)
54 NativeFramework, // OSX-specific
55 NativeUnknown, // default way to specify a dynamic library
58 // Where a crate came from on the local filesystem. One of these two options
60 #[deriving(Eq, Clone)]
61 pub struct CrateSource {
68 priv metas: RefCell<HashMap<ast::CrateNum, @crate_metadata>>,
69 priv extern_mod_crate_map: RefCell<extern_mod_crate_map>,
70 priv used_crate_sources: RefCell<~[CrateSource]>,
71 priv used_libraries: RefCell<~[(~str, NativeLibaryKind)]>,
72 priv used_link_args: RefCell<~[~str]>,
76 // Map from NodeId's of local extern crate statements to crate numbers
77 type extern_mod_crate_map = HashMap<ast::NodeId, ast::CrateNum>;
80 pub fn new(intr: @IdentInterner) -> CStore {
82 metas: RefCell::new(HashMap::new()),
83 extern_mod_crate_map: RefCell::new(HashMap::new()),
84 used_crate_sources: RefCell::new(~[]),
85 used_libraries: RefCell::new(~[]),
86 used_link_args: RefCell::new(~[]),
91 pub fn get_crate_data(&self, cnum: ast::CrateNum) -> @crate_metadata {
92 let metas = self.metas.borrow();
93 *metas.get().get(&cnum)
96 pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
97 let cdata = self.get_crate_data(cnum);
98 decoder::get_crate_hash(cdata.data())
101 pub fn get_crate_id(&self, cnum: ast::CrateNum) -> CrateId {
102 let cdata = self.get_crate_data(cnum);
103 decoder::get_crate_id(cdata.data())
106 pub fn set_crate_data(&self, cnum: ast::CrateNum, data: @crate_metadata) {
107 let mut metas = self.metas.borrow_mut();
108 metas.get().insert(cnum, data);
111 pub fn have_crate_data(&self, cnum: ast::CrateNum) -> bool {
112 let metas = self.metas.borrow();
113 metas.get().contains_key(&cnum)
116 pub fn iter_crate_data(&self, i: |ast::CrateNum, @crate_metadata|) {
117 let metas = self.metas.borrow();
118 for (&k, &v) in metas.get().iter() {
123 pub fn add_used_crate_source(&self, src: CrateSource) {
124 let mut used_crate_sources = self.used_crate_sources.borrow_mut();
125 if !used_crate_sources.get().contains(&src) {
126 used_crate_sources.get().push(src);
130 pub fn get_used_crate_source(&self, cnum: ast::CrateNum)
131 -> Option<CrateSource> {
132 let mut used_crate_sources = self.used_crate_sources.borrow_mut();
133 used_crate_sources.get().iter().find(|source| source.cnum == cnum)
134 .map(|source| source.clone())
137 pub fn reset(&self) {
138 self.metas.with_mut(|s| s.clear());
139 self.extern_mod_crate_map.with_mut(|s| s.clear());
140 self.used_crate_sources.with_mut(|s| s.clear());
141 self.used_libraries.with_mut(|s| s.clear());
142 self.used_link_args.with_mut(|s| s.clear());
145 pub fn get_used_crates(&self, prefer: LinkagePreference)
146 -> ~[(ast::CrateNum, Option<Path>)] {
147 let used_crate_sources = self.used_crate_sources.borrow();
148 used_crate_sources.get()
150 .map(|src| (src.cnum, match prefer {
151 RequireDynamic => src.dylib.clone(),
152 RequireStatic => src.rlib.clone(),
157 pub fn add_used_library(&self, lib: ~str, kind: NativeLibaryKind) {
158 assert!(!lib.is_empty());
159 let mut used_libraries = self.used_libraries.borrow_mut();
160 used_libraries.get().push((lib, kind));
163 pub fn get_used_libraries<'a>(&'a self)
164 -> &'a RefCell<~[(~str, NativeLibaryKind)]> {
168 pub fn add_used_link_args(&self, args: &str) {
169 let mut used_link_args = self.used_link_args.borrow_mut();
170 for s in args.split(' ') {
171 used_link_args.get().push(s.to_owned());
175 pub fn get_used_link_args<'a>(&'a self) -> &'a RefCell<~[~str]> {
179 pub fn add_extern_mod_stmt_cnum(&self,
180 emod_id: ast::NodeId,
181 cnum: ast::CrateNum) {
182 let mut extern_mod_crate_map = self.extern_mod_crate_map.borrow_mut();
183 extern_mod_crate_map.get().insert(emod_id, cnum);
186 pub fn find_extern_mod_stmt_cnum(&self, emod_id: ast::NodeId)
187 -> Option<ast::CrateNum> {
188 let extern_mod_crate_map = self.extern_mod_crate_map.borrow();
189 extern_mod_crate_map.get().find(&emod_id).map(|x| *x)
193 impl crate_metadata {
194 pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() }
198 pub fn as_slice<'a>(&'a self) -> &'a [u8] {
200 MetadataVec(ref vec) => vec.as_slice(),
201 MetadataArchive(ref ar) => ar.as_slice(),