about summary refs log tree commit diff
path: root/src/comp/front
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-06-21 14:23:16 -0700
committerBrian Anderson <banderson@mozilla.com>2011-06-22 13:55:58 -0700
commitadc18bb24ae6dacf6bfd9ca9742d47e6d4187a6b (patch)
tree59624c339dda1e3da0dd1a6ba72f577e39fa095d /src/comp/front
parent64513808cadb809e324084687d94aa763b36c925 (diff)
downloadrust-adc18bb24ae6dacf6bfd9ca9742d47e6d4187a6b.tar.gz
rust-adc18bb24ae6dacf6bfd9ca9742d47e6d4187a6b.zip
rustc: Introduce and parse additional meta_item forms
Examples: #[test], #[link(name = "vers")]

Issue #487
Diffstat (limited to 'src/comp/front')
-rw-r--r--src/comp/front/ast.rs6
-rw-r--r--src/comp/front/creader.rs46
-rw-r--r--src/comp/front/parser.rs31
3 files changed, 62 insertions, 21 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 14bc0e8532e..31556c66b54 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -97,7 +97,11 @@ type crate_directive = spanned[crate_directive_];
 
 type meta_item = spanned[meta_item_];
 
-type meta_item_ = rec(ident key, str value);
+tag meta_item_ {
+    meta_word(ident);
+    meta_list(ident, vec[@meta_item]);
+    meta_key_value(ident, str);
+}
 
 type block = spanned[block_];
 
diff --git a/src/comp/front/creader.rs b/src/comp/front/creader.rs
index b297f062de9..e91f514deee 100644
--- a/src/comp/front/creader.rs
+++ b/src/comp/front/creader.rs
@@ -548,19 +548,30 @@ fn metadata_matches(hashmap[str, str] mm, &vec[@ast::meta_item] metas) ->
     log #fmt("matching %u metadata requirements against %u metadata items",
              vec::len(metas), mm.size());
     for (@ast::meta_item mi in metas) {
-        alt (mm.find(mi.node.key)) {
-            case (some(?v)) {
-                if (v == mi.node.value) {
-                    log #fmt("matched '%s': '%s'", mi.node.key,
-                             mi.node.value);
-                } else {
-                    log #fmt("missing '%s': '%s' (got '%s')", mi.node.key,
-                             mi.node.value, v);
-                    ret false;
+        alt (mi.node) {
+            case (ast::meta_key_value(?key, ?value)) {
+                alt (mm.find(key)) {
+                    case (some(?v)) {
+                        if (v == value) {
+                            log #fmt("matched '%s': '%s'", key,
+                                     value);
+                        } else {
+                            log #fmt("missing '%s': '%s' (got '%s')",
+                                     key,
+                                     value, v);
+                            ret false;
+                        }
+                    }
+                    case (none) {
+                        log #fmt("missing '%s': '%s'",
+                                 key, value);
+                        ret false;
+                    }
                 }
             }
-            case (none) {
-                log #fmt("missing '%s': '%s'", mi.node.key, mi.node.value);
+            case (_) {
+                // FIXME (#487): Support all forms of meta_item
+                log_err "unimplemented meta_item variant in metadata_matches";
                 ret false;
             }
         }
@@ -574,7 +585,18 @@ fn find_library_crate(&session::session sess, &ast::ident ident,
    option::t[tup(str, vec[u8])] {
     let str crate_name = ident;
     for (@ast::meta_item mi in metas) {
-        if (mi.node.key == "name") { crate_name = mi.node.value; break; }
+        alt (mi.node) {
+            case (ast::meta_key_value(?key, ?value)) {
+                if (key == "name") {
+                    crate_name = value;
+                    break;
+                }
+            }
+            case (_) {
+                // FIXME (#487)
+                sess.unimpl("meta_item variant")
+            }
+        }
     }
     auto nn = parser::default_native_lib_naming(sess);
     let str prefix = nn.prefix + crate_name;
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index 94ea7e7b69c..c6e256ac03f 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -2113,26 +2113,41 @@ fn parse_inner_attrs(&parser p) -> vec[ast::attribute] {
 fn parse_meta_item(&parser p) -> @ast::meta_item {
     auto lo = p.get_lo_pos();
     auto ident = parse_ident(p);
-    expect(p, token::EQ);
     alt (p.peek()) {
-        case (token::LIT_STR(?s)) {
-            auto hi = p.get_hi_pos();
+        case (token::EQ) {
             p.bump();
-            ret @spanned(lo, hi, rec(key=ident, value=p.get_str(s)));
+            alt (p.peek()) {
+                case (token::LIT_STR(?s)) {
+                    p.bump();
+                    auto value = p.get_str(s);
+                    auto hi = p.get_hi_pos();
+                    ret @spanned(lo, hi, ast::meta_key_value(ident, value));
+                }
+                case (_) {
+                    p.fatal("Metadata items must be string literals");
+                }
+            }
+        }
+        case (token::LPAREN) {
+            auto inner_items = parse_meta_seq(p);
+            auto hi = p.get_hi_pos();
+            ret @spanned(lo, hi, ast::meta_list(ident, inner_items));
+        }
+        case (_) {
+            auto hi = p.get_hi_pos();
+            ret @spanned(lo, hi, ast::meta_word(ident));
         }
-        case (_) { p.fatal("Metadata items must be string literals"); }
     }
-    fail;
 }
 
-fn parse_meta(&parser p) -> vec[@ast::meta_item] {
+fn parse_meta_seq(&parser p) -> vec[@ast::meta_item] {
     ret parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
                   parse_meta_item, p).node;
 }
 
 fn parse_optional_meta(&parser p) -> vec[@ast::meta_item] {
     alt (p.peek()) {
-        case (token::LPAREN) { ret parse_meta(p); }
+        case (token::LPAREN) { ret parse_meta_seq(p); }
         case (_) { let vec[@ast::meta_item] v = []; ret v; }
     }
 }