about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/back/link.rs4
-rw-r--r--src/librustc/driver/driver.rs38
-rw-r--r--src/librustc/driver/session.rs5
-rw-r--r--src/librustc/lib.rs100
-rw-r--r--src/librustc/middle/trans/base.rs2
-rw-r--r--src/libsyntax/parse/mod.rs24
-rw-r--r--src/test/run-make/crate-data-smoke/Makefile10
-rw-r--r--src/test/run-make/crate-data-smoke/crate.rs7
-rw-r--r--src/test/run-make/crate-data-smoke/lib.rs2
-rw-r--r--src/test/run-make/crate-data-smoke/rlib.rs2
10 files changed, 127 insertions, 67 deletions
diff --git a/src/librustc/back/link.rs b/src/librustc/back/link.rs
index ccd6c66603f..6647a21e26a 100644
--- a/src/librustc/back/link.rs
+++ b/src/librustc/back/link.rs
@@ -447,7 +447,7 @@ pub mod write {
  */
 
 pub fn build_link_meta(sess: Session,
-                       c: &ast::Crate,
+                       attrs: &[ast::Attribute],
                        output: &Path,
                        symbol_hasher: &mut Sha256)
                        -> LinkMeta {
@@ -458,7 +458,7 @@ pub fn build_link_meta(sess: Session,
         truncated_hash_result(symbol_hasher).to_managed()
     }
 
-    let pkgid = match attr::find_pkgid(c.attrs) {
+    let pkgid = match attr::find_pkgid(attrs) {
         None => {
             let stem = session::expect(
                 sess,
diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs
index f02a497ee46..bcaaa9224d9 100644
--- a/src/librustc/driver/driver.rs
+++ b/src/librustc/driver/driver.rs
@@ -165,7 +165,7 @@ pub fn phase_2_configure_and_expand(sess: Session,
     let time_passes = sess.time_passes();
 
     *sess.building_library = session::building_library(sess.opts, &crate);
-    *sess.outputs = session::collect_outputs(sess.opts, &crate);
+    *sess.outputs = session::collect_outputs(sess.opts, crate.attrs);
 
     time(time_passes, "gated feature checking", (), |_|
          front::feature_gate::check_crate(sess, &crate));
@@ -446,42 +446,6 @@ pub fn compile_input(sess: Session, cfg: ast::CrateConfig, input: &input,
     let (outputs, trans) = {
         let expanded_crate = {
             let crate = phase_1_parse_input(sess, cfg.clone(), input);
-            let (crate_id, crate_name, crate_file_name) = sess.opts.print_metas;
-            // these nasty nested conditions are to avoid doing extra work
-            if crate_id || crate_name || crate_file_name {
-                let t_outputs = build_output_filenames(input, outdir, output, crate.attrs, sess);
-                if crate_id || crate_name {
-                    let pkgid = match attr::find_pkgid(crate.attrs) {
-                        Some(pkgid) => pkgid,
-                        None => fail!("No crate_id and --crate-id or --crate-name requested")
-                    };
-                    if crate_id {
-                        println(pkgid.to_str());
-                    }
-                    if crate_name {
-                        println(pkgid.name);
-                    }
-                }
-
-                if crate_file_name {
-                    let lm = link::build_link_meta(sess, &crate, &t_outputs.obj_filename,
-                                                   &mut ::util::sha2::Sha256::new());
-                    // if the vector is empty we default to OutputExecutable.
-                    let style = sess.opts.outputs.get_opt(0).unwrap_or(&OutputExecutable);
-                    let fname = link::filename_for_input(&sess, *style, &lm,
-                                                         &t_outputs.out_filename);
-                    println!("{}", fname.display());
-
-                    // we already maybe printed the first one, so skip it
-                    for style in sess.opts.outputs.iter().skip(1) {
-                        let fname = link::filename_for_input(&sess, *style, &lm,
-                                                             &t_outputs.out_filename);
-                        println!("{}", fname.display());
-                    }
-                }
-
-                return;
-            }
             if stop_after_phase_1(sess) { return; }
             phase_2_configure_and_expand(sess, cfg, crate)
         };
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 58f09a52f23..ba9ffe81a99 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -421,14 +421,15 @@ pub fn building_library(options: &options, crate: &ast::Crate) -> bool {
     }
 }
 
-pub fn collect_outputs(options: &options, crate: &ast::Crate) -> ~[OutputStyle] {
+pub fn collect_outputs(options: &options,
+                       attrs: &[ast::Attribute]) -> ~[OutputStyle] {
     // If we're generating a test executable, then ignore all other output
     // styles at all other locations
     if options.test {
         return ~[OutputExecutable];
     }
     let mut base = options.outputs.clone();
-    let mut iter = crate.attrs.iter().filter_map(|a| {
+    let mut iter = attrs.iter().filter_map(|a| {
         if "crate_type" == a.name() {
             match a.value_str() {
                 Some(n) if "rlib" == n => Some(OutputRlib),
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index f0bff76685f..49288e35f44 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -21,14 +21,12 @@
 extern mod extra;
 extern mod syntax;
 
-use driver::driver::{host_triple, optgroups, early_error};
-use driver::driver::{str_input, file_input, build_session_options};
-use driver::driver::{build_session, build_configuration, parse_pretty};
-use driver::driver::{PpMode, pretty_print_input, list_metadata};
-use driver::driver::{compile_input};
+use back::link;
 use driver::session;
 use middle::lint;
 
+use d = driver::driver;
+
 use std::cast;
 use std::comm;
 use std::io;
@@ -41,9 +39,12 @@ use std::task;
 use std::vec;
 use extra::getopts::groups;
 use extra::getopts;
+use syntax::ast;
+use syntax::attr;
 use syntax::codemap;
 use syntax::diagnostic::Emitter;
 use syntax::diagnostic;
+use syntax::parse;
 
 pub mod middle {
     pub mod trans;
@@ -137,7 +138,7 @@ pub fn version(argv0: &str) {
         None => "unknown version"
     };
     println!("{} {}", argv0, vers);
-    println!("host: {}", host_triple());
+    println!("host: {}", d::host_triple());
 }
 
 pub fn usage(argv0: &str) {
@@ -146,7 +147,7 @@ pub fn usage(argv0: &str) {
 Additional help:
     -W help             Print 'lint' options and default settings
     -Z help             Print internal options for debugging rustc\n",
-              groups::usage(message, optgroups()));
+              groups::usage(message, d::optgroups()));
 }
 
 pub fn describe_warnings() {
@@ -206,10 +207,10 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
     if args.is_empty() { usage(binary); return; }
 
     let matches =
-        &match getopts::groups::getopts(args, optgroups()) {
+        &match getopts::groups::getopts(args, d::optgroups()) {
           Ok(m) => m,
           Err(f) => {
-            early_error(demitter, f.to_err_msg());
+            d::early_error(demitter, f.to_err_msg());
           }
         };
 
@@ -246,48 +247,97 @@ pub fn run_compiler(args: &[~str], demitter: @diagnostic::Emitter) {
         return;
     }
     let input = match matches.free.len() {
-      0u => early_error(demitter, "no input filename given"),
+      0u => d::early_error(demitter, "no input filename given"),
       1u => {
         let ifile = matches.free[0].as_slice();
         if "-" == ifile {
             let src = str::from_utf8_owned(io::stdin().read_to_end());
-            str_input(src.to_managed())
+            d::str_input(src.to_managed())
         } else {
-            file_input(Path::new(ifile))
+            d::file_input(Path::new(ifile))
         }
       }
-      _ => early_error(demitter, "multiple input filenames provided")
+      _ => d::early_error(demitter, "multiple input filenames provided")
     };
 
-    let sopts = build_session_options(binary, matches, demitter);
-    let sess = build_session(sopts, demitter);
+    let sopts = d::build_session_options(binary, matches, demitter);
+    let sess = d::build_session(sopts, demitter);
     let odir = matches.opt_str("out-dir").map(|o| Path::new(o));
     let ofile = matches.opt_str("o").map(|o| Path::new(o));
-    let cfg = build_configuration(sess);
+    let cfg = d::build_configuration(sess);
     let pretty = matches.opt_default("pretty", "normal").map(|a| {
-        parse_pretty(sess, a)
+        d::parse_pretty(sess, a)
     });
     match pretty {
-      Some::<PpMode>(ppm) => {
-        pretty_print_input(sess, cfg, &input, ppm);
+      Some::<d::PpMode>(ppm) => {
+        d::pretty_print_input(sess, cfg, &input, ppm);
         return;
       }
-      None::<PpMode> => {/* continue */ }
+      None::<d::PpMode> => {/* continue */ }
     }
     let ls = matches.opt_present("ls");
     if ls {
         match input {
-          file_input(ref ifile) => {
-            list_metadata(sess, &(*ifile), @mut io::stdout() as @mut io::Writer);
+          d::file_input(ref ifile) => {
+            d::list_metadata(sess, &(*ifile),
+                                  @mut io::stdout() as @mut io::Writer);
           }
-          str_input(_) => {
-            early_error(demitter, "can not list metadata for stdin");
+          d::str_input(_) => {
+            d::early_error(demitter, "can not list metadata for stdin");
           }
         }
         return;
     }
+    let (crate_id, crate_name, crate_file_name) = sopts.print_metas;
+    // these nasty nested conditions are to avoid doing extra work
+    if crate_id || crate_name || crate_file_name {
+        let attrs = parse_crate_attrs(sess, &input);
+        let t_outputs = d::build_output_filenames(&input, &odir, &ofile,
+                                                  attrs, sess);
+        if crate_id || crate_name {
+            let pkgid = match attr::find_pkgid(attrs) {
+                Some(pkgid) => pkgid,
+                None => {
+                    sess.fatal("No crate_id and --crate-id or \
+                                --crate-name requested")
+                }
+            };
+            if crate_id {
+                println(pkgid.to_str());
+            }
+            if crate_name {
+                println(pkgid.name);
+            }
+        }
+
+        if crate_file_name {
+            let lm = link::build_link_meta(sess, attrs, &t_outputs.obj_filename,
+                                           &mut ::util::sha2::Sha256::new());
+            let outputs = session::collect_outputs(sopts, attrs);
+            for &style in outputs.iter() {
+                let fname = link::filename_for_input(&sess, style, &lm,
+                                                     &t_outputs.out_filename);
+                println!("{}", fname.filename_display());
+            }
+        }
+
+        return;
+    }
+
+    d::compile_input(sess, cfg, &input, &odir, &ofile);
+}
 
-    compile_input(sess, cfg, &input, &odir, &ofile);
+fn parse_crate_attrs(sess: session::Session,
+                     input: &d::input) -> ~[ast::Attribute] {
+    match *input {
+        d::file_input(ref ifile) => {
+            parse::parse_crate_attrs_from_file(ifile, ~[], sess.parse_sess)
+        }
+        d::str_input(src) => {
+            parse::parse_crate_attrs_from_source_str(
+                d::anon_src(), src, ~[], sess.parse_sess)
+        }
+    }
 }
 
 #[deriving(Eq)]
diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs
index 7ab3b4fd69e..7dbe760e027 100644
--- a/src/librustc/middle/trans/base.rs
+++ b/src/librustc/middle/trans/base.rs
@@ -3096,7 +3096,7 @@ pub fn trans_crate(sess: session::Session,
     }
 
     let mut symbol_hasher = Sha256::new();
-    let link_meta = link::build_link_meta(sess, &crate, output,
+    let link_meta = link::build_link_meta(sess, crate.attrs, output,
                                           &mut symbol_hasher);
 
     // Append ".rc" to crate name as LLVM module identifier.
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 612151f83e4..73240a9effd 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -79,6 +79,16 @@ pub fn parse_crate_from_file(
     // why is there no p.abort_if_errors here?
 }
 
+pub fn parse_crate_attrs_from_file(
+    input: &Path,
+    cfg: ast::CrateConfig,
+    sess: @mut ParseSess
+) -> ~[ast::Attribute] {
+    let parser = new_parser_from_file(sess, cfg, input);
+    let (inner, _) = parser.parse_inner_attrs_and_next();
+    return inner;
+}
+
 pub fn parse_crate_from_source_str(
     name: @str,
     source: @str,
@@ -92,6 +102,20 @@ pub fn parse_crate_from_source_str(
     maybe_aborted(p.parse_crate_mod(),p)
 }
 
+pub fn parse_crate_attrs_from_source_str(
+    name: @str,
+    source: @str,
+    cfg: ast::CrateConfig,
+    sess: @mut ParseSess
+) -> ~[ast::Attribute] {
+    let p = new_parser_from_source_str(sess,
+                                       /*bad*/ cfg.clone(),
+                                       name,
+                                       source);
+    let (inner, _) = maybe_aborted(p.parse_inner_attrs_and_next(),p);
+    return inner;
+}
+
 pub fn parse_expr_from_source_str(
     name: @str,
     source: @str,
diff --git a/src/test/run-make/crate-data-smoke/Makefile b/src/test/run-make/crate-data-smoke/Makefile
new file mode 100644
index 00000000000..35ae4accb27
--- /dev/null
+++ b/src/test/run-make/crate-data-smoke/Makefile
@@ -0,0 +1,10 @@
+-include ../tools.mk
+
+all:
+	[ `$(RUSTC) --crate-id crate.rs` = "foo#0.9" ]
+	[ `$(RUSTC) --crate-name crate.rs` = "foo" ]
+	[ `$(RUSTC) --crate-file-name crate.rs` = "foo" ]
+	[ `$(RUSTC) --crate-file-name --lib --test crate.rs` = "foo" ]
+	[ `$(RUSTC) --crate-file-name --test lib.rs` = "mylib" ]
+	$(RUSTC) --crate-file-name lib.rs
+	$(RUSTC) --crate-file-name rlib.rs
diff --git a/src/test/run-make/crate-data-smoke/crate.rs b/src/test/run-make/crate-data-smoke/crate.rs
new file mode 100644
index 00000000000..840f346a601
--- /dev/null
+++ b/src/test/run-make/crate-data-smoke/crate.rs
@@ -0,0 +1,7 @@
+#[crate_id = "foo#0.9"];
+
+// Querying about the crate metadata should *not* parse the entire crate, it
+// only needs the crate attributes (which are guaranteed to be at the top) be
+// sure that if we have an error like a missing module that we can still query
+// about the crate id.
+mod error;
diff --git a/src/test/run-make/crate-data-smoke/lib.rs b/src/test/run-make/crate-data-smoke/lib.rs
new file mode 100644
index 00000000000..11c5682389e
--- /dev/null
+++ b/src/test/run-make/crate-data-smoke/lib.rs
@@ -0,0 +1,2 @@
+#[crate_id = "mylib"];
+#[crate_type = "lib"];
diff --git a/src/test/run-make/crate-data-smoke/rlib.rs b/src/test/run-make/crate-data-smoke/rlib.rs
new file mode 100644
index 00000000000..26a1de1806a
--- /dev/null
+++ b/src/test/run-make/crate-data-smoke/rlib.rs
@@ -0,0 +1,2 @@
+#[crate_id = "mylib"];
+#[crate_type = "rlib"];