diff options
| author | Brian Anderson <banderson@mozilla.com> | 2011-10-29 01:21:43 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2011-10-29 01:40:20 -0700 |
| commit | e0f44730e8dc75c17dc86fcb48769d62a4dbcaae (patch) | |
| tree | f11e4626c0fad600fe133c0a2551c1d23ff17d8e /src/comp/syntax | |
| parent | 2cebef095e61608a3d35710cb5fd3d7de18b68ac (diff) | |
| download | rust-e0f44730e8dc75c17dc86fcb48769d62a4dbcaae.tar.gz rust-e0f44730e8dc75c17dc86fcb48769d62a4dbcaae.zip | |
rustc: Support 'companion mod's for crates and directory mods
Under this scheme when parsing foo.rc the parser will also look for foo.rs to fill in the crate-level module, and when evaluating a directory module directive it will look for a .rs file with the same name as the directory.
Diffstat (limited to 'src/comp/syntax')
| -rw-r--r-- | src/comp/syntax/parse/eval.rs | 65 | ||||
| -rw-r--r-- | src/comp/syntax/parse/parser.rs | 8 |
2 files changed, 65 insertions, 8 deletions
diff --git a/src/comp/syntax/parse/eval.rs b/src/comp/syntax/parse/eval.rs index 8a48a8ec2d1..e4b60c4c21e 100644 --- a/src/comp/syntax/parse/eval.rs +++ b/src/comp/syntax/parse/eval.rs @@ -1,5 +1,5 @@ -import std::{str, option}; +import std::{str, option, result, io, fs}; import std::option::{some, none}; import syntax::ast; import syntax::parse::token; @@ -25,11 +25,65 @@ fn eval_crate_directives(cx: ctx, cdirs: [@ast::crate_directive], prefix: str, } fn eval_crate_directives_to_mod(cx: ctx, cdirs: [@ast::crate_directive], - prefix: str) -> ast::_mod { + prefix: str, suffix: option::t<str>) + -> (ast::_mod, [ast::attribute]) { + log #fmt("eval crate prefix: %s", prefix); + log #fmt("eval crate suffix: %s", + option::from_maybe("none", suffix)); + let (cview_items, citems, cattrs) + = parse_companion_mod(cx, prefix, suffix); let view_items: [@ast::view_item] = []; let items: [@ast::item] = []; eval_crate_directives(cx, cdirs, prefix, view_items, items); - ret {view_items: view_items, items: items}; + ret ({view_items: view_items + cview_items, + items: items + citems}, + cattrs); +} + +/* +The 'companion mod'. So .rc crates and directory mod crate directives define +modules but not a .rs file to fill those mods with stuff. The companion mod is +a convention for location a .rs file to go with them. For .rc files the +companion mod is a .rs file with the same name; for directory mods the +companion mod is a .rs file with the same name as the directory. + +We build the path to the companion mod by combining the prefix and the +optional suffix then adding the .rs extension. +*/ +fn parse_companion_mod(cx: ctx, prefix: str, suffix: option::t<str>) + -> ([@ast::view_item], [@ast::item], [ast::attribute]) { + + fn companion_file(prefix: str, suffix: option::t<str>) -> str { + alt suffix { + option::some(s) { fs::connect(prefix, s) } + option::none. { prefix } + } + ".rs" + } + + fn file_exists(path: str) -> bool { + // Crude, but there's no lib function for this and I'm not + // up to writing it just now + alt io::file_reader(path) { + result::ok(_) { true } + result::err(_) { false } + } + } + + let modpath = companion_file(prefix, suffix); + log #fmt("looking for companion mod %s", modpath); + if file_exists(modpath) { + log "found companion mod"; + let p0 = new_parser_from_file(cx.sess, cx.cfg, modpath, + cx.chpos, cx.byte_pos, SOURCE_FILE); + let inner_attrs = parse_inner_attrs_and_next(p0); + let first_item_outer_attrs = inner_attrs.next; + let m0 = parse_mod_items(p0, token::EOF, first_item_outer_attrs); + cx.chpos = p0.get_chpos(); + cx.byte_pos = p0.get_byte_pos(); + ret (m0.view_items, m0.items, inner_attrs.inner); + } else { + ret ([], [], []); + } } fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, @@ -66,10 +120,11 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: str, if std::fs::path_is_absolute(path) { path } else { prefix + std::fs::path_sep() + path }; - let m0 = eval_crate_directives_to_mod(cx, cdirs, full_path); + let (m0, a0) = eval_crate_directives_to_mod( + cx, cdirs, full_path, none); let i = @{ident: id, - attrs: attrs, + attrs: attrs + a0, id: cx.sess.next_id, node: ast::item_mod(m0), span: cdir.span}; diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index f605a2fb699..98dcb141192 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -1,5 +1,5 @@ -import std::{io, vec, str, option, either, result}; +import std::{io, vec, str, option, either, result, fs}; import std::option::{some, none}; import std::either::{left, right}; import std::map::{hashmap, new_str_hash}; @@ -2599,13 +2599,15 @@ fn parse_crate_from_crate_file(input: str, cfg: ast::crate_cfg, mutable chpos: p.get_chpos(), mutable byte_pos: p.get_byte_pos(), cfg: p.get_cfg()}; - let m = eval::eval_crate_directives_to_mod(cx, cdirs, prefix); + let (companionmod, _) = fs::splitext(fs::basename(input)); + let (m, attrs) = eval::eval_crate_directives_to_mod( + cx, cdirs, prefix, option::some(companionmod)); let hi = p.get_hi_pos(); expect(p, token::EOF); ret @spanned(lo, hi, {directives: cdirs, module: m, - attrs: crate_attrs, + attrs: crate_attrs + attrs, config: p.get_cfg()}); } |
