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
::{self, TypeNS, ValueNS}
;
24 use build_reduced_graph
;
27 use rustc
::middle
::def
::Export
;
29 use syntax
::parse
::token
;
31 use std
::ops
::{Deref, DerefMut}
;
34 struct ExportRecorder
<'a
, 'b
:'a
, 'tcx
:'b
> {
35 resolver
: &'a
mut Resolver
<'b
, 'tcx
>
38 // Deref and DerefMut impls allow treating ExportRecorder as Resolver.
39 impl<'a
, 'b
, 'tcx
:'b
> Deref
for ExportRecorder
<'a
, 'b
, 'tcx
> {
40 type Target
= Resolver
<'b
, 'tcx
>;
42 fn deref
<'c
>(&'c
self) -> &'c Resolver
<'b
, 'tcx
> {
47 impl<'a
, 'b
, 'tcx
:'b
> DerefMut
for ExportRecorder
<'a
, 'b
, 'tcx
> {
48 fn deref_mut
<'c
>(&'c
mut self) -> &'c
mut Resolver
<'b
, 'tcx
> {
53 impl<'a
, 'b
, 'tcx
> ExportRecorder
<'a
, 'b
, 'tcx
> {
54 fn record_exports_for_module_subtree(&mut self,
55 module_
: Rc
<Module
>) {
56 // If this isn't a local krate, then bail out. We don't need to record
57 // exports for nonlocal crates.
59 match module_
.def_id
.get() {
60 Some(def_id
) if def_id
.krate
== ast
::LOCAL_CRATE
=> {
62 debug
!("(recording exports for module subtree) recording \
63 exports for local module `{}`",
64 module_to_string(&*module_
));
67 // Record exports for the root module.
68 debug
!("(recording exports for module subtree) recording \
69 exports for root module `{}`",
70 module_to_string(&*module_
));
74 debug
!("(recording exports for module subtree) not recording \
76 module_to_string(&*module_
));
81 self.record_exports_for_module(&*module_
);
82 build_reduced_graph
::populate_module_if_necessary(self.resolver
, &module_
);
84 for (_
, child_name_bindings
) in module_
.children
.borrow().iter() {
85 match child_name_bindings
.get_module_if_available() {
89 Some(child_module
) => {
90 self.record_exports_for_module_subtree(child_module
);
95 for (_
, child_module
) in module_
.anonymous_children
.borrow().iter() {
96 self.record_exports_for_module_subtree(child_module
.clone());
100 fn record_exports_for_module(&mut self, module_
: &Module
) {
101 let mut exports
= Vec
::new();
103 self.add_exports_for_module(&mut exports
, module_
);
104 match module_
.def_id
.get() {
106 self.export_map
.insert(def_id
.node
, exports
);
107 debug
!("(computing exports) writing exports for {} (some)",
114 fn add_exports_of_namebindings(&mut self,
115 exports
: &mut Vec
<Export
>,
117 namebindings
: &NameBindings
,
119 match namebindings
.def_for_namespace(ns
) {
121 debug
!("(computing exports) YES: export '{}' => {:?}",
123 exports
.push(Export
{
129 debug
!("(computing exports) NO: {:?}", d_opt
);
134 fn add_exports_for_module(&mut self,
135 exports
: &mut Vec
<Export
>,
137 for (name
, import_resolution
) in module_
.import_resolutions
.borrow().iter() {
138 if !import_resolution
.is_public
{
141 let xs
= [TypeNS
, ValueNS
];
143 match import_resolution
.target_for_namespace(ns
) {
145 debug
!("(computing exports) maybe export '{}'",
146 token
::get_name(*name
));
147 self.add_exports_of_namebindings(exports
,
159 pub fn record(resolver
: &mut Resolver
) {
160 let mut recorder
= ExportRecorder { resolver: resolver }
;
161 let root_module
= recorder
.graph_root
.get_module();
162 recorder
.record_exports_for_module_subtree(root_module
);