1
Fork 0

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, enum pp_mode {ppm_normal, ppm_expanded, ppm_typed, ppm_identified,
ppm_expanded_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 { ast::crate_cfg {
let libc = alt sess.targ_cfg.os { let libc = alt sess.targ_cfg.os {
session::os_win32 { "msvcrt.dll" } session::os_win32 { "msvcrt.dll" }
@ -42,10 +55,10 @@ fn default_configuration(sess: session, argv0: str, input: str) ->
mk("target_libc", libc), mk("target_libc", libc),
// Build bindings. // Build bindings.
mk("build_compiler", argv0), 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 { 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
@ -71,15 +84,24 @@ fn parse_cfgspecs(cfgspecs: [str]) -> ast::crate_cfg {
ret words; 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 { -> @ast::crate {
if !input_is_stdin(input) { alt input {
parse::parse_crate_from_file(input, cfg, sess.parse_sess) file_input(file) {
} else { parse::parse_crate_from_file(file, cfg, sess.parse_sess)
let src = @str::from_bytes(io::stdin().read_whole_stream()); }
parse::parse_crate_from_source_str(input, src, 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, fn compile_upto(sess: session, cfg: ast::crate_cfg,
input: str, upto: compile_upto, input: input, upto: compile_upto,
outputs: option<output_filenames>) outputs: option<output_filenames>)
-> {crate: @ast::crate, tcx: option<ty::ctxt>} { -> {crate: @ast::crate, tcx: option<ty::ctxt>} {
let time_passes = sess.opts.time_passes; 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)}; 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>) { outdir: option<str>, output: option<str>) {
let upto = if sess.opts.parse_only { cu_parse } 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)); 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) { 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); } _ { } }
@ -277,9 +299,10 @@ fn pretty_print_input(sess: session, cfg: ast::crate_cfg, input: str,
} }
ppm_expanded | ppm_normal {} 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| 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); rdr, io::stdout(), ann);
} }
} }
@ -549,7 +572,7 @@ fn opts() -> [getopts::opt] {
type output_filenames = @{out_filename: str, obj_filename:str}; type output_filenames = @{out_filename: str, obj_filename:str};
fn build_output_filenames(ifile: str, fn build_output_filenames(input: input,
odir: option<str>, odir: option<str>,
ofile: option<str>, ofile: option<str>,
sess: session) sess: session)
@ -582,19 +605,25 @@ fn build_output_filenames(ifile: str,
let dirname = alt odir { let dirname = alt odir {
some(d) { d } some(d) { d }
none { none {
if input_is_stdin(ifile) { alt input {
str_input(_) {
os::getcwd() os::getcwd()
} else { }
file_input(ifile) {
path::dirname(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); let (path, _) = path::splitext(ifile);
path::basename(path) path::basename(path)
} else { }
str_input(_) {
"rust_out" "rust_out"
}
}; };
let base_path = path::connect(dirname, base_filename); let base_path = path::connect(dirname, base_filename);
@ -659,7 +688,7 @@ mod test {
}; };
let sessopts = build_session_options(match, diagnostic::emit); let sessopts = build_session_options(match, diagnostic::emit);
let sess = build_session(sessopts, 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")); assert (attr::contains_name(cfg, "test"));
} }
@ -675,7 +704,7 @@ mod test {
}; };
let sessopts = build_session_options(match, diagnostic::emit); let sessopts = build_session_options(match, diagnostic::emit);
let sess = build_session(sessopts, 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"); let test_items = attr::find_meta_items_by_name(cfg, "test");
assert (vec::len(test_items) == 1u); assert (vec::len(test_items) == 1u);
} }

View file

@ -15,6 +15,7 @@ import rustc::driver::driver::*;
import rustc::syntax::codemap; import rustc::syntax::codemap;
import rustc::driver::diagnostic; import rustc::driver::diagnostic;
import rustc::middle::lint; import rustc::middle::lint;
import io::reader_util;
fn version(argv0: str) { fn version(argv0: str) {
let mut vers = "unknown version"; let mut vers = "unknown version";
@ -138,9 +139,17 @@ fn run_compiler(args: [str], demitter: diagnostic::emitter) {
version(binary); version(binary);
ret; ret;
} }
let ifile = alt vec::len(match.free) { let input = alt vec::len(match.free) {
0u { early_error(demitter, "no input filename given") } 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") } _ { 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 sess = build_session(sopts, demitter);
let odir = getopts::opt_maybe_str(match, "out-dir"); let odir = getopts::opt_maybe_str(match, "out-dir");
let ofile = getopts::opt_maybe_str(match, "o"); let ofile = getopts::opt_maybe_str(match, "o");
let cfg = build_configuration(sess, binary, ifile); let cfg = build_configuration(sess, binary, input);
let pretty = let pretty =
option::map(getopts::opt_default(match, "pretty", option::map(getopts::opt_default(match, "pretty",
"normal"), "normal"),
bind parse_pretty(sess, _)); bind parse_pretty(sess, _));
alt pretty { 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 */ } none::<pp_mode> {/* continue */ }
} }
let ls = opt_present(match, "ls"); let ls = opt_present(match, "ls");
if 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; 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"]; #[doc = "AST-parsing helpers"];
import rustc::driver::driver; import rustc::driver::driver;
import driver::{file_input, str_input};
import rustc::driver::session; import rustc::driver::session;
import rustc::driver::diagnostic; import rustc::driver::diagnostic;
import rustc::syntax::ast; 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 { 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 { fn from_str_sess(sess: session::session, source: str) -> @ast::crate {
parse::parse_crate_from_source_str( 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 { fn cfg(sess: session::session, input: driver::input) -> ast::crate_cfg {
driver::default_configuration(sess, "rustdoc", "<anon>") driver::default_configuration(sess, "rustdoc", input)
} }