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.
14 // This pass simply determines what all "export" keywords refer to and
15 // writes the results into the export map.
17 // FIXME #4953 This pass will be removed once exports change to per-item.
18 // Then this operation can simply be performed as part of item (or import)
21 use {Module, NameBindings, Resolver};
22 use Namespace::{mod, TypeNS, ValueNS};
24 use build_reduced_graph;
26 use rustc::middle::def::Export;
28 use syntax::parse::token;
30 use std::ops::{Deref, DerefMut};
33 struct ExportRecorder<'a, 'b:'a, 'tcx:'b> {
34 resolver: &'a mut Resolver<'b, 'tcx>
37 // Deref and DerefMut impls allow treating ExportRecorder as Resolver.
38 impl<'a, 'b, 'tcx:'b> Deref for ExportRecorder<'a, 'b, 'tcx> {
39 type Target = Resolver<'b, 'tcx>;
41 fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> {
46 impl<'a, 'b, 'tcx:'b> DerefMut for ExportRecorder<'a, 'b, 'tcx> {
47 fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> {
52 impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
53 fn record_exports_for_module_subtree(&mut self,
54 module_: Rc<Module>) {
55 // If this isn't a local krate, then bail out. We don't need to record
56 // exports for nonlocal crates.
58 match module_.def_id.get() {
59 Some(def_id) if def_id.krate == ast::LOCAL_CRATE => {
61 debug!("(recording exports for module subtree) recording \
62 exports for local module `{}`",
63 self.module_to_string(&*module_));
66 // Record exports for the root module.
67 debug!("(recording exports for module subtree) recording \
68 exports for root module `{}`",
69 self.module_to_string(&*module_));
73 debug!("(recording exports for module subtree) not recording \
75 self.module_to_string(&*module_));
80 self.record_exports_for_module(&*module_);
81 build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
83 for (_, child_name_bindings) in module_.children.borrow().iter() {
84 match child_name_bindings.get_module_if_available() {
88 Some(child_module) => {
89 self.record_exports_for_module_subtree(child_module);
94 for (_, child_module) in module_.anonymous_children.borrow().iter() {
95 self.record_exports_for_module_subtree(child_module.clone());
99 fn record_exports_for_module(&mut self, module_: &Module) {
100 let mut exports = Vec::new();
102 self.add_exports_for_module(&mut exports, module_);
103 match module_.def_id.get() {
105 self.export_map.insert(def_id.node, exports);
106 debug!("(computing exports) writing exports for {} (some)",
113 fn add_exports_of_namebindings(&mut self,
114 exports: &mut Vec<Export>,
116 namebindings: &NameBindings,
118 match namebindings.def_for_namespace(ns) {
120 debug!("(computing exports) YES: export '{}' => {}",
122 exports.push(Export {
128 debug!("(computing exports) NO: {}", d_opt);
133 fn add_exports_for_module(&mut self,
134 exports: &mut Vec<Export>,
136 for (name, importresolution) in module_.import_resolutions.borrow().iter() {
137 if !importresolution.is_public {
140 let xs = [TypeNS, ValueNS];
141 for &ns in xs.iter() {
142 match importresolution.target_for_namespace(ns) {
144 debug!("(computing exports) maybe export '{}'",
145 token::get_name(*name));
146 self.add_exports_of_namebindings(exports,
158 pub fn record(resolver: &mut Resolver) {
159 let mut recorder = ExportRecorder { resolver: resolver };
160 let root_module = recorder.graph_root.get_module();
161 recorder.record_exports_for_module_subtree(root_module);