librustc: Implement lazy module loading.
This commit is contained in:
parent
1bbb1e06f1
commit
ff7b8d6d88
@ -471,12 +471,18 @@ pub struct Module {
|
||||
|
||||
// The index of the import we're resolving.
|
||||
resolved_import_count: uint,
|
||||
|
||||
// Whether this module is populated. If not populated, any attempt to
|
||||
// access the children must be preceded with a
|
||||
// `populate_module_if_necessary` call.
|
||||
populated: bool,
|
||||
}
|
||||
|
||||
pub fn Module(parent_link: ParentLink,
|
||||
def_id: Option<def_id>,
|
||||
kind: ModuleKind)
|
||||
-> Module {
|
||||
kind: ModuleKind,
|
||||
external: bool)
|
||||
-> Module {
|
||||
Module {
|
||||
parent_link: parent_link,
|
||||
def_id: def_id,
|
||||
@ -488,6 +494,7 @@ pub fn Module(parent_link: ParentLink,
|
||||
import_resolutions: @mut HashMap::new(),
|
||||
glob_count: 0,
|
||||
resolved_import_count: 0,
|
||||
populated: !external,
|
||||
}
|
||||
}
|
||||
|
||||
@ -534,9 +541,10 @@ impl NameBindings {
|
||||
parent_link: ParentLink,
|
||||
def_id: Option<def_id>,
|
||||
kind: ModuleKind,
|
||||
external: bool,
|
||||
sp: span) {
|
||||
// Merges the module with the existing type def or creates a new one.
|
||||
let module_ = @mut Module(parent_link, def_id, kind);
|
||||
let module_ = @mut Module(parent_link, def_id, kind, external);
|
||||
match self.type_def {
|
||||
None => {
|
||||
self.type_def = Some(TypeNsDef {
|
||||
@ -563,10 +571,11 @@ impl NameBindings {
|
||||
parent_link: ParentLink,
|
||||
def_id: Option<def_id>,
|
||||
kind: ModuleKind,
|
||||
external: bool,
|
||||
_sp: span) {
|
||||
match self.type_def {
|
||||
None => {
|
||||
let module = @mut Module(parent_link, def_id, kind);
|
||||
let module = @mut Module(parent_link, def_id, kind, external);
|
||||
self.type_def = Some(TypeNsDef {
|
||||
privacy: privacy,
|
||||
module_def: Some(module),
|
||||
@ -577,7 +586,10 @@ impl NameBindings {
|
||||
Some(type_def) => {
|
||||
match type_def.module_def {
|
||||
None => {
|
||||
let module = @mut Module(parent_link, def_id, kind);
|
||||
let module = @mut Module(parent_link,
|
||||
def_id,
|
||||
kind,
|
||||
external);
|
||||
self.type_def = Some(TypeNsDef {
|
||||
privacy: privacy,
|
||||
module_def: Some(module),
|
||||
@ -799,6 +811,7 @@ pub fn Resolver(session: Session,
|
||||
NoParentLink,
|
||||
Some(def_id { crate: 0, node: 0 }),
|
||||
NormalModuleKind,
|
||||
false,
|
||||
crate.span);
|
||||
|
||||
let current_module = graph_root.get_module();
|
||||
@ -1164,6 +1177,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def_id),
|
||||
NormalModuleKind,
|
||||
false,
|
||||
sp);
|
||||
|
||||
let new_parent =
|
||||
@ -1186,6 +1200,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def_id),
|
||||
ExternModuleKind,
|
||||
false,
|
||||
sp);
|
||||
|
||||
ModuleReducedGraphParent(name_bindings.get_module())
|
||||
@ -1310,6 +1325,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def_id),
|
||||
ImplModuleKind,
|
||||
false,
|
||||
sp);
|
||||
|
||||
ModuleReducedGraphParent(
|
||||
@ -1367,6 +1383,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(local_def(item.id)),
|
||||
TraitModuleKind,
|
||||
false,
|
||||
sp);
|
||||
let module_parent = ModuleReducedGraphParent(name_bindings.
|
||||
get_module());
|
||||
@ -1556,7 +1573,8 @@ impl Resolver {
|
||||
(self.get_module_from_parent(parent), name);
|
||||
let external_module = @mut Module(parent_link,
|
||||
Some(def_id),
|
||||
NormalModuleKind);
|
||||
NormalModuleKind,
|
||||
false);
|
||||
|
||||
parent.external_module_children.insert(
|
||||
name,
|
||||
@ -1620,7 +1638,8 @@ impl Resolver {
|
||||
let new_module = @mut Module(
|
||||
BlockParentLink(parent_module, block_id),
|
||||
None,
|
||||
AnonymousModuleKind);
|
||||
AnonymousModuleKind,
|
||||
false);
|
||||
parent_module.anonymous_children.insert(block_id, new_module);
|
||||
new_parent = ModuleReducedGraphParent(new_module);
|
||||
} else {
|
||||
@ -1656,6 +1675,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def_id),
|
||||
NormalModuleKind,
|
||||
true,
|
||||
dummy_sp());
|
||||
}
|
||||
}
|
||||
@ -1717,6 +1737,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def_id),
|
||||
TraitModuleKind,
|
||||
true,
|
||||
dummy_sp())
|
||||
}
|
||||
def_ty(_) => {
|
||||
@ -1755,8 +1776,19 @@ impl Resolver {
|
||||
match def_like {
|
||||
dl_def(def) => {
|
||||
// Add the new child item, if necessary.
|
||||
let optional_module = match def {
|
||||
def_foreign_mod(*) => Some(root),
|
||||
match def {
|
||||
def_foreign_mod(def_id) => {
|
||||
// Foreign modules have no names. Recur and populate
|
||||
// eagerly.
|
||||
do csearch::each_child_of_item(self.session.cstore,
|
||||
def_id)
|
||||
|def_like, child_ident| {
|
||||
self.build_reduced_graph_for_external_crate_def(
|
||||
root,
|
||||
def_like,
|
||||
child_ident)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let (child_name_bindings, new_parent) =
|
||||
self.add_child(ident,
|
||||
@ -1770,28 +1802,6 @@ impl Resolver {
|
||||
self.session.str_of(ident),
|
||||
ident,
|
||||
new_parent);
|
||||
|
||||
/*println(fmt!(">>> child item added: %s",
|
||||
self.session.str_of(ident)));*/
|
||||
|
||||
child_name_bindings.get_module_if_available()
|
||||
}
|
||||
};
|
||||
|
||||
match optional_module {
|
||||
None => {}
|
||||
Some(module) => {
|
||||
do csearch::each_child_of_item(self.session.cstore,
|
||||
def_id_of_def(def))
|
||||
|def_like, child_ident| {
|
||||
/*println(fmt!(">>> each_child_of_item: %s %s",
|
||||
self.session.str_of(ident),
|
||||
self.session.str_of(child_ident)));*/
|
||||
self.build_reduced_graph_for_external_crate_def(
|
||||
module,
|
||||
def_like,
|
||||
child_ident)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1844,6 +1854,7 @@ impl Resolver {
|
||||
parent_link,
|
||||
Some(def),
|
||||
ImplModuleKind,
|
||||
true,
|
||||
dummy_sp());
|
||||
type_module =
|
||||
child_name_bindings.
|
||||
@ -1890,6 +1901,31 @@ impl Resolver {
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds the reduced graph rooted at the given external module.
|
||||
fn populate_external_module(@mut self, module: @mut Module) {
|
||||
let def_id = match module.def_id {
|
||||
None => return,
|
||||
Some(def_id) => def_id,
|
||||
};
|
||||
|
||||
do csearch::each_child_of_item(self.session.cstore, def_id)
|
||||
|def_like, child_ident| {
|
||||
self.build_reduced_graph_for_external_crate_def(module,
|
||||
def_like,
|
||||
child_ident)
|
||||
}
|
||||
module.populated = true
|
||||
}
|
||||
|
||||
/// Ensures that the reduced graph rooted at the given external module
|
||||
/// is built, building it if it is not.
|
||||
fn populate_module_if_necessary(@mut self, module: @mut Module) {
|
||||
if !module.populated {
|
||||
self.populate_external_module(module)
|
||||
}
|
||||
assert!(module.populated)
|
||||
}
|
||||
|
||||
/// Builds the reduced graph rooted at the 'use' directive for an external
|
||||
/// crate.
|
||||
pub fn build_reduced_graph_for_external_crate(@mut self,
|
||||
@ -1999,6 +2035,7 @@ impl Resolver {
|
||||
self.module_to_str(module_));
|
||||
self.resolve_imports_for_module(module_);
|
||||
|
||||
self.populate_module_if_necessary(module_);
|
||||
for (_, &child_node) in module_.children.iter() {
|
||||
match child_node.get_module_if_available() {
|
||||
None => {
|
||||
@ -2224,6 +2261,7 @@ impl Resolver {
|
||||
let mut type_result = UnknownResult;
|
||||
|
||||
// Search for direct children of the containing module.
|
||||
self.populate_module_if_necessary(containing_module);
|
||||
match containing_module.children.find(&source) {
|
||||
None => {
|
||||
// Continue.
|
||||
@ -2542,6 +2580,7 @@ impl Resolver {
|
||||
};
|
||||
|
||||
// Add all children from the containing module.
|
||||
self.populate_module_if_necessary(containing_module);
|
||||
for (&ident, name_bindings) in containing_module.children.iter() {
|
||||
merge_import_resolution(ident, *name_bindings);
|
||||
}
|
||||
@ -2775,6 +2814,7 @@ impl Resolver {
|
||||
|
||||
// The current module node is handled specially. First, check for
|
||||
// its immediate children.
|
||||
self.populate_module_if_necessary(module_);
|
||||
match module_.children.find(&name) {
|
||||
Some(name_bindings)
|
||||
if name_bindings.defined_in_namespace(namespace) => {
|
||||
@ -3029,6 +3069,7 @@ impl Resolver {
|
||||
self.module_to_str(module_));
|
||||
|
||||
// First, check the direct children of the module.
|
||||
self.populate_module_if_necessary(module_);
|
||||
match module_.children.find(&name) {
|
||||
Some(name_bindings)
|
||||
if name_bindings.defined_in_namespace(namespace) => {
|
||||
@ -3118,6 +3159,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
// Descend into children and anonymous children.
|
||||
self.populate_module_if_necessary(module_);
|
||||
for (_, &child_node) in module_.children.iter() {
|
||||
match child_node.get_module_if_available() {
|
||||
None => {
|
||||
@ -3176,6 +3218,7 @@ impl Resolver {
|
||||
}
|
||||
|
||||
self.record_exports_for_module(module_);
|
||||
self.populate_module_if_necessary(module_);
|
||||
|
||||
for (_, &child_name_bindings) in module_.children.iter() {
|
||||
match child_name_bindings.get_module_if_available() {
|
||||
@ -3289,6 +3332,7 @@ impl Resolver {
|
||||
// Nothing to do.
|
||||
}
|
||||
Some(name) => {
|
||||
self.populate_module_if_necessary(orig_module);
|
||||
match orig_module.children.find(&name) {
|
||||
None => {
|
||||
debug!("!!! (with scope) didn't find `%s` in `%s`",
|
||||
@ -4569,6 +4613,7 @@ impl Resolver {
|
||||
xray: XrayFlag)
|
||||
-> NameDefinition {
|
||||
// First, search children.
|
||||
self.populate_module_if_necessary(containing_module);
|
||||
match containing_module.children.find(&name) {
|
||||
Some(child_name_bindings) => {
|
||||
match (child_name_bindings.def_for_namespace(namespace),
|
||||
@ -5233,7 +5278,9 @@ impl Resolver {
|
||||
}
|
||||
|
||||
// Look for trait children.
|
||||
for (_, &child_name_bindings) in search_module.children.iter() {
|
||||
self.populate_module_if_necessary(search_module);
|
||||
for (_, &child_name_bindings) in
|
||||
search_module.children.iter() {
|
||||
match child_name_bindings.def_for_namespace(TypeNS) {
|
||||
Some(def) => {
|
||||
match def {
|
||||
@ -5432,6 +5479,7 @@ impl Resolver {
|
||||
debug!("Dump of module `%s`:", self.module_to_str(module_));
|
||||
|
||||
debug!("Children:");
|
||||
self.populate_module_if_necessary(module_);
|
||||
for (&name, _) in module_.children.iter() {
|
||||
debug!("* %s", self.session.str_of(name));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user