]> git.proxmox.com Git - rustc.git/blob - src/librustdoc/attr_parser.rs
Imported Upstream version 0.6
[rustc.git] / src / librustdoc / attr_parser.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12 Attribute parsing
13
14 The attribute parser provides methods for pulling documentation out of
15 an AST's attributes.
16 */
17
18 use core::prelude::*;
19
20 use core::str;
21 use syntax::ast;
22 use syntax::attr;
23
24 pub struct CrateAttrs {
25 name: Option<~str>
26 }
27
28 #[cfg(test)]
29 mod test {
30 use syntax::ast;
31 use syntax;
32
33 use core::option::None;
34
35 pub fn parse_attributes(source: ~str) -> ~[ast::attribute] {
36 use syntax::parse;
37 use syntax::parse::attr::parser_attr;
38 use syntax::codemap;
39
40 let parse_sess = syntax::parse::new_parse_sess(None);
41 let parser = parse::new_parser_from_source_str(
42 parse_sess, ~[], ~"-", codemap::FssNone, @source);
43
44 parser.parse_outer_attributes()
45 }
46 }
47
48 fn doc_metas(
49 attrs: ~[ast::attribute]
50 ) -> ~[@ast::meta_item] {
51
52 let doc_attrs = attr::find_attrs_by_name(attrs, ~"doc");
53 let doc_metas = do doc_attrs.map |attr| {
54 attr::attr_meta(attr::desugar_doc_attr(attr))
55 };
56
57 return doc_metas;
58 }
59
60 pub fn parse_crate(attrs: ~[ast::attribute]) -> CrateAttrs {
61 let link_metas = attr::find_linkage_metas(attrs);
62 let name = attr::last_meta_item_value_str_by_name(link_metas, ~"name");
63
64 CrateAttrs {
65 name: name.map(|s| copy **s)
66 }
67 }
68
69 #[test]
70 fn should_extract_crate_name_from_link_attribute() {
71 let source = ~"#[link(name = \"snuggles\")]";
72 let attrs = test::parse_attributes(source);
73 let attrs = parse_crate(attrs);
74 assert!(attrs.name == Some(~"snuggles"));
75 }
76
77 #[test]
78 fn should_not_extract_crate_name_if_no_link_attribute() {
79 let source = ~"";
80 let attrs = test::parse_attributes(source);
81 let attrs = parse_crate(attrs);
82 assert!(attrs.name == None);
83 }
84
85 #[test]
86 fn should_not_extract_crate_name_if_no_name_value_in_link_attribute() {
87 let source = ~"#[link(whatever)]";
88 let attrs = test::parse_attributes(source);
89 let attrs = parse_crate(attrs);
90 assert!(attrs.name == None);
91 }
92
93 pub fn parse_desc(attrs: ~[ast::attribute]) -> Option<~str> {
94 let doc_strs = do doc_metas(attrs).filter_mapped |meta| {
95 attr::get_meta_item_value_str(*meta).map(|s| copy **s)
96 };
97 if doc_strs.is_empty() {
98 None
99 } else {
100 Some(str::connect(doc_strs, "\n"))
101 }
102 }
103
104 #[test]
105 fn parse_desc_should_handle_undocumented_mods() {
106 let source = ~"";
107 let attrs = test::parse_attributes(source);
108 let attrs = parse_desc(attrs);
109 assert!(attrs == None);
110 }
111
112 #[test]
113 fn parse_desc_should_parse_simple_doc_attributes() {
114 let source = ~"#[doc = \"basic\"]";
115 let attrs = test::parse_attributes(source);
116 let attrs = parse_desc(attrs);
117 assert!(attrs == Some(~"basic"));
118 }
119
120 pub fn parse_hidden(attrs: ~[ast::attribute]) -> bool {
121 do doc_metas(attrs).find |meta| {
122 match attr::get_meta_item_list(*meta) {
123 Some(metas) => {
124 let hiddens = attr::find_meta_items_by_name(metas, ~"hidden");
125 !hiddens.is_empty()
126 }
127 None => false
128 }
129 }.is_some()
130 }
131
132 #[test]
133 fn should_parse_hidden_attribute() {
134 let source = ~"#[doc(hidden)]";
135 let attrs = test::parse_attributes(source);
136 assert!(parse_hidden(attrs) == true);
137 }
138
139 #[test]
140 fn should_parse_hidden_attribute_with_other_docs() {
141 let source = ~"#[doc = \"foo\"] #[doc(hidden)] #[doc = \"foo\"]";
142 let attrs = test::parse_attributes(source);
143 assert!(parse_hidden(attrs) == true);
144 }
145
146 #[test]
147 fn should_not_parse_non_hidden_attribute() {
148 let source = ~"#[doc = \"\"]";
149 let attrs = test::parse_attributes(source);
150 assert!(parse_hidden(attrs) == false);
151 }
152
153 #[test]
154 fn should_concatenate_multiple_doc_comments() {
155 let source = ~"/// foo\n/// bar";
156 let desc = parse_desc(test::parse_attributes(source));
157 assert!(desc == Some(~"foo\nbar"));
158 }
159
160