about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2012-11-21 15:51:11 -0800
committerBrian Anderson <banderson@mozilla.com>2012-11-26 18:13:54 -0800
commit58e26243a7d7efa8e37703fb6dca95652c79f848 (patch)
treed9a3159063b0e604054aae0dbc1c1d1700523e64 /src/libsyntax/parse
parentde0268b693ad1ff0f319d189b081c26576b7d535 (diff)
downloadrust-58e26243a7d7efa8e37703fb6dca95652c79f848.tar.gz
rust-58e26243a7d7efa8e37703fb6dca95652c79f848.zip
syntax: Add a hack to support the int-template pattern
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/eval.rs21
-rw-r--r--src/libsyntax/parse/parser.rs41
2 files changed, 53 insertions, 9 deletions
diff --git a/src/libsyntax/parse/eval.rs b/src/libsyntax/parse/eval.rs
index 78a47ec09c7..cdfd8a9bcec 100644
--- a/src/libsyntax/parse/eval.rs
+++ b/src/libsyntax/parse/eval.rs
@@ -5,6 +5,7 @@ use codemap::span;
 
 export eval_crate_directives_to_mod;
 export eval_src_mod;
+export eval_src_mod_from_path;
 
 type ctx =
     @{sess: parse::parse_sess,
@@ -84,15 +85,23 @@ fn cdir_path_opt(default: ~str, attrs: ~[ast::attribute]) -> ~str {
     }
 }
 
-fn eval_src_mod(cx: ctx, prefix: &Path, id: ast::ident,
+fn eval_src_mod(cx: ctx, prefix: &Path,
                 outer_attrs: ~[ast::attribute],
-                sp: span) -> (ast::item_, ~[ast::attribute]) {
+                id: ast::ident, sp: span
+               ) -> (ast::item_, ~[ast::attribute]) {
     let file_path = Path(cdir_path_opt(
         cx.sess.interner.get(id) + ~".rs", outer_attrs));
-    let full_path = if file_path.is_absolute {
-        copy file_path
+    eval_src_mod_from_path(cx, prefix, &file_path, outer_attrs, sp)
+}
+
+fn eval_src_mod_from_path(cx: ctx, prefix: &Path, path: &Path,
+                          outer_attrs: ~[ast::attribute],
+                          sp: span
+                         ) -> (ast::item_, ~[ast::attribute]) {
+    let full_path = if path.is_absolute {
+        copy *path
     } else {
-        prefix.push_many(file_path.components)
+        prefix.push_many(path.components)
     };
     let p0 =
         new_sub_parser_from_file(cx.sess, cx.cfg,
@@ -121,7 +130,7 @@ fn eval_crate_directive(cx: ctx, cdir: @ast::crate_directive, prefix: &Path,
                         items: &mut ~[@ast::item]) {
     match cdir.node {
       ast::cdir_src_mod(vis, id, attrs) => {
-        let (m, mod_attrs) = eval_src_mod(cx, prefix, id, attrs, cdir.span);
+        let (m, mod_attrs) = eval_src_mod(cx, prefix, attrs, id, cdir.span);
         let i = mk_item(cx, cdir.span.lo, cdir.span.hi,
                            /* FIXME (#2543) */ copy id,
                            m, vis, mod_attrs);
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 925934d165f..2f32b8436af 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -2963,7 +2963,7 @@ impl Parser {
     fn parse_item_mod(outer_attrs: ~[ast::attribute]) -> item_info {
         let id_span = self.span;
         let id = self.parse_ident();
-        if self.token == token::SEMI {
+        let info_ = if self.token == token::SEMI {
             self.bump();
             // This mod is in an external file. Let's go get it!
             let eval_ctx = @{
@@ -2972,8 +2972,9 @@ impl Parser {
             };
             let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
             let prefix = prefix.dir_path();
-            let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix, id,
-                                                outer_attrs, id_span);
+            let (m, attrs) = eval::eval_src_mod(eval_ctx, &prefix,
+                                                outer_attrs,
+                                                id, id_span);
             (id, m, Some(move attrs))
         } else {
             self.expect(token::LBRACE);
@@ -2981,6 +2982,40 @@ impl Parser {
             let m = self.parse_mod_items(token::RBRACE, inner_attrs.next);
             self.expect(token::RBRACE);
             (id, item_mod(m), Some(inner_attrs.inner))
+        };
+
+        // XXX: Transitionary hack to do the template work inside core
+        // (int-template, iter-trait). If there's a 'merge' attribute
+        // on the mod, then we'll go and suck in another file and merge
+        // its contents
+        match ::attr::first_attr_value_str_by_name(outer_attrs, ~"merge") {
+            Some(path) => {
+                let eval_ctx = @{
+                    sess: self.sess,
+                    cfg: self.cfg
+                };
+                let prefix = Path(self.sess.cm.span_to_filename(copy self.span));
+                let prefix = prefix.dir_path();
+                let path = Path(path);
+                let (new_mod_item, new_attrs) = eval::eval_src_mod_from_path(
+                    eval_ctx, &prefix, &path, ~[], id_span);
+
+                let (main_id, main_mod_item, main_attrs) = info_;
+                let main_attrs = main_attrs.get();
+
+                let (main_mod, new_mod) = match (main_mod_item, new_mod_item) {
+                    (item_mod(m), item_mod(n)) => (m, n),
+                    _ => self.bug(~"parsed mod item should be mod")
+                };
+                let merged_mod = {
+                    view_items: main_mod.view_items + new_mod.view_items,
+                    items: main_mod.items + new_mod.items
+                };
+
+                let merged_attrs = main_attrs + new_attrs;
+                (main_id, item_mod(merged_mod), Some(merged_attrs))
+            }
+            None => info_
         }
     }