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`
This commit is contained in:
Nick Cameron 2016-04-26 10:14:44 +12:00
parent 91b5ed5ce3
commit 5065f0c2a2
5 changed files with 92 additions and 19 deletions

View file

@ -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,

View file

@ -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 {

View file

@ -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");

View file

@ -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));

View file

@ -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.