From e494e73cdd30fda0a10d6b3c067ca3a2809527eb Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sat, 9 Jul 2011 22:56:12 -0700 Subject: [PATCH] Use more encapsulation for metadata::cstore --- src/comp/metadata/cstore.rs | 88 +++++++++++++++++++++++++++--------- src/comp/metadata/encoder.rs | 2 +- src/comp/middle/resolve.rs | 4 +- 3 files changed, 69 insertions(+), 25 deletions(-) diff --git a/src/comp/metadata/cstore.rs b/src/comp/metadata/cstore.rs index dfa44909ce22..2812dd533079 100644 --- a/src/comp/metadata/cstore.rs +++ b/src/comp/metadata/cstore.rs @@ -6,6 +6,23 @@ import std::vec; import std::str; import syntax::ast; +export cstore; +export cnum_map; +export crate_metadata; +export mk_cstore; +export get_crate_data; +export set_crate_data; +export have_crate_data; +export iter_crate_data; +export add_used_crate_file; +export get_used_crate_files; +export add_used_library; +export get_used_libraries; +export add_used_link_args; +export get_used_link_args; +export add_use_stmt_cnum; +export get_use_stmt_cnum; + // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external // crate may refer to types in other external crates, and each has their @@ -16,73 +33,100 @@ type crate_metadata = rec(str name, vec[u8] data, cnum_map cnum_map); +// This is a bit of an experiment at encapsulating the data in cstore. By +// keeping all the data in a non-exported tag variant, it's impossible for +// other modules to access the cstore's private data. This could also be +// achieved with an obj, but at the expense of a vtable. Not sure if this is a +// good pattern or not. +tag cstore { + private(cstore_private); +} + +type cstore_private = @rec(map::hashmap[ast::crate_num, crate_metadata] metas, + use_crate_map use_crate_map, + mutable vec[str] used_crate_files, + mutable vec[str] used_libraries, + mutable vec[str] used_link_args); + // Map from node_id's of local use statements to crate numbers type use_crate_map = map::hashmap[ast::node_id, ast::crate_num]; -type cstore = @rec(map::hashmap[ast::crate_num, crate_metadata] metas, - use_crate_map use_crate_map, - mutable vec[str] used_crate_files, - mutable vec[str] used_libraries, - mutable vec[str] used_link_args); +// Internal method to retrieve the data from the cstore +fn p(&cstore cstore) -> cstore_private { + alt (cstore) { + case (private(?p)) { p } + } +} fn mk_cstore() -> cstore { auto meta_cache = map::new_int_hash[crate_metadata](); auto crate_map = map::new_int_hash[ast::crate_num](); - ret @rec(metas = meta_cache, - use_crate_map = crate_map, - mutable used_crate_files = [], - mutable used_libraries = [], - mutable used_link_args = []); + ret private(@rec(metas = meta_cache, + use_crate_map = crate_map, + mutable used_crate_files = [], + mutable used_libraries = [], + mutable used_link_args = [])); } fn get_crate_data(&cstore cstore, ast::crate_num cnum) -> crate_metadata { - ret cstore.metas.get(cnum); + ret p(cstore).metas.get(cnum); } fn set_crate_data(&cstore cstore, ast::crate_num cnum, &crate_metadata data) { - cstore.metas.insert(cnum, data); + p(cstore).metas.insert(cnum, data); } fn have_crate_data(&cstore cstore, ast::crate_num cnum) -> bool { - ret cstore.metas.contains_key(cnum); + ret p(cstore).metas.contains_key(cnum); +} + +iter iter_crate_data(&cstore cstore) -> @tup(ast::crate_num, crate_metadata) { + for each (@tup(ast::crate_num, crate_metadata) kv + in p(cstore).metas.items()) { + put kv; + } } fn add_used_crate_file(&cstore cstore, &str lib) { - if (!vec::member(lib, cstore.used_crate_files)) { - cstore.used_crate_files += [lib]; + if (!vec::member(lib, p(cstore).used_crate_files)) { + p(cstore).used_crate_files += [lib]; } } fn get_used_crate_files(&cstore cstore) -> vec[str] { - ret cstore.used_crate_files; + ret p(cstore).used_crate_files; } fn add_used_library(&cstore cstore, &str lib) -> bool { if (lib == "") { ret false; } - if (vec::member(lib, cstore.used_libraries)) { + if (vec::member(lib, p(cstore).used_libraries)) { ret false; } - cstore.used_libraries += [lib]; + p(cstore).used_libraries += [lib]; ret true; } fn get_used_libraries(&cstore cstore) -> vec[str] { - ret cstore.used_libraries; + ret p(cstore).used_libraries; } fn add_used_link_args(&cstore cstore, &str args) { - cstore.used_link_args += str::split(args, ' ' as u8); + p(cstore).used_link_args += str::split(args, ' ' as u8); } fn get_used_link_args(&cstore cstore) -> vec[str] { - ret cstore.used_link_args; + ret p(cstore).used_link_args; } fn add_use_stmt_cnum(&cstore cstore, ast::node_id use_id, ast::crate_num cnum) { - cstore.use_crate_map.insert(use_id, cnum); + p(cstore).use_crate_map.insert(use_id, cnum); +} + +fn get_use_stmt_cnum(&cstore cstore, ast::node_id use_id) -> ast::crate_num { + ret p(cstore).use_crate_map.get(use_id); } // Local Variables: diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index 89634d233bff..c1c48bcd18eb 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -528,7 +528,7 @@ fn encode_crate_deps(&ebml::writer ebml_w, &cstore::cstore cstore) { // Pull the cnums and names out of cstore let vec[mutable numname] pairs = [mutable]; - for each (hashkv hashkv in cstore.metas.items()) { + for each (hashkv hashkv in cstore::iter_crate_data(cstore)) { pairs += [mutable tup(hashkv._0, hashkv._1.name)]; } diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 32976aadedea..ab7aa564477a 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -886,8 +886,8 @@ fn found_view_item(&env e, @ast::view_item vi, namespace ns) -> option::t[def] { alt (vi.node) { case (ast::view_item_use(_, _, ?id)) { - auto crate_map = e.cstore.use_crate_map; - ret some(ast::def_mod(tup(crate_map.get(id), -1))); + auto cnum = cstore::get_use_stmt_cnum(e.cstore, id); + ret some(ast::def_mod(tup(cnum, -1))); } case (ast::view_item_import(_, _, ?id)) { ret lookup_import(e, local_def(id), ns);