Skip to content

Commit 75dbb0f

Browse files
committed
rustdoc: Use attr API in attr_parser
1 parent 29409af commit 75dbb0f

File tree

1 file changed

+119
-60
lines changed

1 file changed

+119
-60
lines changed

src/rustdoc/attr_parser.rs

Lines changed: 119 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import rustc::syntax::ast;
2+
import rustc::front::attr;
23

34
export fn_attrs, arg_attrs;
45
export parse_fn;
@@ -15,86 +16,143 @@ type arg_attrs = {
1516
desc: str
1617
};
1718

19+
fn doc_meta(
20+
attrs: [ast::attribute]
21+
) -> option<@ast::meta_item> {
22+
let doc_attrs = attr::find_attrs_by_name(attrs, "doc");
23+
let doc_metas = attr::attr_metas(doc_attrs);
24+
if vec::is_not_empty(doc_metas) {
25+
if vec::len(doc_metas) != 1u {
26+
#warn("ignoring %u doc attributes", vec::len(doc_metas) - 1u);
27+
}
28+
some(doc_metas[0])
29+
} else {
30+
none
31+
}
32+
}
33+
1834
fn parse_fn(
1935
attrs: [ast::attribute]
2036
) -> fn_attrs {
2137

22-
for attr in attrs {
23-
alt attr.node.value.node {
24-
ast::meta_name_value(
25-
"doc", {node: ast::lit_str(value), span: _}) {
26-
ret {
38+
let no_attrs = {
39+
brief: none,
40+
desc: none,
41+
args: [],
42+
return: none
43+
};
44+
45+
ret alt doc_meta(attrs) {
46+
some(meta) {
47+
alt attr::get_meta_item_value_str(meta) {
48+
some(desc) {
49+
{
2750
brief: none,
28-
desc: some(value),
51+
desc: some(desc),
2952
args: [],
3053
return: none
31-
};
54+
}
3255
}
33-
ast::meta_list("doc", docs) {
34-
ret parse_fn_(docs);
56+
none. {
57+
alt attr::get_meta_item_list(meta) {
58+
some(list) {
59+
parse_fn_(list)
60+
}
61+
none. {
62+
no_attrs
63+
}
64+
}
3565
}
36-
_ { }
3766
}
67+
}
68+
none. {
69+
no_attrs
70+
}
71+
};
72+
}
73+
74+
fn meta_item_from_list(
75+
items: [@ast::meta_item],
76+
name: str
77+
) -> option<@ast::meta_item> {
78+
let items = attr::find_meta_items_by_name(items, name);
79+
vec::last(items)
80+
}
81+
82+
fn meta_item_value_from_list(
83+
items: [@ast::meta_item],
84+
name: str
85+
) -> option<str> {
86+
alt meta_item_from_list(items, name) {
87+
some(item) {
88+
alt attr::get_meta_item_value_str(item) {
89+
some(value) { some(value) }
90+
none. { none }
91+
}
92+
}
93+
none. { none }
3894
}
95+
}
3996

40-
{
41-
brief: none,
42-
desc: none,
43-
args: [],
44-
return: none
97+
fn meta_item_list_from_list(
98+
items: [@ast::meta_item],
99+
name: str
100+
) -> option<[@ast::meta_item]> {
101+
alt meta_item_from_list(items, name) {
102+
some(item) {
103+
attr::get_meta_item_list(item)
104+
}
105+
none. { none }
106+
}
107+
}
108+
109+
fn name_value_str_pair(
110+
item: @ast::meta_item
111+
) -> option<(str, str)> {
112+
alt attr::get_meta_item_value_str(item) {
113+
some(value) {
114+
let name = attr::get_meta_item_name(item);
115+
some((name, value))
116+
}
117+
none. { none }
45118
}
46119
}
47120

121+
fn fst<T, U>(+pair: (T, U)) -> T {
122+
let (t, _) = pair;
123+
ret t;
124+
}
125+
126+
fn snd<T, U>(+pair: (T, U)) -> U {
127+
let (_, u) = pair;
128+
ret u;
129+
}
130+
48131
fn parse_fn_(
49132
items: [@ast::meta_item]
50133
) -> fn_attrs {
51-
let brief = none;
52-
let desc = none;
53-
let return = none;
54-
let argdocs = [];
55-
let argdocsfound = none;
56-
for item: @ast::meta_item in items {
57-
alt item.node {
58-
ast::meta_name_value("brief", {node: ast::lit_str(value),
59-
span: _}) {
60-
brief = some(value);
61-
}
62-
ast::meta_name_value("desc", {node: ast::lit_str(value),
63-
span: _}) {
64-
desc = some(value);
65-
}
66-
ast::meta_name_value("return", {node: ast::lit_str(value),
67-
span: _}) {
68-
return = some(value);
69-
}
70-
ast::meta_list("args", args) {
71-
argdocsfound = some(args);
72-
}
73-
_ { }
74-
}
75-
}
76-
77-
alt argdocsfound {
78-
none. { }
79-
some(ds) {
80-
for d: @ast::meta_item in ds {
81-
alt d.node {
82-
ast::meta_name_value(key, {node: ast::lit_str(value),
83-
span: _}) {
84-
argdocs += [{
85-
name: key,
86-
desc: value
87-
}];
88-
}
134+
let brief = meta_item_value_from_list(items, "brief");
135+
let desc = meta_item_value_from_list(items, "desc");
136+
let return = meta_item_value_from_list(items, "return");
137+
138+
let args = alt meta_item_list_from_list(items, "args") {
139+
some(items) {
140+
vec::filter_map(items) {|item|
141+
option::map(name_value_str_pair(item)) { |pair|
142+
{
143+
name: fst(pair),
144+
desc: snd(pair)
89145
}
90146
}
91147
}
92-
}
148+
}
149+
none. { [] }
150+
};
93151

94152
{
95153
brief: brief,
96154
desc: desc,
97-
args: argdocs,
155+
args: args,
98156
return: return
99157
}
100158
}
@@ -103,11 +161,12 @@ fn parse_fn_(
103161
mod tests {
104162

105163
fn parse_attributes(source: str) -> [ast::attribute] {
106-
import rustc::driver::diagnostic;
107-
import rustc::syntax::codemap;
108164
import rustc::syntax::parse::parser;
165+
// FIXME: Uncommenting this results in rustc bugs
166+
//import rustc::syntax::codemap;
167+
import rustc::driver::diagnostic;
109168

110-
let cm = codemap::new_codemap();
169+
let cm = rustc::syntax::codemap::new_codemap();
111170
let parse_sess = @{
112171
cm: cm,
113172
mutable next_id: 0,
@@ -130,12 +189,12 @@ mod tests {
130189
assert vec::len(attrs.args) == 0u;
131190
}
132191

133-
#[tes]
192+
#[test]
134193
fn parse_fn_should_parse_simple_doc_attributes() {
135194
let source = "#[doc = \"basic\"]";
136195
let attrs = parse_attributes(source);
137196
let attrs = parse_fn(attrs);
138-
assert attrs.brief == some("basic");
197+
assert attrs.desc == some("basic");
139198
}
140199

141200
#[test]

0 commit comments

Comments
 (0)