1
Fork 0

Fix --pretty normal, reorganize some code in driver.rs

There is now only one path doing crate expanding and typechecking,
which should make it less likely for the pretty-printing code to be
broken by changes to the compilation pipeline.

Closes #1536
This commit is contained in:
Marijn Haverbeke 2012-01-17 16:42:45 +01:00
parent 1c7a62c93b
commit 08c16b17e9

View file

@ -20,7 +20,7 @@ import back::{x86, x86_64};
tag pp_mode { ppm_normal; ppm_expanded; ppm_typed; ppm_identified; } tag pp_mode { ppm_normal; ppm_expanded; ppm_typed; ppm_identified; }
fn default_configuration(sess: session::session, argv0: str, input: str) -> fn default_configuration(sess: session, argv0: str, input: str) ->
ast::crate_cfg { ast::crate_cfg {
let libc = let libc =
alt sess.targ_cfg.os { alt sess.targ_cfg.os {
@ -48,7 +48,7 @@ fn default_configuration(sess: session::session, argv0: str, input: str) ->
mk("build_input", input)]; mk("build_input", input)];
} }
fn build_configuration(sess: session::session, argv0: str, input: str) -> fn build_configuration(sess: session, argv0: str, input: str) ->
ast::crate_cfg { ast::crate_cfg {
// Combine the configuration requested by the session (command line) with // Combine the configuration requested by the session (command line) with
// some default and generated configuration items // some default and generated configuration items
@ -76,31 +76,27 @@ fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg {
fn input_is_stdin(filename: str) -> bool { filename == "-" } fn input_is_stdin(filename: str) -> bool { filename == "-" }
fn parse_input(sess: session::session, cfg: ast::crate_cfg, input: str) -> fn parse_input(sess: session, cfg: ast::crate_cfg, input: str) ->
@ast::crate { @ast::crate {
if !input_is_stdin(input) { if !input_is_stdin(input) {
parser::parse_crate_from_file(input, cfg, sess.parse_sess) parser::parse_crate_from_file(input, cfg, sess.parse_sess)
} else { parse_input_src(sess, cfg, input).crate } } else {
let srcbytes = get_input_stream(sess, input).read_whole_stream();
let srcstring = str::unsafe_from_bytes(srcbytes);
parser::parse_crate_from_source_str(input, srcstring, cfg,
sess.parse_sess)
}
} }
fn parse_input_src(sess: session::session, cfg: ast::crate_cfg, infile: str) fn get_input_stream(sess: session, infile: str) -> io::reader {
-> {crate: @ast::crate, src: str} { if !input_is_stdin(infile) {
let src_stream = if infile != "-" {
alt io::file_reader(infile) { alt io::file_reader(infile) {
result::ok(reader) { reader } result::ok(reader) { reader }
result::err(e) { result::err(e) {
sess.fatal(e) sess.fatal(e)
} }
} }
} else { } else { io::stdin() }
io::stdin()
};
let srcbytes = src_stream.read_whole_stream();
let src = str::unsafe_from_bytes(srcbytes);
let crate =
parser::parse_crate_from_source_str(infile, src, cfg,
sess.parse_sess);
ret {crate: crate, src: src};
} }
fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T { fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
@ -113,7 +109,7 @@ fn time<T>(do_it: bool, what: str, thunk: fn@() -> T) -> T {
ret rv; ret rv;
} }
fn inject_libcore_reference(sess: session::session, fn inject_libcore_reference(sess: session,
crate: @ast::crate) -> @ast::crate { crate: @ast::crate) -> @ast::crate {
fn spanned<T: copy>(x: T) -> @ast::spanned<T> { fn spanned<T: copy>(x: T) -> @ast::spanned<T> {
@ -134,14 +130,22 @@ fn inject_libcore_reference(sess: session::session,
with crate.node} with *crate } with crate.node} with *crate }
} }
enum compile_upto {
cu_parse;
cu_expand;
cu_typeck;
cu_no_trans;
cu_everything;
}
fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str, fn compile_upto(sess: session, cfg: ast::crate_cfg,
outdir: option::t<str>, output: option::t<str>) { input: str, upto: compile_upto,
outputs: option::t<output_filenames>)
-> {crate: @ast::crate, tcx: option::t<ty::ctxt>} {
let time_passes = sess.opts.time_passes; let time_passes = sess.opts.time_passes;
let crate = let crate =
time(time_passes, "parsing", bind parse_input(sess, cfg, input)); time(time_passes, "parsing", bind parse_input(sess, cfg, input));
if sess.opts.parse_only { ret; } if upto == cu_parse { ret {crate: crate, tcx: none}; }
sess.building_library = sess.building_library =
session::building_library(sess.opts.crate_type, crate); session::building_library(sess.opts.crate_type, crate);
@ -156,6 +160,7 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
time(time_passes, "expansion", time(time_passes, "expansion",
bind syntax::ext::expand::expand_crate(sess, crate)); bind syntax::ext::expand::expand_crate(sess, crate));
if upto == cu_expand { ret {crate: crate, tcx: none}; }
if sess.opts.libcore { if sess.opts.libcore {
crate = inject_libcore_reference(sess, crate); crate = inject_libcore_reference(sess, crate);
} }
@ -177,6 +182,9 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
let (method_map, dict_map) = let (method_map, dict_map) =
time(time_passes, "typechecking", time(time_passes, "typechecking",
bind typeck::check_crate(ty_cx, impl_map, crate)); bind typeck::check_crate(ty_cx, impl_map, crate));
if upto == cu_typeck { ret {crate: crate, tcx: some(ty_cx)}; }
time(time_passes, "block-use checking", time(time_passes, "block-use checking",
bind middle::block_use::check_crate(ty_cx, crate)); bind middle::block_use::check_crate(ty_cx, crate));
time(time_passes, "function usage", time(time_passes, "function usage",
@ -195,9 +203,9 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx)); bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
time(time_passes, "kind checking", time(time_passes, "kind checking",
bind kind::check_crate(ty_cx, method_map, last_uses, crate)); bind kind::check_crate(ty_cx, method_map, last_uses, crate));
if sess.opts.no_trans { ret; }
let outputs = build_output_filenames(input, outdir, output, sess); if upto == cu_no_trans { ret {crate: crate, tcx: some(ty_cx)}; }
let outputs = option::get(outputs);
let (llmod, link_meta) = let (llmod, link_meta) =
time(time_passes, "translation", time(time_passes, "translation",
@ -212,14 +220,25 @@ fn compile_input(sess: session::session, cfg: ast::crate_cfg, input: str,
sess.opts.output_type != link::output_type_exe || sess.opts.output_type != link::output_type_exe ||
sess.opts.static && sess.building_library; sess.opts.static && sess.building_library;
if stop_after_codegen { ret; } if stop_after_codegen { ret {crate: crate, tcx: some(ty_cx)}; }
time(time_passes, "Linking", time(time_passes, "Linking",
bind link::link_binary(sess, outputs.obj_filename, bind link::link_binary(sess, outputs.obj_filename,
outputs.out_filename, link_meta)); outputs.out_filename, link_meta));
ret {crate: crate, tcx: some(ty_cx)};
} }
fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg, input: str, fn compile_input(sess: session, cfg: ast::crate_cfg, input: str,
outdir: option::t<str>, output: option::t<str>) {
let upto = if sess.opts.parse_only { cu_parse }
else if sess.opts.no_trans { cu_no_trans }
else { cu_everything };
let outputs = build_output_filenames(input, outdir, output, sess);
compile_upto(sess, cfg, input, upto, some(outputs));
}
fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
ppm: pp_mode) { ppm: pp_mode) {
fn ann_paren_for_expr(node: pprust::ann_node) { fn ann_paren_for_expr(node: pprust::ann_node) {
alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } } alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } }
@ -260,33 +279,27 @@ fn pretty_print_input(sess: session::session, cfg: ast::crate_cfg, input: str,
// to collect comments and literals, and we need to support reading // to collect comments and literals, and we need to support reading
// from stdin, we're going to just suck the source into a string // from stdin, we're going to just suck the source into a string
// so both the parser and pretty-printer can use it. // so both the parser and pretty-printer can use it.
let crate_src = parse_input_src(sess, cfg, input); let upto = alt ppm {
let crate = crate_src.crate; ppm_expanded. { cu_expand }
let src = crate_src.src; ppm_typed. { cu_typeck }
_ { cu_parse }
};
let {crate, tcx} = compile_upto(sess, cfg, input, upto, none);
let src = get_input_stream(sess, input);
let ann; let ann: pprust::pp_ann = pprust::no_ann();
alt ppm { alt ppm {
ppm_expanded. {
crate = syntax::ext::expand::expand_crate(sess, crate);
ann = pprust::no_ann();
}
ppm_typed. { ppm_typed. {
crate = syntax::ext::expand::expand_crate(sess, crate); ann = {pre: ann_paren_for_expr,
let amap = middle::ast_map::map_crate(*crate); post: bind ann_typed_post(option::get(tcx), _)};
let {def_map, impl_map, _} =
resolve::resolve_crate(sess, amap, crate);
let freevars = freevars::annotate_freevars(def_map, crate);
let ty_cx = ty::mk_ctxt(sess, def_map, amap, freevars);
typeck::check_crate(ty_cx, impl_map, crate);
ann = {pre: ann_paren_for_expr, post: bind ann_typed_post(ty_cx, _)};
} }
ppm_identified. { ppm_identified. {
ann = {pre: ann_paren_for_expr, post: ann_identified_post}; ann = {pre: ann_paren_for_expr, post: ann_identified_post};
} }
ppm_normal. { ann = pprust::no_ann(); } ppm_expanded. | ppm_normal. {}
} }
pprust::print_crate(sess.codemap, sess.diagnostic, crate, input, pprust::print_crate(sess.codemap, sess.diagnostic, crate, input,
io::string_reader(src), io::stdout(), ann); src, io::stdout(), ann);
} }
fn get_os(triple: str) -> option<session::os> { fn get_os(triple: str) -> option<session::os> {
@ -453,7 +466,7 @@ fn build_session_options(match: getopts::match,
} }
fn build_session(sopts: @session::options, input: str, fn build_session(sopts: @session::options, input: str,
demitter: diagnostic::emitter) -> session::session { demitter: diagnostic::emitter) -> session {
let target_cfg = build_target_config(sopts, demitter); let target_cfg = build_target_config(sopts, demitter);
let cstore = cstore::mk_cstore(); let cstore = cstore::mk_cstore();
let filesearch = filesearch::mk_filesearch( let filesearch = filesearch::mk_filesearch(
@ -480,7 +493,7 @@ fn build_session(sopts: @session::options, input: str,
working_dir: fs::dirname(input)} working_dir: fs::dirname(input)}
} }
fn parse_pretty(sess: session::session, &&name: str) -> pp_mode { fn parse_pretty(sess: session, &&name: str) -> pp_mode {
if str::eq(name, "normal") { if str::eq(name, "normal") {
ret ppm_normal; ret ppm_normal;
} else if str::eq(name, "expanded") { } else if str::eq(name, "expanded") {
@ -509,11 +522,13 @@ fn opts() -> [getopts::opt] {
optflag("warn-unused-imports")]; optflag("warn-unused-imports")];
} }
type output_filenames = @{out_filename: str, obj_filename:str};
fn build_output_filenames(ifile: str, fn build_output_filenames(ifile: str,
odir: option::t<str>, odir: option::t<str>,
ofile: option::t<str>, ofile: option::t<str>,
sess: session::session) sess: session)
-> @{out_filename: str, obj_filename:str} { -> output_filenames {
let obj_path = ""; let obj_path = "";
let out_path: str = ""; let out_path: str = "";
let sopts = sess.opts; let sopts = sess.opts;
@ -599,7 +614,7 @@ fn early_error(emitter: diagnostic::emitter, msg: str) -> ! {
fail; fail;
} }
fn list_metadata(sess: session::session, path: str, out: io::writer) { fn list_metadata(sess: session, path: str, out: io::writer) {
metadata::creader::list_file_metadata(sess, path, out); metadata::creader::list_file_metadata(sess, path, out);
} }