Skip to content

Minor refactoring/modernization/reintegration/enhancement of --pretty. #23017

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,10 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"Include assignment analysis data in --pretty flowgraph output"),
flowgraph_print_all: bool = (false, parse_bool,
"Include all dataflow analysis data in --pretty flowgraph output"),
pretty_keep_going: bool = (false, parse_bool,
"Do not stop after pretty-printing (use with --pretty)"),
pretty_dump_dir: Option<String> = (None, parse_opt_string,
"The directory where --pretty output will be saved"),
print_region_graph: bool = (false, parse_bool,
"Prints region inference graph. \
Use with RUST_REGION_GRAPH=help for more info"),
Expand Down
17 changes: 6 additions & 11 deletions src/librustc/util/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,27 +30,22 @@ pub const FN_OUTPUT_NAME: &'static str = "Output";
#[derive(Clone, Copy, Debug)]
pub struct ErrorReported;

pub fn time<T, U, F>(do_it: bool, what: &str, u: U, f: F) -> T where
F: FnOnce(U) -> T,
pub fn time<T, F>(do_it: bool, what: &str, f: F) -> T where
F: FnOnce() -> T,
{
thread_local!(static DEPTH: Cell<uint> = Cell::new(0));
if !do_it { return f(u); }
if !do_it { return f(); }

let old = DEPTH.with(|slot| {
let r = slot.get();
slot.set(r + 1);
r
});

let mut u = Some(u);
let mut rv = None;
let dur = {
let ref mut rvp = rv;

Duration::span(move || {
*rvp = Some(f(u.take().unwrap()))
})
};
let dur = Duration::span(|| {
rv = Some(f());
});
let rv = rv.unwrap();

println!("{}time: {}.{:03} \t{}", repeat(" ").take(old).collect::<String>(),
Expand Down
228 changes: 130 additions & 98 deletions src/librustc_driver/driver.rs

Large diffs are not rendered by default.

99 changes: 36 additions & 63 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const BUG_REPORT_URL: &'static str =


pub fn run(args: Vec<String>) -> int {
monitor(move || run_compiler(&args, &mut RustcDefaultCalls));
monitor(move || run_compiler(&args, &mut RustcDefaultCalls::new()));
0
}

Expand Down Expand Up @@ -142,17 +142,6 @@ pub fn run_compiler<'a>(args: &[String],

do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile));

// It is somewhat unfortunate that this is hardwired in - this is forced by
// the fact that pretty_print_input requires the session by value.
let pretty = callbacks.parse_pretty(&sess, &matches);
match pretty {
Some((ppm, opt_uii)) => {
pretty::pretty_print_input(sess, cfg, &input, ppm, opt_uii, ofile);
return;
}
None => {/* continue */ }
}

let plugins = sess.opts.debugging_opts.extra_plugins.clone();
let control = callbacks.build_controller(&sess);
driver::compile_input(sess, cfg, &input, &odir, &ofile, Some(plugins), control);
Expand Down Expand Up @@ -239,33 +228,15 @@ pub trait CompilerCalls<'a> {
&diagnostics::registry::Registry)
-> Option<(Input, Option<Path>)>;

// Parse pretty printing information from the arguments. The implementer can
// choose to ignore this (the default will return None) which will skip pretty
// printing. If you do want to pretty print, it is recommended to use the
// implementation of this method from RustcDefaultCalls.
// FIXME, this is a terrible bit of API. Parsing of pretty printing stuff
// should be done as part of the framework and the implementor should customise
// handling of it. However, that is not possible atm because pretty printing
// essentially goes off and takes another path through the compiler which
// means the session is either moved or not depending on what parse_pretty
// returns (we could fix this by cloning, but it's another hack). The proper
// solution is to handle pretty printing as if it were a compiler extension,
// extending CompileController to make this work (see for example the treatment
// of save-analysis in RustcDefaultCalls::build_controller).
fn parse_pretty(&mut self,
_sess: &Session,
_matches: &getopts::Matches)
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
None
}

// Create a CompilController struct for controlling the behaviour of compilation.
fn build_controller(&mut self, &Session) -> CompileController<'a>;
}

// CompilerCalls instance for a regular rustc build.
#[derive(Copy)]
pub struct RustcDefaultCalls;
pub struct RustcDefaultCalls {
save_analysis: bool,
pretty_print: Option<(PpMode, Option<UserIdentifiedItem>)>
}

impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
fn early_callback(&mut self,
Expand Down Expand Up @@ -320,35 +291,25 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
None
}

fn parse_pretty(&mut self,
sess: &Session,
matches: &getopts::Matches)
-> Option<(PpMode, Option<UserIdentifiedItem>)> {
let pretty = if sess.opts.debugging_opts.unstable_options {
matches.opt_default("pretty", "normal").map(|a| {
// stable pretty-print variants only
pretty::parse_pretty(sess, &a, false)
})
} else {
None
};
if pretty.is_none() && sess.unstable_options() {
matches.opt_str("xpretty").map(|a| {
// extended with unstable pretty-print variants
pretty::parse_pretty(sess, &a, true)
})
} else {
pretty
}
}

fn late_callback(&mut self,
matches: &getopts::Matches,
sess: &Session,
input: &Input,
odir: &Option<Path>,
ofile: &Option<Path>)
-> Compilation {
self.save_analysis = sess.opts.debugging_opts.save_analysis;

if sess.unstable_options() {
self.pretty_print = matches.opt_default("pretty", "normal").map(|a| {
// stable pretty-print variants only
pretty::parse_pretty(&a, false).unwrap_or_else(|e| sess.fatal(&e))
}).or_else(|| matches.opt_str("xpretty").map(|a| {
// extended with unstable pretty-print variants
pretty::parse_pretty(&a, true).unwrap_or_else(|e| sess.fatal(&e))
}));
}

RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile).and_then(
|| RustcDefaultCalls::list_metadata(sess, matches, input))
}
Expand All @@ -374,15 +335,20 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
control.after_llvm.stop = Compilation::Stop;
}

if sess.opts.debugging_opts.save_analysis {
pretty::setup_controller(&mut control,
self.pretty_print.take(),
sess.opts.debugging_opts.pretty_dump_dir
.as_ref().map(|s| &s[..]),
sess.opts.debugging_opts.pretty_keep_going);

if self.save_analysis {
control.after_analysis.callback = box |state| {
time(state.session.time_passes(),
"save analysis",
state.expanded_crate.unwrap(),
|krate| save::process_crate(state.session,
krate,
state.analysis.unwrap(),
state.out_dir));
"save analysis", ||
save::process_crate(state.session,
state.expanded_crate.unwrap(),
state.analysis.unwrap(),
state.out_dir));
};
control.make_glob_map = resolve::MakeGlobMap::Yes;
}
Expand All @@ -392,6 +358,13 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
}

impl RustcDefaultCalls {
pub fn new() -> RustcDefaultCalls {
RustcDefaultCalls {
save_analysis: false,
pretty_print: None
}
}

pub fn list_metadata(sess: &Session,
matches: &getopts::Matches,
input: &Input)
Expand Down
Loading