From 6a8169db0a201b9fc2fbf581f507e143f0482aae Mon Sep 17 00:00:00 2001
From: Patrick Walton <pcwalton@mimiga.net>
Date: Fri, 30 Aug 2013 12:21:45 -0700
Subject: [PATCH] libsyntax: Remove some more `@fn` uses

---
 src/librustpkg/util.rs      | 91 +++++++++++++++++++++++++------------
 src/libsyntax/diagnostic.rs |  7 ---
 2 files changed, 61 insertions(+), 37 deletions(-)

diff --git a/src/librustpkg/util.rs b/src/librustpkg/util.rs
index 8c6268e7d23..ac11744f16a 100644
--- a/src/librustpkg/util.rs
+++ b/src/librustpkg/util.rs
@@ -16,9 +16,10 @@ use extra::getopts::groups::getopts;
 use syntax::ast_util::*;
 use syntax::codemap::{dummy_sp, Spanned};
 use syntax::ext::base::ExtCtxt;
-use syntax::{ast, attr, codemap, diagnostic, fold};
+use syntax::{ast, attr, codemap, diagnostic, fold, visit};
 use syntax::attr::AttrMetaMethods;
 use syntax::fold::ast_fold;
+use syntax::visit::Visitor;
 use rustc::back::link::output_type_exe;
 use rustc::back::link;
 use rustc::driver::session::{lib_crate, bin_crate};
@@ -28,6 +29,7 @@ use package_source::PkgSrc;
 use workspace::pkg_parent_workspaces;
 use path_util::{installed_library_in_workspace, U_RWX, rust_path, system_library, target_build_dir};
 use messages::error;
+use conditions::nonexistent_package::cond;
 
 pub use target::{OutputType, Main, Lib, Bench, Test, JustOne, lib_name_of, lib_crate_filename};
 use workcache_support::{digest_file_with_date, digest_only_date};
@@ -395,31 +397,28 @@ pub fn compile_crate(ctxt: &BuildContext,
     compile_input(ctxt, exec, pkg_id, crate, workspace, flags, cfgs, opt, what)
 }
 
+struct ViewItemVisitor<'self> {
+    context: &'self BuildContext,
+    parent: &'self PkgId,
+    sess: session::Session,
+    exec: &'self mut workcache::Exec,
+    c: &'self ast::Crate,
+    save: @fn(Path),
+}
 
-/// Collect all `extern mod` directives in `c`, then
-/// try to install their targets, failing if any target
-/// can't be found.
-pub fn find_and_install_dependencies(context: &BuildContext,
-                                     parent: &PkgId,
-                                     sess: session::Session,
-                                     exec: &mut workcache::Exec,
-                                     c: &ast::Crate,
-                                     save: @fn(Path)
-                                     ) {
-    use conditions::nonexistent_package::cond;
-
-    do c.each_view_item() |vi: &ast::view_item| {
+impl<'self> Visitor<()> for ViewItemVisitor<'self> {
+    fn visit_view_item(&mut self, vi: &ast::view_item, env: ()) {
         debug!("A view item!");
         match vi.node {
             // ignore metadata, I guess
             ast::view_item_extern_mod(lib_ident, path_opt, _, _) => {
                 let lib_name = match path_opt {
                     Some(p) => p,
-                    None => sess.str_of(lib_ident)
+                    None => self.sess.str_of(lib_ident)
                 };
                 debug!("Finding and installing... %s", lib_name);
                 // Check standard Rust library path first
-                match system_library(&context.sysroot(), lib_name) {
+                match system_library(&self.context.sysroot(), lib_name) {
                     Some(ref installed_path) => {
                         debug!("It exists: %s", installed_path.to_str());
                         // Say that [path for c] has a discovered dependency on
@@ -428,8 +427,9 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                         // I'm not sure what the right thing is.
                         // Now we know that this crate has a discovered dependency on
                         // installed_path
-                        exec.discover_input("binary", installed_path.to_str(),
-                                                      digest_only_date(installed_path));
+                        self.exec.discover_input("binary",
+                                                 installed_path.to_str(),
+                                                 digest_only_date(installed_path));
                     }
                     None => {
                         // FIXME #8711: need to parse version out of path_opt
@@ -437,35 +437,44 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                                lib_name.to_str());
                         // Try to install it
                         let pkg_id = PkgId::new(lib_name);
-                        let workspaces = pkg_parent_workspaces(&context.context, &pkg_id);
+                        let workspaces = pkg_parent_workspaces(&self.context.context,
+                                                               &pkg_id);
                         let dep_workspace = if workspaces.is_empty() {
                             error(fmt!("Couldn't find package %s, which is needed by %s, \
                                             in any of the workspaces in the RUST_PATH (%?)",
-                                            lib_name, parent.to_str(), rust_path()));
+                                            lib_name,
+                                            self.parent.to_str(),
+                                            rust_path()));
                             cond.raise((pkg_id.clone(), ~"Dependency not found"))
                         }
                         else {
                             workspaces[0]
                         };
                         let (outputs_disc, inputs_disc) =
-                            context.install(PkgSrc::new(dep_workspace.clone(),
-                                false, pkg_id), &JustOne(Path(lib_crate_filename)));
+                            self.context.install(PkgSrc::new(dep_workspace.clone(),
+                                                             false,
+                                                             pkg_id),
+                                                 &JustOne(Path(
+                                                    lib_crate_filename)));
                         debug!("Installed %s, returned %? dependencies and \
                                %? transitive dependencies",
                                lib_name, outputs_disc.len(), inputs_disc.len());
                         for dep in outputs_disc.iter() {
                             debug!("Discovering a binary input: %s", dep.to_str());
-                            exec.discover_input("binary", dep.to_str(),
-                                                digest_only_date(dep));
+                            self.exec.discover_input("binary",
+                                                     dep.to_str(),
+                                                     digest_only_date(dep));
                         }
                         for &(ref what, ref dep) in inputs_disc.iter() {
                             if *what == ~"file" {
-                                exec.discover_input(*what, *dep,
-                                                    digest_file_with_date(&Path(*dep)));
+                                self.exec.discover_input(*what,
+                                                         *dep,
+                                                         digest_file_with_date(&Path(*dep)));
                             }
                             else if *what == ~"binary" {
-                                exec.discover_input(*what, *dep,
-                                                    digest_only_date(&Path(*dep)));
+                                self.exec.discover_input(*what,
+                                                         *dep,
+                                                         digest_only_date(&Path(*dep)));
                             }
                             else {
                                 fail!("Bad kind: %s", *what);
@@ -480,14 +489,36 @@ pub fn find_and_install_dependencies(context: &BuildContext,
                         let install_dir = installed_library.pop();
                         debug!("Installed %s into %s [%?]", lib_name, install_dir.to_str(),
                                datestamp(&installed_library));
-                        save(install_dir);
+                        (self.save)(install_dir);
                     }
                 }}
             // Ignore `use`s
             _ => ()
         }
-        true
+
+        visit::walk_view_item(self, vi, env)
+    }
+}
+
+/// Collect all `extern mod` directives in `c`, then
+/// try to install their targets, failing if any target
+/// can't be found.
+pub fn find_and_install_dependencies(context: &BuildContext,
+                                     parent: &PkgId,
+                                     sess: session::Session,
+                                     exec: &mut workcache::Exec,
+                                     c: &ast::Crate,
+                                     save: @fn(Path)) {
+    debug!("In find_and_install_dependencies...");
+    let mut visitor = ViewItemVisitor {
+        context: context,
+        parent: parent,
+        sess: sess,
+        exec: exec,
+        c: c,
+        save: save,
     };
+    visit::walk_crate(&mut visitor, c, ())
 }
 
 pub fn mk_string_lit(s: @str) -> ast::lit {
diff --git a/src/libsyntax/diagnostic.rs b/src/libsyntax/diagnostic.rs
index 6f066218b7c..aa06e1bee41 100644
--- a/src/libsyntax/diagnostic.rs
+++ b/src/libsyntax/diagnostic.rs
@@ -236,13 +236,6 @@ fn print_diagnostic(topic: &str, lvl: level, msg: &str) {
     print_maybe_styled(fmt!("%s\n", msg), term::attr::Bold);
 }
 
-pub fn collect(messages: @mut ~[~str])
-            -> @fn(Option<(@codemap::CodeMap, Span)>, &str, level) {
-    let f: @fn(Option<(@codemap::CodeMap, Span)>, &str, level) =
-        |_o, msg: &str, _l| { messages.push(msg.to_str()); };
-    f
-}
-
 pub struct DefaultEmitter;
 
 impl Emitter for DefaultEmitter {