about summary refs log tree commit diff
path: root/src/comp/syntax/parse/eval.rs
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-10-29 01:21:43 -0700
committerBrian Anderson <banderson@mozilla.com>2011-10-29 01:40:20 -0700
commite0f44730e8dc75c17dc86fcb48769d62a4dbcaae (patch)
treef11e4626c0fad600fe133c0a2551c1d23ff17d8e /src/comp/syntax/parse/eval.rs
parent2cebef095e61608a3d35710cb5fd3d7de18b68ac (diff)
downloadrust-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/parse/eval.rs')
-rw-r--r--src/comp/syntax/parse/eval.rs65
1 files changed, 60 insertions, 5 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};