]>
git.proxmox.com Git - rustc.git/blob - src/libsyntax/parse/attr.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.
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.
14 use parse
::common
::*; //resolve bug?
16 use parse
::parser
::Parser
;
18 // a parser that can parse attributes.
19 pub trait parser_attr
{
20 fn parse_outer_attributes(&self) -> ~[ast
::attribute
];
21 fn parse_attribute(&self, style
: ast
::attr_style
) -> ast
::attribute
;
22 fn parse_attribute_naked(
24 style
: ast
::attr_style
,
27 fn parse_inner_attrs_and_next(&self) ->
28 (~[ast
::attribute
], ~[ast
::attribute
]);
29 fn parse_meta_item(&self) -> @ast
::meta_item
;
30 fn parse_meta_seq(&self) -> ~[@ast
::meta_item
];
31 fn parse_optional_meta(&self) -> ~[@ast
::meta_item
];
34 impl parser_attr
for Parser
{
36 // Parse attributes that appear before an item
37 fn parse_outer_attributes(&self) -> ~[ast
::attribute
] {
38 let mut attrs
: ~[ast
::attribute
] = ~[];
42 if self.look_ahead(1u) != token
::LBRACKET
{
45 attrs
.push(self.parse_attribute(ast
::attr_outer
));
47 token
::DOC_COMMENT(s
) => {
48 let attr
= ::attr
::mk_sugared_doc_attr(
53 if attr
.node
.style
!= ast
::attr_outer
{
54 self.fatal("expected outer comment");
65 // matches attribute = # attribute_naked
66 fn parse_attribute(&self, style
: ast
::attr_style
) -> ast
::attribute
{
67 let lo
= self.span
.lo
;
68 self.expect(&token
::POUND
);
69 return self.parse_attribute_naked(style
, lo
);
72 // matches attribute_naked = [ meta_item ]
73 fn parse_attribute_naked(&self, style
: ast
::attr_style
, lo
: BytePos
) ->
75 self.expect(&token
::LBRACKET
);
76 let meta_item
= self.parse_meta_item();
77 self.expect(&token
::RBRACKET
);
78 let hi
= self.span
.hi
;
79 return spanned(lo
, hi
, ast
::attribute_
{ style
: style
,
80 value
: meta_item
, is_sugared_doc
: false }); }
82 // Parse attributes that appear after the opening of an item, each
83 // terminated by a semicolon. In addition to a vector of inner attributes,
84 // this function also returns a vector that may contain the first outer
85 // attribute of the next item (since we can't know whether the attribute
86 // is an inner attribute of the containing item or an outer attribute of
87 // the first contained item until we see the semi).
89 // matches inner_attrs* outer_attr?
90 // you can make the 'next' field an Option, but the result is going to be
91 // more useful as a vector.
92 fn parse_inner_attrs_and_next(&self) ->
93 (~[ast
::attribute
], ~[ast
::attribute
]) {
94 let mut inner_attrs
: ~[ast
::attribute
] = ~[];
95 let mut next_outer_attrs
: ~[ast
::attribute
] = ~[];
99 if self.look_ahead(1u) != token
::LBRACKET
{
100 // This is an extension
103 let attr
= self.parse_attribute(ast
::attr_inner
);
104 if *self.token
== token
::SEMI
{
106 inner_attrs
.push(attr
);
108 // It's not really an inner attribute
110 spanned(attr
.span
.lo
, attr
.span
.hi
,
111 ast
::attribute_
{ style
: ast
::attr_outer
,
112 value
: attr
.node
.value
,
113 is_sugared_doc
: false });
114 next_outer_attrs
.push(outer_attr
);
118 token
::DOC_COMMENT(s
) => {
119 let attr
= ::attr
::mk_sugared_doc_attr(
125 if attr
.node
.style
== ast
::attr_inner
{
126 inner_attrs
.push(attr
);
128 next_outer_attrs
.push(attr
);
135 (inner_attrs
, next_outer_attrs
)
138 // matches meta_item = IDENT
141 fn parse_meta_item(&self) -> @ast
::meta_item
{
142 let lo
= self.span
.lo
;
143 let name
= self.id_to_str(self.parse_ident());
147 let lit
= self.parse_lit();
148 let hi
= self.span
.hi
;
149 @
spanned(lo
, hi
, ast
::meta_name_value(name
, lit
))
152 let inner_items
= self.parse_meta_seq();
153 let hi
= self.span
.hi
;
154 @
spanned(lo
, hi
, ast
::meta_list(name
, inner_items
))
157 let hi
= self.last_span
.hi
;
158 @
spanned(lo
, hi
, ast
::meta_word(name
))
163 // matches meta_seq = ( COMMASEP(meta_item) )
164 fn parse_meta_seq(&self) -> ~[@ast
::meta_item
] {
168 seq_sep_trailing_disallowed(token
::COMMA
),
169 |p
| p
.parse_meta_item()
173 fn parse_optional_meta(&self) -> ~[@ast
::meta_item
] {
175 token
::LPAREN
=> self.parse_meta_seq(),