about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2011-06-28 11:24:24 -0700
committerBrian Anderson <banderson@mozilla.com>2011-06-28 15:25:47 -0700
commit0608e277b62bb96de225bfae404b3fcfef6253c4 (patch)
tree2706a9a1220cc2105edad5e5030fac469dc30c0e
parent7554423423c0770cad63178f31db699b9e7c62ed (diff)
Add some helper functions for attributes. Issue #487
-rw-r--r--src/comp/metadata/decoder.rs4
-rw-r--r--src/comp/middle/attr.rs74
-rw-r--r--src/comp/rustc.rc1
-rw-r--r--src/test/run-pass/item-attributes.rs201
4 files changed, 79 insertions, 201 deletions
diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs
index 8a58a4ce319..b7751fc2303 100644
--- a/src/comp/metadata/decoder.rs
+++ b/src/comp/metadata/decoder.rs
@@ -328,6 +328,10 @@ fn list_crate_attributes(&ebml::doc md, io::writer out) {
     out.write_str("\n\n");
 }
 
+fn get_crate_attributes(&vec[u8] data) -> vec[ast::attribute] {
+    ret get_attributes(ebml::new_doc(data));
+}
+
 fn list_crate_items(vec[u8] bytes, &ebml::doc md, io::writer out) {
     out.write_str("=Items=\n");
     auto paths = ebml::get_doc(md, tag_paths);
diff --git a/src/comp/middle/attr.rs b/src/comp/middle/attr.rs
new file mode 100644
index 00000000000..45b0ccb7026
--- /dev/null
+++ b/src/comp/middle/attr.rs
@@ -0,0 +1,74 @@
+import std::vec;
+import std::option;
+import front::ast;
+
+export get_linkage_metas;
+export find_attrs_by_name;
+
+// From a list of crate attributes get only the meta_items that impact crate
+// linkage
+fn find_linkage_metas(vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
+    let vec[@ast::meta_item] metas = [];
+    for (ast::attribute attr in find_attrs_by_name(attrs, "link")) {
+        alt (attr.node.value.node) {
+            case (ast::meta_list(_, ?items)) {
+                metas += items;
+            }
+            case (_) {
+                // FIXME: Maybe need a warning that this attr isn't
+                // being used for linkage
+            }
+        }
+    }
+    ret metas;
+}
+
+// Search a list of attributes and return only those with a specific name
+fn find_attrs_by_name(vec[ast::attribute] attrs,
+                      ast::ident name) -> vec[ast::attribute] {
+    auto filter = bind fn(&ast::attribute a,
+                          ast::ident name) -> option::t[ast::attribute] {
+        if (get_attr_name(a) == name) {
+            option::some(a)
+        } else {
+            option::none
+        }
+    } (_, name);
+    ret vec::filter_map(filter, attrs);
+}
+
+fn get_attr_name(&ast::attribute attr) -> ast::ident {
+    get_meta_item_name(@attr.node.value)
+}
+
+fn find_meta_items_by_name(vec[@ast::meta_item] metas,
+                           ast::ident name) -> vec[@ast::meta_item] {
+    auto filter = bind fn(&@ast::meta_item m,
+                          ast::ident name) -> option::t[@ast::meta_item] {
+        if (get_meta_item_name(m) == name) {
+            option::some(m)
+        } else {
+            option::none
+        }
+    } (_, name);
+    ret vec::filter_map(filter, metas);
+}
+
+fn get_meta_item_name(&@ast::meta_item meta) -> ast::ident {
+    alt (meta.node) {
+        case (ast::meta_word(?n)) { n }
+        case (ast::meta_name_value(?n, _)) { n }
+        case (ast::meta_list(?n, _)) { n }
+    }
+}
+
+//
+// Local Variables:
+// mode: rust
+// fill-column: 78;
+// indent-tabs-mode: nil
+// c-basic-offset: 4
+// buffer-file-coding-system: utf-8-unix
+// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
+// End:
+//
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index ac64e7068f2..75af89639ca 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -14,6 +14,7 @@ use std (name = "std",
          url = "http://rust-lang.org/src/std");
 
 mod middle {
+    mod attr;
     mod trans;
     mod ty;
     mod walk;
diff --git a/src/test/run-pass/item-attributes.rs b/src/test/run-pass/item-attributes.rs
deleted file mode 100644
index bb8f068874c..00000000000
--- a/src/test/run-pass/item-attributes.rs
+++ /dev/null
@@ -1,201 +0,0 @@
-// xfail-stage0
-
-// These are attributes of the implicit crate. Really this just needs to parse
-// for completeness since .rs files linked from .rc files support this
-// notation to specify their module's attributes
-#[attr1 = "val"];
-#[attr2 = "val"];
-#[attr3];
-#[attr4(attr5)];
-
-// These are are attributes of the following mod
-#[attr1 = "val"]
-#[attr2 = "val"]
-mod test_first_item_in_file_mod {
-}
-
-mod test_single_attr_outer {
-
-    #[attr = "val"]
-    const int x = 10;
-
-    #[attr = "val"]
-    fn f() {}
-
-    #[attr = "val"]
-    mod mod1 {
-    }
-
-    #[attr = "val"]
-    native "rust" mod rustrt { }
-
-    #[attr = "val"]
-    type t = obj { };
-
-
-    #[attr = "val"]
-    obj o() { }
-}
-
-mod test_multi_attr_outer {
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    const int x = 10;
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    fn f() {}
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    mod mod1 {
-    }
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    native "rust" mod rustrt { }
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    type t = obj { };
-
-
-    #[attr1 = "val"]
-    #[attr2 = "val"]
-    obj o() { }
-}
-
-mod test_stmt_single_attr_outer {
-
-    fn f() {
-
-        #[attr = "val"]
-        const int x = 10;
-
-        #[attr = "val"]
-        fn f() {}
-
-        /* FIXME: Issue #493
-        #[attr = "val"]
-        mod mod1 {
-        }
-
-        #[attr = "val"]
-        native "rust" mod rustrt {
-        }
-        */
-
-        #[attr = "val"]
-        type t = obj { };
-
-        #[attr = "val"]
-        obj o() { }
-
-    }
-}
-
-mod test_stmt_multi_attr_outer {
-
-    fn f() {
-
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        const int x = 10;
-
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        fn f() {}
-
-        /* FIXME: Issue #493
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        mod mod1 {
-        }
-
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        native "rust" mod rustrt {
-        }
-        */
-
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        type t = obj { };
-
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        obj o() { }
-
-    }
-}
-
-mod test_attr_inner {
-
-    mod m {
-        // This is an attribute of mod m
-        #[attr = "val"];
-    }
-}
-
-mod test_attr_inner_then_outer {
-
-    mod m {
-        // This is an attribute of mod m
-        #[attr = "val"];
-        // This is an attribute of fn f
-        #[attr = "val"]
-        fn f() {
-        }
-    }
-}
-
-mod test_attr_inner_then_outer_multi {
-    mod m {
-        // This is an attribute of mod m
-        #[attr1 = "val"];
-        #[attr2 = "val"];
-        // This is an attribute of fn f
-        #[attr1 = "val"]
-        #[attr2 = "val"]
-        fn f() {
-        }
-    }
-}
-
-mod test_distinguish_syntax_ext {
-
-    use std;
-
-    fn f() {
-        #fmt("test%s", "s");
-        #[attr = "val"]
-        fn g() {
-        }
-    }
-}
-
-mod test_other_forms {
-    #[attr]
-    #[attr(word)]
-    #[attr(attr(word))]
-    #[attr(key1 = "val",
-           key2 = "val",
-           attr)]
-    fn f() {
-    }
-}
-
-fn main() {
-}
-
-//
-// Local Variables:
-// mode: rust
-// fill-column: 78;
-// indent-tabs-mode: nil
-// c-basic-offset: 4
-// buffer-file-coding-system: utf-8-unix
-// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
-// End:
-//