1
1
import rustc:: syntax:: ast;
2
+ import rustc:: front:: attr;
2
3
3
4
export fn_attrs, arg_attrs;
4
5
export parse_fn;
@@ -15,86 +16,143 @@ type arg_attrs = {
15
16
desc : str
16
17
} ;
17
18
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) != 1 u {
26
+ #warn ( "ignoring %u doc attributes" , vec:: len ( doc_metas) - 1 u) ;
27
+ }
28
+ some ( doc_metas[ 0 ] )
29
+ } else {
30
+ none
31
+ }
32
+ }
33
+
18
34
fn parse_fn (
19
35
attrs : [ ast:: attribute ]
20
36
) -> fn_attrs {
21
37
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
+ {
27
50
brief: none,
28
- desc : some ( value ) ,
51
+ desc: some ( desc ) ,
29
52
args: [ ] ,
30
53
return : none
31
- } ;
54
+ }
32
55
}
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
+ }
35
65
}
36
- _ { }
37
66
}
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 }
38
94
}
95
+ }
39
96
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 }
45
118
}
46
119
}
47
120
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
+
48
131
fn parse_fn_ (
49
132
items : [ @ast:: meta_item ]
50
133
) -> 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)
89
145
}
90
146
}
91
147
}
92
- }
148
+ }
149
+ none. { [ ] }
150
+ } ;
93
151
94
152
{
95
153
brief: brief,
96
154
desc: desc,
97
- args: argdocs ,
155
+ args: args ,
98
156
return : return
99
157
}
100
158
}
@@ -103,11 +161,12 @@ fn parse_fn_(
103
161
mod tests {
104
162
105
163
fn parse_attributes ( source : str ) -> [ ast:: attribute ] {
106
- import rustc:: driver:: diagnostic;
107
- import rustc:: syntax:: codemap;
108
164
import rustc:: syntax:: parse:: parser;
165
+ // FIXME: Uncommenting this results in rustc bugs
166
+ //import rustc::syntax::codemap;
167
+ import rustc:: driver:: diagnostic;
109
168
110
- let cm = codemap:: new_codemap ( ) ;
169
+ let cm = rustc :: syntax :: codemap:: new_codemap ( ) ;
111
170
let parse_sess = @{
112
171
cm: cm,
113
172
mutable next_id: 0 ,
@@ -130,12 +189,12 @@ mod tests {
130
189
assert vec:: len ( attrs. args ) == 0 u;
131
190
}
132
191
133
- #[ tes ]
192
+ #[ test ]
134
193
fn parse_fn_should_parse_simple_doc_attributes ( ) {
135
194
let source = "#[doc = \" basic\" ]" ;
136
195
let attrs = parse_attributes ( source) ;
137
196
let attrs = parse_fn ( attrs) ;
138
- assert attrs. brief == some ( "basic" ) ;
197
+ assert attrs. desc == some ( "basic" ) ;
139
198
}
140
199
141
200
#[ test]
0 commit comments