]> git.lizzy.rs Git - rust.git/commitdiff
Use the compiler API to run pretty printing.
authorNick Cameron <ncameron@mozilla.com>
Wed, 20 Apr 2016 04:24:14 +0000 (16:24 +1200)
committerNick Cameron <ncameron@mozilla.com>
Mon, 2 May 2016 22:49:47 +0000 (10:49 +1200)
This commit still does a lot of building in pretty because we always run after parsing.

src/librustc_driver/driver.rs
src/librustc_driver/lib.rs
src/librustc_driver/pretty.rs
src/test/run-pass-fulldeps/compiler-calls.rs

index 6e47ee8101d31ff3c2cd53bcbbd457c41ee31034..bf1457c576ebae2d994991c2e21f8cff299d5ff3 100644 (file)
@@ -70,7 +70,7 @@ pub fn compile_input(sess: &Session,
                      control: &CompileController) -> CompileResult {
     macro_rules! controller_entry_point {
         ($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
-            let state = $make_state;
+            let state = &mut $make_state;
             let phase_result: &CompileResult = &$phase_result;
             if phase_result.is_ok() || control.$point.run_callback_on_error {
                 (control.$point.callback)(state);
@@ -95,10 +95,17 @@ macro_rules! controller_entry_point {
                 }
             };
 
+            let mut compile_state = CompileState::state_after_parse(input,
+                                                                    sess,
+                                                                    outdir,
+                                                                    output,
+                                                                    krate,
+                                                                    &cstore);
             controller_entry_point!(after_parse,
                                     sess,
-                                    CompileState::state_after_parse(input, sess, outdir, &krate),
+                                    compile_state,
                                     Ok(()));
+            let krate = compile_state.krate.unwrap();
 
             let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
             let id = link::find_crate_name(Some(sess), &krate.attrs, input);
@@ -194,16 +201,16 @@ macro_rules! controller_entry_point {
                 // Eventually, we will want to track plugins.
                 let _ignore = tcx.dep_graph.in_ignore();
 
-                let state = CompileState::state_after_analysis(input,
-                                                               &tcx.sess,
-                                                               outdir,
-                                                               opt_crate,
-                                                               tcx.map.krate(),
-                                                               &analysis,
-                                                               mir_map.as_ref(),
-                                                               tcx,
-                                                               &id);
-                (control.after_analysis.callback)(state);
+                let mut state = CompileState::state_after_analysis(input,
+                                                                   &tcx.sess,
+                                                                   outdir,
+                                                                   opt_crate,
+                                                                   tcx.map.krate(),
+                                                                   &analysis,
+                                                                   mir_map.as_ref(),
+                                                                   tcx,
+                                                                   &id);
+                (control.after_analysis.callback)(&mut state);
 
                 if control.after_analysis.stop == Compilation::Stop {
                     return result.and_then(|_| Err(0usize));
@@ -311,7 +318,7 @@ pub struct PhaseController<'a> {
     // If true then the compiler will try to run the callback even if the phase
     // ends with an error. Note that this is not always possible.
     pub run_callback_on_error: bool,
-    pub callback: Box<Fn(CompileState) -> () + 'a>,
+    pub callback: Box<Fn(&mut CompileState) + 'a>,
 }
 
 impl<'a> PhaseController<'a> {
@@ -330,11 +337,12 @@ pub fn basic() -> PhaseController<'a> {
 pub struct CompileState<'a, 'ast: 'a, 'tcx: 'a> {
     pub input: &'a Input,
     pub session: &'a Session,
-    pub cfg: Option<&'a ast::CrateConfig>,
-    pub krate: Option<&'a ast::Crate>,
+    pub krate: Option<ast::Crate>,
+    pub cstore: Option<&'a CStore>,
     pub crate_name: Option<&'a str>,
     pub output_filenames: Option<&'a OutputFilenames>,
     pub out_dir: Option<&'a Path>,
+    pub out_file: Option<&'a Path>,
     pub expanded_crate: Option<&'a ast::Crate>,
     pub hir_crate: Option<&'a hir::Crate>,
     pub ast_map: Option<&'a hir_map::Map<'ast>>,
@@ -353,8 +361,9 @@ fn empty(input: &'a Input,
             input: input,
             session: session,
             out_dir: out_dir.as_ref().map(|s| &**s),
-            cfg: None,
+            out_file: None,
             krate: None,
+            cstore: None,
             crate_name: None,
             output_filenames: None,
             expanded_crate: None,
@@ -370,9 +379,16 @@ fn empty(input: &'a Input,
     fn state_after_parse(input: &'a Input,
                          session: &'a Session,
                          out_dir: &'a Option<PathBuf>,
-                         krate: &'a ast::Crate)
+                         out_file: &'a Option<PathBuf>,
+                         krate: ast::Crate,
+                         cstore: &'a CStore)
                          -> CompileState<'a, 'ast, 'tcx> {
-        CompileState { krate: Some(krate), ..CompileState::empty(input, session, out_dir) }
+        CompileState {
+            krate: Some(krate),
+            cstore: Some(cstore),
+            out_file: out_file.as_ref().map(|s| &**s),
+            ..CompileState::empty(input, session, out_dir)
+        }
     }
 
     fn state_after_expand(input: &'a Input,
@@ -399,7 +415,7 @@ fn state_after_write_deps(input: &'a Input,
         CompileState {
             crate_name: Some(crate_name),
             ast_map: Some(hir_map),
-            krate: Some(krate),
+            expanded_crate: Some(krate),
             hir_crate: Some(hir_crate),
             ..CompileState::empty(input, session, out_dir)
         }
@@ -419,7 +435,7 @@ fn state_after_analysis(input: &'a Input,
             analysis: Some(analysis),
             mir_map: mir_map,
             tcx: Some(tcx),
-            krate: krate,
+            expanded_crate: krate,
             hir_crate: Some(hir_crate),
             crate_name: Some(crate_name),
             ..CompileState::empty(input, session, out_dir)
index dc96884e47bbffcf082a6523c7f1519b4cfafdfb..8ffdf6843e75acc4ee13e8da1896e3f34829c081 100644 (file)
@@ -31,6 +31,7 @@
 #![feature(set_stdio)]
 #![feature(staged_api)]
 #![feature(question_mark)]
+#![feature(unboxed_closures)]
 
 extern crate arena;
 extern crate flate;
@@ -208,15 +209,8 @@ macro_rules! do_or_return {($expr: expr, $sess: expr) => {
 
     do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess));
 
-    // It is somewhat unfortunate that this is hardwired in.
-    let pretty = callbacks.parse_pretty(&sess, &matches);
-    if let Some((ppm, opt_uii)) = pretty {
-        pretty::pretty_print_input(&sess, &cstore, cfg, &input, ppm, opt_uii, ofile);
-        return (Ok(()), None);
-    }
-
     let plugins = sess.opts.debugging_opts.extra_plugins.clone();
-    let control = callbacks.build_controller(&sess);
+    let control = callbacks.build_controller(&sess, &matches);
     (driver::compile_input(&sess, &cstore, cfg, &input, &odir, &ofile,
                            Some(plugins), &control),
      Some(sess))
@@ -247,6 +241,27 @@ fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
     }
 }
 
+fn parse_pretty(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("unpretty").map(|a| {
+            // extended with unstable pretty-print variants
+            pretty::parse_pretty(sess, &a, true)
+        })
+    } else {
+        pretty
+    }
+}
+
 // Whether to stop or continue compilation.
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum Compilation {
@@ -316,29 +331,9 @@ fn no_input(&mut self,
         None
     }
 
-    // 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>;
+    fn build_controller(&mut self, &Session, &getopts::Matches) -> CompileController<'a>;
 }
 
 // CompilerCalls instance for a regular rustc build.
@@ -441,28 +436,6 @@ fn no_input(&mut self,
         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("unpretty").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,
@@ -474,9 +447,22 @@ fn late_callback(&mut self,
             .and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input))
     }
 
-    fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
+    fn build_controller(&mut self, sess: &Session, matches: &getopts::Matches) -> CompileController<'a> {
         let mut control = CompileController::basic();
 
+        if let Some((ppm, opt_uii)) = parse_pretty(&sess, &matches) {
+            control.after_parse.stop = Compilation::Stop;
+            control.after_parse.callback = box move |state| {
+                pretty::pretty_print_input(state.session,
+                                           state.cstore.unwrap(),
+                                           state.input,
+                                           state.krate.take().unwrap(),
+                                           ppm,
+                                           opt_uii.clone(),
+                                           state.out_file);
+            };
+        }
+
         if sess.opts.parse_only || sess.opts.debugging_opts.show_span.is_some() ||
            sess.opts.debugging_opts.ast_json_noexpand {
             control.after_parse.stop = Compilation::Stop;
@@ -498,7 +484,7 @@ fn build_controller(&mut self, sess: &Session) -> CompileController<'a> {
             control.after_analysis.callback = box |state| {
                 time(state.session.time_passes(), "save analysis", || {
                     save::process_crate(state.tcx.unwrap(),
-                                        state.krate.unwrap(),
+                                        state.expanded_crate.unwrap(),
                                         state.analysis.unwrap(),
                                         state.crate_name.unwrap(),
                                         state.out_dir,
index 0591b0493cfb6d28d45b9cbe29537e1b9f75e413..80d8a40b4e91485a6961f296cb04833bb5f1dc38 100644 (file)
@@ -49,7 +49,7 @@
 use std::io::{self, Write};
 use std::iter;
 use std::option;
-use std::path::PathBuf;
+use std::path::Path;
 use std::str::FromStr;
 
 use rustc::hir::map as hir_map;
@@ -702,13 +702,11 @@ fn fold_mac(&mut self, mac: ast::Mac) -> ast::Mac {
 
 pub fn pretty_print_input(sess: &Session,
                           cstore: &CStore,
-                          cfg: ast::CrateConfig,
                           input: &Input,
+                          krate: ast::Crate,
                           ppm: PpMode,
                           opt_uii: Option<UserIdentifiedItem>,
-                          ofile: Option<PathBuf>) {
-    let krate = panictry!(driver::phase_1_parse_input(sess, cfg, input));
-
+                          ofile: Option<&Path>) {
     let krate = if let PpmSource(PpmEveryBodyLoops) = ppm {
         let mut fold = ReplaceBodyWithLoop::new();
         fold.fold_crate(krate)
@@ -922,7 +920,7 @@ pub fn pretty_print_input(sess: &Session,
     match ofile {
         None => print!("{}", String::from_utf8(out).unwrap()),
         Some(p) => {
-            match File::create(&p) {
+            match File::create(p) {
                 Ok(mut w) => w.write_all(&out).unwrap(),
                 Err(e) => panic!("print-print failed to open {} due to {}", p.display(), e),
             }
index 42784e009ee44a962b2259610754335e8771006b..837215c3cac4e49cd2a99fbc3c978626da356a23 100644 (file)
@@ -69,7 +69,7 @@ fn no_input(&mut self,
         panic!("This shouldn't happen");
     }
 
-    fn build_controller(&mut self, _: &Session) -> driver::CompileController<'a> {
+    fn build_controller(&mut self, _: &Session, _: &getopts::Matches) -> driver::CompileController<'a> {
         panic!("This shouldn't be called");
     }
 }