]> git.lizzy.rs Git - rust.git/commitdiff
save-analysis-json: thread through -z option
authorNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 22:14:44 +0000 (10:14 +1200)
committerNick Cameron <ncameron@mozilla.com>
Mon, 25 Apr 2016 22:14:44 +0000 (10:14 +1200)
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`

src/librustc/session/config.rs
src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_save_analysis/json_dumper.rs
src/librustc_save_analysis/lib.rs

index 347221ad5d48acaaa41af4165903cba2335dd1e3..9f29f9050e6a6df659a74f03f7c504a7de0db921 100644 (file)
@@ -618,7 +618,9 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
     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,
index 5fc2a955c0602ed5a713413065f5c2abe7f0018a..81a21a6eb2ed86d262996c217b365e1b46a8376b 100644 (file)
@@ -141,8 +141,7 @@ macro_rules! controller_entry_point {
                                                            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 @@ macro_rules! controller_entry_point {
              "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 @@ macro_rules! controller_entry_point {
     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 {
index 0e100f48ac38d64488defa10f3e3d7775c0e49ff..b04503d12ae208a86f1d88638a3d33d6df10957d 100644 (file)
@@ -483,7 +483,7 @@ fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
             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 @@ fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
                                         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 @@ fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
     }
 }
 
+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");
index e040b392ae7218e8d3d8812345ea893982412bbd..212e3eea8f99a296dd727c4f01bbab7dc104b9a3 100644 (file)
 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));
index db7a7a64998a1658d699c84ecf3cc962fa54d150..d529f66a64069cde91cb5039fa0de33a9a1d3547 100644 (file)
@@ -688,12 +688,28 @@ fn visit_pat(&mut self, p: &ast::Pat) {
     }
 }
 
+#[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.