about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNick Cameron <ncameron@mozilla.com>2016-04-26 10:14:44 +1200
committerNick Cameron <ncameron@mozilla.com>2016-04-26 10:14:44 +1200
commit5065f0c2a2a37ad160268a214523f45402502be2 (patch)
treea9df057d80f211af3f06930ba8b16069ecd3437b
parent91b5ed5ce38e3833e985c2cf023e1902891f30e2 (diff)
downloadrust-5065f0c2a2a37ad160268a214523f45402502be2.tar.gz
rust-5065f0c2a2a37ad160268a214523f45402502be2.zip
save-analysis-json: thread through -z option
In fact, we make JSOn the default and add an option for save-analysis-csv for the legacy behaviour.

We also rename some bits and pieces `dxr` -> `save-analysis`
-rw-r--r--src/librustc/session/config.rs4
-rw-r--r--src/librustc_driver/driver.rs18
-rw-r--r--src/librustc_driver/lib.rs20
-rw-r--r--src/librustc_save_analysis/json_dumper.rs23
-rw-r--r--src/librustc_save_analysis/lib.rs46
5 files changed, 92 insertions, 19 deletions
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 347221ad5d4..9f29f9050e6 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -618,7 +618,9 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     ls: bool = (false, parse_bool,
         "list the symbols defined by a library crate"),
     save_analysis: bool = (false, parse_bool,
-        "write syntax and type analysis information in addition to normal output"),
+        "write syntax and type analysis (in JSON format) information in addition to normal output"),
+    save_analysis_csv: bool = (false, parse_bool,
+        "write syntax and type analysis (in CSV format) information in addition to normal output"),
     print_move_fragments: bool = (false, parse_bool,
         "print out move-fragment data for every fn"),
     flowgraph_print_loans: bool = (false, parse_bool,
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 5fc2a955c06..81a21a6eb2e 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -141,8 +141,7 @@ pub fn compile_input(sess: &Session,
                                                            dep_graph));
 
         // Discard MTWT tables that aren't required past lowering to HIR.
-        if !sess.opts.debugging_opts.keep_mtwt_tables &&
-           !sess.opts.debugging_opts.save_analysis {
+        if !keep_mtwt_tables(sess) {
             syntax::ext::mtwt::clear_tables();
         }
 
@@ -179,8 +178,7 @@ pub fn compile_input(sess: &Session,
              "early lint checks",
              || lint::check_ast_crate(sess, &expanded_crate));
 
-        let opt_crate = if sess.opts.debugging_opts.keep_ast ||
-                           sess.opts.debugging_opts.save_analysis {
+        let opt_crate = if keep_ast(sess) {
             Some(&expanded_crate)
         } else {
             drop(expanded_crate);
@@ -249,6 +247,18 @@ pub fn compile_input(sess: &Session,
     Ok(())
 }
 
+fn keep_mtwt_tables(sess: &Session) -> bool {
+    sess.opts.debugging_opts.keep_mtwt_tables ||
+    sess.opts.debugging_opts.save_analysis ||
+    sess.opts.debugging_opts.save_analysis_csv
+}
+
+fn keep_ast(sess: &Session) -> bool {
+    sess.opts.debugging_opts.keep_ast ||
+    sess.opts.debugging_opts.save_analysis ||
+    sess.opts.debugging_opts.save_analysis_csv
+}
+
 /// The name used for source code that doesn't originate in a file
 /// (e.g. source from stdin or a string)
 pub fn anon_src() -> String {
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 0e100f48ac3..b04503d12ae 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -483,7 +483,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
             control.after_llvm.stop = Compilation::Stop;
         }
 
-        if sess.opts.debugging_opts.save_analysis {
+        if save_analysis(sess) {
             control.after_analysis.callback = box |state| {
                 time(state.session.time_passes(), "save analysis", || {
                     save::process_crate(state.tcx.unwrap(),
@@ -491,7 +491,8 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                                         state.krate.unwrap(),
                                         state.analysis.unwrap(),
                                         state.crate_name.unwrap(),
-                                        state.out_dir)
+                                        state.out_dir,
+                                        save_analysis_format(state.session))
                 });
             };
             control.after_analysis.run_callback_on_error = true;
@@ -502,6 +503,21 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
     }
 }
 
+fn save_analysis(sess: &Session) -> bool {
+    sess.opts.debugging_opts.save_analysis ||
+    sess.opts.debugging_opts.save_analysis_csv
+}
+
+fn save_analysis_format(sess: &Session) -> save::Format {
+    if sess.opts.debugging_opts.save_analysis {
+        save::Format::Json
+    } else if sess.opts.debugging_opts.save_analysis_csv {
+        save::Format::Csv
+    } else {
+        unreachable!();
+    }
+}
+
 impl RustcDefaultCalls {
     pub fn list_metadata(sess: &Session, matches: &getopts::Matches, input: &Input) -> Compilation {
         let r = matches.opt_strs("Z");
diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs
index e040b392ae7..212e3eea8f9 100644
--- a/src/librustc_save_analysis/json_dumper.rs
+++ b/src/librustc_save_analysis/json_dumper.rs
@@ -19,20 +19,39 @@ use syntax::ast::{CrateNum, NodeId};
 use super::data::{self, SpanData};
 use super::dump::Dump;
 
-pub struct JsonDumper<'a, 'b, W: 'b> {
+pub struct JsonDumper<'a, 'b, W: Write + 'b> {
     output: &'b mut W,
     codemap: &'a CodeMap,
+    first: bool,
 }
 
 impl<'a, 'b, W: Write> JsonDumper<'a, 'b, W> {
     pub fn new(writer: &'b mut W, codemap: &'a CodeMap) -> JsonDumper<'a, 'b, W> {
-        JsonDumper { output: writer, codemap:codemap }
+        if let Err(_) = write!(writer, "[") {
+            error!("Error writing output");
+        }        
+        JsonDumper { output: writer, codemap:codemap, first: true }
+    }
+}
+
+impl<'a, 'b, W: Write> Drop for JsonDumper<'a, 'b, W> {
+    fn drop(&mut self) {
+        if let Err(_) = write!(self.output, "]") {
+            error!("Error writing output");
+        }
     }
 }
 
 macro_rules! impl_fn {
     ($fn_name: ident, $data_type: ident) => {
         fn $fn_name(&mut self, data: data::$data_type) {
+            if self.first {
+                self.first = false;
+            } else {
+                if let Err(_) = write!(self.output, ",") {
+                    error!("Error writing output");
+                }
+            }
             let data = data.lower(self.codemap);
             if let Err(_) = write!(self.output, "{}", as_json(&data)) {
                 error!("Error writing output '{}'", as_json(&data));
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index db7a7a64998..d529f66a640 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -688,12 +688,28 @@ impl<'v> Visitor<'v> for PathCollector {
     }
 }
 
+#[derive(Clone, Copy, Debug)]
+pub enum Format {
+    Csv,
+    Json,
+}
+
+impl Format {
+    fn extension(&self) -> &'static str {
+        match *self {
+            Format::Csv => ".csv",
+            Format::Json => ".json",
+        }
+    }
+}
+
 pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
                                lcx: &'l lowering::LoweringContext<'l>,
                                krate: &ast::Crate,
                                analysis: &'l ty::CrateAnalysis<'l>,
                                cratename: &str,
-                               odir: Option<&Path>) {
+                               odir: Option<&Path>,
+                               format: Format) {
     let _ignore = tcx.dep_graph.in_ignore();
 
     assert!(analysis.glob_map.is_some());
@@ -701,11 +717,11 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
     info!("Dumping crate {}", cratename);
 
     // find a path to dump our data to
-    let mut root_path = match env::var_os("DXR_RUST_TEMP_FOLDER") {
+    let mut root_path = match env::var_os("RUST_SAVE_ANALYSIS_FOLDER") {
         Some(val) => PathBuf::from(val),
         None => match odir {
-            Some(val) => val.join("dxr"),
-            None => PathBuf::from("dxr-temp"),
+            Some(val) => val.join("save-analysis"),
+            None => PathBuf::from("save-analysis-temp"),
         },
     };
 
@@ -729,22 +745,32 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>,
     };
     out_name.push_str(&cratename);
     out_name.push_str(&tcx.sess.opts.cg.extra_filename);
-    out_name.push_str(".csv");
+    out_name.push_str(format.extension());
     root_path.push(&out_name);
     let mut output_file = File::create(&root_path).unwrap_or_else(|e| {
         let disp = root_path.display();
         tcx.sess.fatal(&format!("Could not open {}: {}", disp, e));
     });
     root_path.pop();
+    let output = &mut output_file;
 
     let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess);
     let save_ctxt = SaveContext::new(tcx, lcx);
-    let mut dumper = CsvDumper::new(&mut output_file, utils);
-    let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper);
-    // FIXME: we don't write anything!
 
-    visitor.dump_crate_info(cratename, krate);
-    visit::walk_crate(&mut visitor, krate);
+    macro_rules! dump {
+        ($new_dumper: expr) => {{
+            let mut dumper = $new_dumper;
+            let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper);
+
+            visitor.dump_crate_info(cratename, krate);
+            visit::walk_crate(&mut visitor, krate);            
+        }}
+    }
+
+    match format {
+        Format::Csv => dump!(CsvDumper::new(output, utils)),
+        Format::Json => dump!(JsonDumper::new(output, utils.sess.codemap())),
+    }
 }
 
 // Utility functions for the module.