rustc: Refactor driver to better understand string sources

This commit is contained in:
Brian Anderson 2012-05-09 19:41:24 -07:00
parent 50a3dd40ae
commit fa6c18e014
3 changed files with 79 additions and 32 deletions

View file

@ -18,7 +18,20 @@ import back::{x86, x86_64};
enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
ppm_expanded_identified }
fn default_configuration(sess: session, argv0: str, input: str) ->
#[doc = "
The name used for source code that doesn't originate in a file
(e.g. source from stdin or a string)
"]
fn anon_src() -> str { "<anon>" }
fn source_name(input: input) -> str {
alt input {
file_input(ifile) { ifile }
str_input(_) { anon_src() }
}
}
fn default_configuration(sess: session, argv0: str, input: input) ->
ast::crate_cfg {
let libc = alt sess.targ_cfg.os {
session::os_win32 { "msvcrt.dll" }
@ -42,10 +55,10 @@ fn default_configuration(sess: session, argv0: str, input: str) ->
mk("target_libc", libc),
// Build bindings.
mk("build_compiler", argv0),
mk("build_input", input)];
mk("build_input", source_name(input))];
}
fn build_configuration(sess: session, argv0: str, input: str) ->
fn build_configuration(sess: session, argv0: str, input: input) ->
ast::crate_cfg {
// Combine the configuration requested by the session (command line) with
// some default and generated configuration items
@ -71,15 +84,24 @@ fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg {
ret words;
}
fn input_is_stdin(filename: str) -> bool { filename == "-" }
enum input {
#[doc = "Load source from file"]
file_input(str),
#[doc = "The string is the source"]
str_input(str)
}
fn parse_input(sess: session, cfg: ast::crate_cfg, input: str)
fn parse_input(sess: session, cfg: ast::crate_cfg, input: input)
-> @ast::crate {
if !input_is_stdin(input) {
parse::parse_crate_from_file(input, cfg, sess.parse_sess)
} else {
let src = @str::from_bytes(io::stdin().read_whole_stream());
parse::parse_crate_from_source_str(input, src, cfg, sess.parse_sess)
alt input {
file_input(file) {
parse::parse_crate_from_file(file, cfg, sess.parse_sess)
}
str_input(src) {
// FIXME: Don't really want to box the source string
parse::parse_crate_from_source_str(
anon_src(), @src, cfg, sess.parse_sess)
}
}
}
@ -102,7 +124,7 @@ enum compile_upto {
}
fn compile_upto(sess: session, cfg: ast::crate_cfg,
input: str, upto: compile_upto,
input: input, upto: compile_upto,
outputs: option<output_filenames>)
-> {crate: @ast::crate, tcx: option<ty::ctxt>} {
let time_passes = sess.opts.time_passes;
@ -208,7 +230,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
ret {crate: crate, tcx: some(ty_cx)};
}
fn compile_input(sess: session, cfg: ast::crate_cfg, input: str,
fn compile_input(sess: session, cfg: ast::crate_cfg, input: input,
outdir: option<str>, output: option<str>) {
let upto = if sess.opts.parse_only { cu_parse }
@ -218,7 +240,7 @@ fn compile_input(sess: session, cfg: ast::crate_cfg, input: str,
compile_upto(sess, cfg, input, upto, some(outputs));
}
fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: input,
ppm: pp_mode) {
fn ann_paren_for_expr(node: pprust::ann_node) {
alt node { pprust::node_expr(s, expr) { pprust::popen(s); } _ { } }
@ -277,9 +299,10 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
}
ppm_expanded | ppm_normal {}
}
let src = codemap::get_filemap(sess.codemap, input).src;
let src = codemap::get_filemap(sess.codemap, source_name(input)).src;
io::with_str_reader(*src) { |rdr|
pprust::print_crate(sess.codemap, sess.span_diagnostic, crate, input,
pprust::print_crate(sess.codemap, sess.span_diagnostic, crate,
source_name(input),
rdr, io::stdout(), ann);
}
}
@ -549,7 +572,7 @@ fn opts() -> [getopts::opt] {
type output_filenames = @{out_filename: str, obj_filename:str};
fn build_output_filenames(ifile: str,
fn build_output_filenames(input: input,
odir: option<str>,
ofile: option<str>,
sess: session)
@ -582,19 +605,25 @@ fn build_output_filenames(ifile: str,
let dirname = alt odir {
some(d) { d }
none {
if input_is_stdin(ifile) {
alt input {
str_input(_) {
os::getcwd()
} else {
}
file_input(ifile) {
path::dirname(ifile)
}
}
}
};
let base_filename = if !input_is_stdin(ifile) {
let base_filename = alt input {
file_input(ifile) {
let (path, _) = path::splitext(ifile);
path::basename(path)
} else {
}
str_input(_) {
"rust_out"
}
};
let base_path = path::connect(dirname, base_filename);
@ -659,7 +688,7 @@ mod test {
};
let sessopts = build_session_options(match, diagnostic::emit);
let sess = build_session(sessopts, diagnostic::emit);
let cfg = build_configuration(sess, "whatever", "whatever");
let cfg = build_configuration(sess, "whatever", str_input(""));
assert (attr::contains_name(cfg, "test"));
}
@ -675,7 +704,7 @@ mod test {
};
let sessopts = build_session_options(match, diagnostic::emit);
let sess = build_session(sessopts, diagnostic::emit);
let cfg = build_configuration(sess, "whatever", "whatever");
let cfg = build_configuration(sess, "whatever", str_input(""));
let test_items = attr::find_meta_items_by_name(cfg, "test");
assert (vec::len(test_items) == 1u);
}

View file

@ -15,6 +15,7 @@ import rustc::driver::driver::*;
import rustc::syntax::codemap;
import rustc::driver::diagnostic;
import rustc::middle::lint;
import io::reader_util;
fn version(argv0: str) {
let mut vers = "unknown version";
@ -138,9 +139,17 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
version(binary);
ret;
}
let ifile = alt vec::len(match.free) {
let input = alt vec::len(match.free) {
0u { early_error(demitter, "no input filename given") }
1u { match.free[0] }
1u {
let ifile = match.free[0];
if ifile == "-" {
let src = str::from_bytes(io::stdin().read_whole_stream());
str_input(src)
} else {
file_input(ifile)
}
}
_ { early_error(demitter, "multiple input filenames provided") }
};
@ -148,22 +157,29 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
let sess = build_session(sopts, demitter);
let odir = getopts::opt_maybe_str(match, "out-dir");
let ofile = getopts::opt_maybe_str(match, "o");
let cfg = build_configuration(sess, binary, ifile);
let cfg = build_configuration(sess, binary, input);
let pretty =
option::map(getopts::opt_default(match, "pretty",
"normal"),
bind parse_pretty(sess, _));
alt pretty {
some::<pp_mode>(ppm) { pretty_print_input(sess, cfg, ifile, ppm); ret; }
some::<pp_mode>(ppm) { pretty_print_input(sess, cfg, input, ppm); ret; }
none::<pp_mode> {/* continue */ }
}
let ls = opt_present(match, "ls");
if ls {
list_metadata(sess, ifile, io::stdout());
alt input {
file_input(ifile) {
list_metadata(sess, ifile, io::stdout());
}
str_input(_) {
early_error(demitter, "can not list metadata for stdin");
}
}
ret;
}
compile_input(sess, cfg, ifile, odir, ofile);
compile_input(sess, cfg, input, odir, ofile);
}
/*

View file

@ -1,6 +1,7 @@
#[doc = "AST-parsing helpers"];
import rustc::driver::driver;
import driver::{file_input, str_input};
import rustc::driver::session;
import rustc::driver::diagnostic;
import rustc::syntax::ast;
@ -33,14 +34,15 @@ fn from_str(source: str) -> @ast::crate {
}
fn from_file_sess(sess: session::session, file: str) -> @ast::crate {
parse::parse_crate_from_file(file, cfg(sess), sess.parse_sess)
parse::parse_crate_from_file(
file, cfg(sess, file_input(file)), sess.parse_sess)
}
fn from_str_sess(sess: session::session, source: str) -> @ast::crate {
parse::parse_crate_from_source_str(
"-", @source, cfg(sess), sess.parse_sess)
"-", @source, cfg(sess, str_input(source)), sess.parse_sess)
}
fn cfg(sess: session::session) -> ast::crate_cfg {
driver::default_configuration(sess, "rustdoc", "<anon>")
fn cfg(sess: session::session, input: driver::input) -> ast::crate_cfg {
driver::default_configuration(sess, "rustdoc", input)
}