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 //! Reduced graph building
13 //! Here we build the "reduced graph": the graph of the module tree without
14 //! any imports resolved.
17 use resolve_imports
::ImportDirective
;
18 use resolve_imports
::ImportDirectiveSubclass
::{self, SingleImport, GlobImport}
;
19 use resolve_imports
::ImportResolution
;
22 use Namespace
::{TypeNS, ValueNS}
;
24 use {names_to_string, module_to_string}
;
25 use ParentLink
::{self, ModuleParentLink, BlockParentLink}
;
27 use resolve_imports
::Shadowable
;
30 use self::DuplicateCheckingMode
::*;
31 use self::NamespaceError
::*;
33 use rustc
::metadata
::csearch
;
34 use rustc
::metadata
::decoder
::{DefLike, DlDef, DlField, DlImpl}
;
35 use rustc
::middle
::def
::*;
37 use syntax
::ast
::{Block, Crate}
;
38 use syntax
::ast
::{DeclItem, DefId}
;
39 use syntax
::ast
::{ForeignItem, ForeignItemFn, ForeignItemStatic}
;
40 use syntax
::ast
::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}
;
41 use syntax
::ast
::{ItemForeignMod, ItemImpl, ItemMac, ItemMod, ItemStatic, ItemDefaultImpl}
;
42 use syntax
::ast
::{ItemStruct, ItemTrait, ItemTy, ItemUse}
;
43 use syntax
::ast
::{Name, NamedField, NodeId}
;
44 use syntax
::ast
::{PathListIdent, PathListMod, Public}
;
45 use syntax
::ast
::StmtDecl
;
46 use syntax
::ast
::StructVariantKind
;
47 use syntax
::ast
::TupleVariantKind
;
48 use syntax
::ast
::UnnamedField
;
49 use syntax
::ast
::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}
;
50 use syntax
::ast
::Visibility
;
52 use syntax
::ast_util
::local_def
;
53 use syntax
::attr
::AttrMetaMethods
;
54 use syntax
::parse
::token
::{self, special_idents}
;
55 use syntax
::codemap
::{Span, DUMMY_SP}
;
56 use syntax
::visit
::{self, Visitor}
;
58 use std
::mem
::replace
;
59 use std
::ops
::{Deref, DerefMut}
;
62 // Specifies how duplicates should be handled when adding a child item if
63 // another item exists with the same name in some namespace.
64 #[derive(Copy, Clone, PartialEq)]
65 enum DuplicateCheckingMode
{
66 ForbidDuplicateModules
,
67 ForbidDuplicateTypesAndModules
,
68 ForbidDuplicateValues
,
69 ForbidDuplicateTypesAndValues
,
73 #[derive(Copy, Clone, PartialEq)]
81 fn namespace_error_to_string(ns
: NamespaceError
) -> &'
static str {
84 ModuleError
| TypeError
=> "type or module",
85 ValueError
=> "value",
89 struct GraphBuilder
<'a
, 'b
:'a
, 'tcx
:'b
> {
90 resolver
: &'a
mut Resolver
<'b
, 'tcx
>
93 impl<'a
, 'b
:'a
, 'tcx
:'b
> Deref
for GraphBuilder
<'a
, 'b
, 'tcx
> {
94 type Target
= Resolver
<'b
, 'tcx
>;
96 fn deref(&self) -> &Resolver
<'b
, 'tcx
> {
101 impl<'a
, 'b
:'a
, 'tcx
:'b
> DerefMut
for GraphBuilder
<'a
, 'b
, 'tcx
> {
102 fn deref_mut(&mut self) -> &mut Resolver
<'b
, 'tcx
> {
107 impl<'a
, 'b
:'a
, 'tcx
:'b
> GraphBuilder
<'a
, 'b
, 'tcx
> {
108 /// Constructs the reduced graph for the entire crate.
109 fn build_reduced_graph(self, krate
: &ast
::Crate
) {
110 let parent
= self.graph_root
.get_module();
111 let mut visitor
= BuildReducedGraphVisitor
{
115 visit
::walk_crate(&mut visitor
, krate
);
118 /// Adds a new child item to the module definition of the parent node and
119 /// returns its corresponding name bindings as well as the current parent.
120 /// Or, if we're inside a block, creates (or reuses) an anonymous module
121 /// corresponding to the innermost block ID and returns the name bindings
122 /// as well as the newly-created parent.
126 /// Panics if this node does not have a module definition and we are not inside
131 duplicate_checking_mode
: DuplicateCheckingMode
,
132 // For printing errors
134 -> Rc
<NameBindings
> {
135 // If this is the immediate descendant of a module, then we add the
136 // child name directly. Otherwise, we create or reuse an anonymous
137 // module and add the child to that.
139 self.check_for_conflicts_between_external_crates_and_items(&**parent
,
143 // Add or reuse the child.
144 let child
= parent
.children
.borrow().get(&name
).cloned();
147 let child
= Rc
::new(NameBindings
::new());
148 parent
.children
.borrow_mut().insert(name
, child
.clone());
152 // Enforce the duplicate checking mode:
154 // * If we're requesting duplicate module checking, check that
155 // there isn't a module in the module with the same name.
157 // * If we're requesting duplicate type checking, check that
158 // there isn't a type in the module with the same name.
160 // * If we're requesting duplicate value checking, check that
161 // there isn't a value in the module with the same name.
163 // * If we're requesting duplicate type checking and duplicate
164 // value checking, check that there isn't a duplicate type
165 // and a duplicate value with the same name.
167 // * If no duplicate checking was requested at all, do
170 let mut duplicate_type
= NoError
;
171 let ns
= match duplicate_checking_mode
{
172 ForbidDuplicateModules
=> {
173 if child
.get_module_if_available().is_some() {
174 duplicate_type
= ModuleError
;
178 ForbidDuplicateTypesAndModules
=> {
179 if child
.defined_in_namespace(TypeNS
) {
180 duplicate_type
= TypeError
;
184 ForbidDuplicateValues
=> {
185 if child
.defined_in_namespace(ValueNS
) {
186 duplicate_type
= ValueError
;
190 ForbidDuplicateTypesAndValues
=> {
192 match child
.def_for_namespace(TypeNS
) {
193 Some(DefMod(_
)) | None
=> {}
196 duplicate_type
= TypeError
;
199 if child
.defined_in_namespace(ValueNS
) {
200 duplicate_type
= ValueError
;
205 OverwriteDuplicates
=> None
207 if duplicate_type
!= NoError
{
208 // Return an error here by looking up the namespace that
209 // had the duplicate.
210 let ns
= ns
.unwrap();
211 self.resolve_error(sp
,
212 &format
!("duplicate definition of {} `{}`",
213 namespace_error_to_string(duplicate_type
),
214 token
::get_name(name
)));
216 let r
= child
.span_for_namespace(ns
);
217 if let Some(sp
) = r
{
218 self.session
.span_note(sp
,
219 &format
!("first definition of {} `{}` here",
220 namespace_error_to_string(duplicate_type
),
221 token
::get_name(name
)));
230 fn block_needs_anonymous_module(&mut self, block
: &Block
) -> bool
{
231 // Check each statement.
232 for statement
in &block
.stmts
{
233 match statement
.node
{
234 StmtDecl(ref declaration
, _
) => {
235 match declaration
.node
{
250 // If we found no items, we don't need to create
251 // an anonymous module.
256 fn get_parent_link(&mut self, parent
: &Rc
<Module
>, name
: Name
) -> ParentLink
{
257 ModuleParentLink(parent
.downgrade(), name
)
260 /// Constructs the reduced graph for one item.
261 fn build_reduced_graph_for_item(&mut self, item
: &Item
, parent
: &Rc
<Module
>) -> Rc
<Module
> {
262 let name
= item
.ident
.name
;
264 let is_public
= item
.vis
== ast
::Public
;
265 let modifiers
= if is_public
{
268 DefModifiers
::empty()
269 } | DefModifiers
::IMPORTABLE
;
272 ItemUse(ref view_path
) => {
273 // Extract and intern the module part of the path. For
274 // globs and lists, the path is found directly in the AST;
275 // for simple paths we have to munge the path a little.
276 let module_path
= match view_path
.node
{
277 ViewPathSimple(_
, ref full_path
) => {
280 .iter().map(|ident
| ident
.identifier
.name
)
284 ViewPathGlob(ref module_ident_path
) |
285 ViewPathList(ref module_ident_path
, _
) => {
286 module_ident_path
.segments
287 .iter().map(|ident
| ident
.identifier
.name
).collect()
291 // Build up the import directives.
292 let shadowable
= item
.attrs
.iter().any(|attr
| {
293 attr
.name() == token
::get_name(special_idents
::prelude_import
.name
)
295 let shadowable
= if shadowable
{
301 match view_path
.node
{
302 ViewPathSimple(binding
, ref full_path
) => {
304 full_path
.segments
.last().unwrap().identifier
.name
;
305 if &token
::get_name(source_name
)[..] == "mod" ||
306 &token
::get_name(source_name
)[..] == "self" {
307 self.resolve_error(view_path
.span
,
308 "`self` imports are only allowed within a { } list");
311 let subclass
= SingleImport(binding
.name
,
313 self.build_import_directive(&**parent
,
321 ViewPathList(_
, ref source_items
) => {
322 // Make sure there's at most one `mod` import in the list.
323 let mod_spans
= source_items
.iter().filter_map(|item
| match item
.node
{
324 PathListMod { .. }
=> Some(item
.span
),
326 }).collect
::<Vec
<Span
>>();
327 if mod_spans
.len() > 1 {
328 self.resolve_error(mod_spans
[0],
329 "`self` import can only appear once in the list");
330 for other_span
in mod_spans
.iter().skip(1) {
331 self.session
.span_note(*other_span
,
332 "another `self` import appears here");
336 for source_item
in source_items
{
337 let (module_path
, name
) = match source_item
.node
{
338 PathListIdent { name, .. }
=>
339 (module_path
.clone(), name
.name
),
340 PathListMod { .. }
=> {
341 let name
= match module_path
.last() {
344 self.resolve_error(source_item
.span
,
345 "`self` import can only appear in an import list \
346 with a non-empty prefix");
350 let module_path
= module_path
.init();
351 (module_path
.to_vec(), name
)
354 self.build_import_directive(
357 SingleImport(name
, name
),
359 source_item
.node
.id(),
365 self.build_import_directive(&**parent
,
377 ItemExternCrate(_
) => {
378 // n.b. we don't need to look at the path option here, because cstore already did
379 if let Some(crate_id
) = self.session
.cstore
.find_extern_mod_stmt_cnum(item
.id
) {
380 let def_id
= DefId { krate: crate_id, node: 0 }
;
381 self.external_exports
.insert(def_id
);
382 let parent_link
= ModuleParentLink(parent
.downgrade(), name
);
383 let external_module
= Rc
::new(Module
::new(parent_link
,
388 debug
!("(build reduced graph for item) found extern `{}`",
389 module_to_string(&*external_module
));
390 self.check_for_conflicts_between_external_crates(&**parent
, name
, sp
);
391 parent
.external_module_children
.borrow_mut()
392 .insert(name
, external_module
.clone());
393 self.build_reduced_graph_for_external_crate(&external_module
);
399 let name_bindings
= self.add_child(name
, parent
, ForbidDuplicateModules
, sp
);
401 let parent_link
= self.get_parent_link(parent
, name
);
402 let def_id
= DefId { krate: 0, node: item.id }
;
403 name_bindings
.define_module(parent_link
,
410 name_bindings
.get_module()
413 ItemForeignMod(..) => parent
.clone(),
415 // These items live in the value namespace.
416 ItemStatic(_
, m
, _
) => {
417 let name_bindings
= self.add_child(name
, parent
, ForbidDuplicateValues
, sp
);
418 let mutbl
= m
== ast
::MutMutable
;
420 name_bindings
.define_value(DefStatic(local_def(item
.id
), mutbl
), sp
, modifiers
);
424 self.add_child(name
, parent
, ForbidDuplicateValues
, sp
)
425 .define_value(DefConst(local_def(item
.id
)), sp
, modifiers
);
428 ItemFn(_
, _
, _
, _
, _
, _
) => {
429 let name_bindings
= self.add_child(name
, parent
, ForbidDuplicateValues
, sp
);
431 let def
= DefFn(local_def(item
.id
), false);
432 name_bindings
.define_value(def
, sp
, modifiers
);
436 // These items live in the type namespace.
439 self.add_child(name
, parent
, ForbidDuplicateTypesAndModules
, sp
);
441 name_bindings
.define_type(DefTy(local_def(item
.id
), false), sp
,
444 let parent_link
= self.get_parent_link(parent
, name
);
445 name_bindings
.set_module_kind(parent_link
,
446 Some(local_def(item
.id
)),
454 ItemEnum(ref enum_definition
, _
) => {
456 self.add_child(name
, parent
, ForbidDuplicateTypesAndModules
, sp
);
458 name_bindings
.define_type(DefTy(local_def(item
.id
), true), sp
, modifiers
);
460 let parent_link
= self.get_parent_link(parent
, name
);
461 name_bindings
.set_module_kind(parent_link
,
462 Some(local_def(item
.id
)),
468 let module
= name_bindings
.get_module();
470 for variant
in &(*enum_definition
).variants
{
471 self.build_reduced_graph_for_variant(
479 // These items live in both the type and value namespaces.
480 ItemStruct(ref struct_def
, _
) => {
481 // Adding to both Type and Value namespaces or just Type?
482 let (forbid
, ctor_id
) = match struct_def
.ctor_id
{
483 Some(ctor_id
) => (ForbidDuplicateTypesAndValues
, Some(ctor_id
)),
484 None
=> (ForbidDuplicateTypesAndModules
, None
)
487 let name_bindings
= self.add_child(name
, parent
, forbid
, sp
);
489 // Define a name in the type namespace.
490 name_bindings
.define_type(DefTy(local_def(item
.id
), false), sp
, modifiers
);
492 // If this is a newtype or unit-like struct, define a name
493 // in the value namespace as well
494 if let Some(cid
) = ctor_id
{
495 name_bindings
.define_value(DefStruct(local_def(cid
)), sp
, modifiers
);
498 // Record the def ID and fields of this struct.
499 let named_fields
= struct_def
.fields
.iter().filter_map(|f
| {
501 NamedField(ident
, _
) => Some(ident
.name
),
502 UnnamedField(_
) => None
505 self.structs
.insert(local_def(item
.id
), named_fields
);
510 ItemDefaultImpl(_
, _
) |
511 ItemImpl(..) => parent
.clone(),
513 ItemTrait(_
, _
, _
, ref items
) => {
515 self.add_child(name
, parent
, ForbidDuplicateTypesAndModules
, sp
);
517 // Add all the items within to a new module.
518 let parent_link
= self.get_parent_link(parent
, name
);
519 name_bindings
.define_module(parent_link
,
520 Some(local_def(item
.id
)),
525 let module_parent
= name_bindings
.get_module();
527 let def_id
= local_def(item
.id
);
529 // Add the names of all the items to the trait info.
530 for trait_item
in items
{
531 let name_bindings
= self.add_child(trait_item
.ident
.name
,
533 ForbidDuplicateTypesAndValues
,
536 match trait_item
.node
{
537 ast
::ConstTraitItem(..) => {
538 let def
= DefAssociatedConst(local_def(trait_item
.id
),
539 FromTrait(local_def(item
.id
)));
540 // NB: not DefModifiers::IMPORTABLE
541 name_bindings
.define_value(def
, trait_item
.span
, DefModifiers
::PUBLIC
);
543 ast
::MethodTraitItem(..) => {
544 let def
= DefMethod(local_def(trait_item
.id
),
545 FromTrait(local_def(item
.id
)));
546 // NB: not DefModifiers::IMPORTABLE
547 name_bindings
.define_value(def
, trait_item
.span
, DefModifiers
::PUBLIC
);
549 ast
::TypeTraitItem(..) => {
550 let def
= DefAssociatedTy(local_def(item
.id
),
551 local_def(trait_item
.id
));
552 // NB: not DefModifiers::IMPORTABLE
553 name_bindings
.define_type(def
, trait_item
.span
, DefModifiers
::PUBLIC
);
557 self.trait_item_map
.insert((trait_item
.ident
.name
, def_id
),
558 local_def(trait_item
.id
));
561 name_bindings
.define_type(DefTrait(def_id
), sp
, modifiers
);
564 ItemMac(..) => parent
.clone()
568 // Constructs the reduced graph for one variant. Variants exist in the
569 // type and value namespaces.
570 fn build_reduced_graph_for_variant(&mut self,
573 parent
: &Rc
<Module
>) {
574 let name
= variant
.node
.name
.name
;
575 let is_exported
= match variant
.node
.kind
{
576 TupleVariantKind(_
) => false,
577 StructVariantKind(_
) => {
578 // Not adding fields for variants as they are not accessed with a self receiver
579 self.structs
.insert(local_def(variant
.node
.id
), Vec
::new());
584 let child
= self.add_child(name
, parent
,
585 ForbidDuplicateTypesAndValues
,
587 // variants are always treated as importable to allow them to be glob
589 child
.define_value(DefVariant(item_id
,
590 local_def(variant
.node
.id
), is_exported
),
591 variant
.span
, DefModifiers
::PUBLIC
| DefModifiers
::IMPORTABLE
);
592 child
.define_type(DefVariant(item_id
,
593 local_def(variant
.node
.id
), is_exported
),
594 variant
.span
, DefModifiers
::PUBLIC
| DefModifiers
::IMPORTABLE
);
597 /// Constructs the reduced graph for one foreign item.
598 fn build_reduced_graph_for_foreign_item(&mut self,
599 foreign_item
: &ForeignItem
,
600 parent
: &Rc
<Module
>) {
601 let name
= foreign_item
.ident
.name
;
602 let is_public
= foreign_item
.vis
== ast
::Public
;
603 let modifiers
= if is_public
{
606 DefModifiers
::empty()
607 } | DefModifiers
::IMPORTABLE
;
609 self.add_child(name
, parent
, ForbidDuplicateValues
,
612 let def
= match foreign_item
.node
{
613 ForeignItemFn(..) => {
614 DefFn(local_def(foreign_item
.id
), false)
616 ForeignItemStatic(_
, m
) => {
617 DefStatic(local_def(foreign_item
.id
), m
)
620 name_bindings
.define_value(def
, foreign_item
.span
, modifiers
);
623 fn build_reduced_graph_for_block(&mut self, block
: &Block
, parent
: &Rc
<Module
>) -> Rc
<Module
> {
624 if self.block_needs_anonymous_module(block
) {
625 let block_id
= block
.id
;
627 debug
!("(building reduced graph for block) creating a new \
628 anonymous module for block {}",
631 let new_module
= Rc
::new(Module
::new(
632 BlockParentLink(parent
.downgrade(), block_id
),
637 parent
.anonymous_children
.borrow_mut().insert(block_id
, new_module
.clone());
644 fn handle_external_def(&mut self,
647 child_name_bindings
: &NameBindings
,
650 new_parent
: &Rc
<Module
>) {
651 debug
!("(building reduced graph for \
652 external crate) building external def {}, priv {:?}",
654 let is_public
= vis
== ast
::Public
;
655 let modifiers
= if is_public
{
658 DefModifiers
::empty()
659 } | DefModifiers
::IMPORTABLE
;
660 let is_exported
= is_public
&& match new_parent
.def_id
.get() {
662 Some(did
) => self.external_exports
.contains(&did
)
665 self.external_exports
.insert(def
.def_id());
668 let kind
= match def
{
669 DefTy(_
, true) => EnumModuleKind
,
670 DefTy(_
, false) | DefStruct(..) => TypeModuleKind
,
671 _
=> NormalModuleKind
675 DefMod(def_id
) | DefForeignMod(def_id
) | DefStruct(def_id
) |
676 DefTy(def_id
, _
) => {
677 let type_def
= child_name_bindings
.type_def
.borrow().clone();
679 Some(TypeNsDef { module_def: Some(module_def), .. }
) => {
680 debug
!("(building reduced graph for external crate) \
681 already created module");
682 module_def
.def_id
.set(Some(def_id
));
685 debug
!("(building reduced graph for \
686 external crate) building module \
687 {} {}", final_ident
, is_public
);
688 let parent_link
= self.get_parent_link(new_parent
, name
);
690 child_name_bindings
.define_module(parent_link
,
703 DefMod(_
) | DefForeignMod(_
) => {}
704 DefVariant(_
, variant_id
, is_struct
) => {
705 debug
!("(building reduced graph for external crate) building \
708 // variants are always treated as importable to allow them to be
710 let modifiers
= DefModifiers
::PUBLIC
| DefModifiers
::IMPORTABLE
;
712 child_name_bindings
.define_type(def
, DUMMY_SP
, modifiers
);
713 // Not adding fields for variants as they are not accessed with a self receiver
714 self.structs
.insert(variant_id
, Vec
::new());
716 child_name_bindings
.define_value(def
, DUMMY_SP
, modifiers
);
719 DefFn(ctor_id
, true) => {
720 child_name_bindings
.define_value(
721 csearch
::get_tuple_struct_definition_if_ctor(&self.session
.cstore
, ctor_id
)
722 .map_or(def
, |_
| DefStruct(ctor_id
)), DUMMY_SP
, modifiers
);
724 DefFn(..) | DefStatic(..) | DefConst(..) | DefAssociatedConst(..) |
726 debug
!("(building reduced graph for external \
727 crate) building value (fn/static) {}", final_ident
);
728 // impl methods have already been defined with the correct importability modifier
729 let mut modifiers
= match *child_name_bindings
.value_def
.borrow() {
730 Some(ref def
) => (modifiers
& !DefModifiers
::IMPORTABLE
) |
731 (def
.modifiers
& DefModifiers
::IMPORTABLE
),
734 if new_parent
.kind
.get() != NormalModuleKind
{
735 modifiers
= modifiers
& !DefModifiers
::IMPORTABLE
;
737 child_name_bindings
.define_value(def
, DUMMY_SP
, modifiers
);
739 DefTrait(def_id
) => {
740 debug
!("(building reduced graph for external \
741 crate) building type {}", final_ident
);
743 // If this is a trait, add all the trait item names to the trait
746 let trait_item_def_ids
=
747 csearch
::get_trait_item_def_ids(&self.session
.cstore
, def_id
);
748 for trait_item_def
in &trait_item_def_ids
{
749 let trait_item_name
= csearch
::get_trait_name(&self.session
.cstore
,
750 trait_item_def
.def_id());
752 debug
!("(building reduced graph for external crate) ... \
753 adding trait item '{}'",
754 token
::get_name(trait_item_name
));
756 self.trait_item_map
.insert((trait_item_name
, def_id
),
757 trait_item_def
.def_id());
760 self.external_exports
.insert(trait_item_def
.def_id());
764 child_name_bindings
.define_type(def
, DUMMY_SP
, modifiers
);
766 // Define a module if necessary.
767 let parent_link
= self.get_parent_link(new_parent
, name
);
768 child_name_bindings
.set_module_kind(parent_link
,
775 DefTy(..) | DefAssociatedTy(..) => {
776 debug
!("(building reduced graph for external \
777 crate) building type {}", final_ident
);
779 child_name_bindings
.define_type(def
, DUMMY_SP
, modifiers
);
781 DefStruct(def_id
) => {
782 debug
!("(building reduced graph for external \
783 crate) building type and value for {}",
785 child_name_bindings
.define_type(def
, DUMMY_SP
, modifiers
);
786 let fields
= csearch
::get_struct_fields(&self.session
.cstore
, def_id
).iter().map(|f
| {
788 }).collect
::<Vec
<_
>>();
790 if fields
.is_empty() {
791 child_name_bindings
.define_value(def
, DUMMY_SP
, modifiers
);
794 // Record the def ID and fields of this struct.
795 self.structs
.insert(def_id
, fields
);
797 DefLocal(..) | DefPrimTy(..) | DefTyParam(..) |
798 DefUse(..) | DefUpvar(..) | DefRegion(..) |
799 DefLabel(..) | DefSelfTy(..) => {
800 panic
!("didn't expect `{:?}`", def
);
805 /// Builds the reduced graph for a single item in an external crate.
806 fn build_reduced_graph_for_external_crate_def(&mut self,
810 def_visibility
: Visibility
) {
813 // Add the new child item, if necessary.
815 DefForeignMod(def_id
) => {
816 // Foreign modules have no names. Recur and populate
818 csearch
::each_child_of_item(&self.session
.cstore
,
823 self.build_reduced_graph_for_external_crate_def(
831 let child_name_bindings
=
837 self.handle_external_def(def
,
839 &*child_name_bindings
,
840 &token
::get_name(name
),
847 debug
!("(building reduced graph for external crate) \
851 debug
!("(building reduced graph for external crate) \
857 /// Builds the reduced graph rooted at the given external module.
858 fn populate_external_module(&mut self, module
: &Rc
<Module
>) {
859 debug
!("(populating external module) attempting to populate {}",
860 module_to_string(&**module
));
862 let def_id
= match module
.def_id
.get() {
864 debug
!("(populating external module) ... no def ID!");
867 Some(def_id
) => def_id
,
870 csearch
::each_child_of_item(&self.session
.cstore
,
872 |def_like
, child_name
, visibility
| {
873 debug
!("(populating external module) ... found ident: {}",
874 token
::get_name(child_name
));
875 self.build_reduced_graph_for_external_crate_def(module
,
880 module
.populated
.set(true)
883 /// Ensures that the reduced graph rooted at the given external module
884 /// is built, building it if it is not.
885 fn populate_module_if_necessary(&mut self, module
: &Rc
<Module
>) {
886 if !module
.populated
.get() {
887 self.populate_external_module(module
)
889 assert
!(module
.populated
.get())
892 /// Builds the reduced graph rooted at the 'use' directive for an external
894 fn build_reduced_graph_for_external_crate(&mut self, root
: &Rc
<Module
>) {
895 csearch
::each_top_level_item_of_crate(&self.session
.cstore
,
900 |def_like
, name
, visibility
| {
901 self.build_reduced_graph_for_external_crate_def(root
, def_like
, name
, visibility
)
905 /// Creates and adds an import directive to the given module.
906 fn build_import_directive(&mut self,
908 module_path
: Vec
<Name
>,
909 subclass
: ImportDirectiveSubclass
,
913 shadowable
: Shadowable
) {
914 module_
.imports
.borrow_mut().push(ImportDirective
::new(module_path
,
920 self.unresolved_imports
+= 1;
921 // Bump the reference count on the name. Or, if this is a glob, set
922 // the appropriate flag.
925 SingleImport(target
, _
) => {
926 debug
!("(building import directive) building import directive: {}::{}",
927 names_to_string(&module_
.imports
.borrow().last().unwrap().module_path
),
928 token
::get_name(target
));
930 let mut import_resolutions
= module_
.import_resolutions
.borrow_mut();
931 match import_resolutions
.get_mut(&target
) {
932 Some(resolution
) => {
933 debug
!("(building import directive) bumping reference");
934 resolution
.outstanding_references
+= 1;
936 // the source of this name is different now
937 resolution
.type_id
= id
;
938 resolution
.value_id
= id
;
939 resolution
.is_public
= is_public
;
944 debug
!("(building import directive) creating new");
945 let mut resolution
= ImportResolution
::new(id
, is_public
);
946 resolution
.outstanding_references
= 1;
947 import_resolutions
.insert(target
, resolution
);
950 // Set the glob flag. This tells us that we don't know the
951 // module's exports ahead of time.
953 module_
.glob_count
.set(module_
.glob_count
.get() + 1);
959 struct BuildReducedGraphVisitor
<'a
, 'b
:'a
, 'tcx
:'b
> {
960 builder
: GraphBuilder
<'a
, 'b
, 'tcx
>,
964 impl<'a
, 'b
, 'v
, 'tcx
> Visitor
<'v
> for BuildReducedGraphVisitor
<'a
, 'b
, 'tcx
> {
965 fn visit_item(&mut self, item
: &Item
) {
966 let p
= self.builder
.build_reduced_graph_for_item(item
, &self.parent
);
967 let old_parent
= replace(&mut self.parent
, p
);
968 visit
::walk_item(self, item
);
969 self.parent
= old_parent
;
972 fn visit_foreign_item(&mut self, foreign_item
: &ForeignItem
) {
973 self.builder
.build_reduced_graph_for_foreign_item(foreign_item
, &self.parent
);
976 fn visit_block(&mut self, block
: &Block
) {
977 let np
= self.builder
.build_reduced_graph_for_block(block
, &self.parent
);
978 let old_parent
= replace(&mut self.parent
, np
);
979 visit
::walk_block(self, block
);
980 self.parent
= old_parent
;
984 pub fn build_reduced_graph(resolver
: &mut Resolver
, krate
: &ast
::Crate
) {
987 }.build_reduced_graph(krate
);
990 pub fn populate_module_if_necessary(resolver
: &mut Resolver
, module
: &Rc
<Module
>) {
993 }.populate_module_if_necessary(module
);