9
9
// except according to those terms.
10
10
11
11
use ast;
12
- use codemap:: spanned;
12
+ use codemap:: { spanned, mk_sp } ;
13
13
use codemap:: BytePos ;
14
14
use parse:: common:: * ; //resolve bug?
15
15
use parse:: token;
16
16
use parse:: parser:: Parser ;
17
+ use parse:: token:: INTERPOLATED ;
17
18
18
19
// a parser that can parse attributes.
19
20
pub trait parser_attr {
20
21
fn parse_outer_attributes ( & self ) -> ~[ ast:: Attribute ] ;
21
- fn parse_attribute ( & self , style : ast:: AttrStyle ) -> ast:: Attribute ;
22
- fn parse_attribute_naked (
23
- & self ,
24
- style : ast:: AttrStyle ,
25
- lo : BytePos
26
- ) -> ast:: Attribute ;
22
+ fn parse_attribute ( & self , permit_inner : bool ) -> ast:: Attribute ;
27
23
fn parse_inner_attrs_and_next ( & self ) ->
28
24
( ~[ ast:: Attribute ] , ~[ ast:: Attribute ] ) ;
29
25
fn parse_meta_item ( & self ) -> @ast:: MetaItem ;
@@ -37,12 +33,17 @@ impl parser_attr for Parser {
37
33
fn parse_outer_attributes ( & self ) -> ~[ ast:: Attribute ] {
38
34
let mut attrs: ~[ ast:: Attribute ] = ~[ ] ;
39
35
loop {
36
+ debug ! ( "parse_outer_attributes: self.token=%?" ,
37
+ self . token) ;
40
38
match * self . token {
39
+ token:: INTERPOLATED ( token:: nt_attr( * ) ) => {
40
+ attrs. push ( self . parse_attribute ( false ) ) ;
41
+ }
41
42
token:: POUND => {
42
43
if self . look_ahead ( 1 , |t| * t != token:: LBRACKET ) {
43
44
break ;
44
45
}
45
- attrs. push ( self . parse_attribute ( ast :: AttrOuter ) ) ;
46
+ attrs. push ( self . parse_attribute ( false ) ) ;
46
47
}
47
48
token:: DOC_COMMENT ( s) => {
48
49
let attr = :: attr:: mk_sugared_doc_attr (
@@ -62,23 +63,49 @@ impl parser_attr for Parser {
62
63
return attrs;
63
64
}
64
65
65
- // matches attribute = # attribute_naked
66
- fn parse_attribute ( & self , style : ast:: AttrStyle ) -> ast:: Attribute {
67
- let lo = self . span . lo ;
68
- self . expect ( & token:: POUND ) ;
69
- return self . parse_attribute_naked ( style, lo) ;
66
+ // matches attribute = # [ meta_item ]
67
+ //
68
+ // if permit_inner is true, then a trailing `;` indicates an inner
69
+ // attribute
70
+ fn parse_attribute ( & self , permit_inner : bool ) -> ast:: Attribute {
71
+ debug ! ( "parse_attributes: permit_inner=%? self.token=%?" ,
72
+ permit_inner, self . token) ;
73
+ let ( span, value) = match * self . token {
74
+ INTERPOLATED ( token:: nt_attr( attr) ) => {
75
+ assert ! ( attr. node. style == ast:: AttrOuter ) ;
76
+ self . bump ( ) ;
77
+ ( attr. span , attr. node . value )
78
+ }
79
+ token:: POUND => {
80
+ let lo = self . span . lo ;
81
+ self . bump ( ) ;
82
+ self . expect ( & token:: LBRACKET ) ;
83
+ let meta_item = self . parse_meta_item ( ) ;
84
+ self . expect ( & token:: RBRACKET ) ;
85
+ let hi = self . span . hi ;
86
+ ( mk_sp ( lo, hi) , meta_item)
87
+ }
88
+ _ => {
89
+ self . fatal ( fmt ! ( "expected `#` but found `%s`" ,
90
+ self . this_token_to_str( ) ) ) ;
91
+ }
92
+ } ;
93
+ let style = if permit_inner && * self . token == token:: SEMI {
94
+ self . bump ( ) ;
95
+ ast:: AttrInner
96
+ } else {
97
+ ast:: AttrOuter
98
+ } ;
99
+ return spanned {
100
+ span : span,
101
+ node : ast:: Attribute_ {
102
+ style : style,
103
+ value : value,
104
+ is_sugared_doc : false
105
+ }
106
+ } ;
70
107
}
71
108
72
- // matches attribute_naked = [ meta_item ]
73
- fn parse_attribute_naked ( & self , style : ast:: AttrStyle , lo : BytePos ) ->
74
- ast:: Attribute {
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 } ) ; }
81
-
82
109
// Parse attributes that appear after the opening of an item, each
83
110
// terminated by a semicolon. In addition to a vector of inner attributes,
84
111
// this function also returns a vector that may contain the first outer
@@ -89,47 +116,37 @@ impl parser_attr for Parser {
89
116
// matches inner_attrs* outer_attr?
90
117
// you can make the 'next' field an Option, but the result is going to be
91
118
// more useful as a vector.
92
- fn parse_inner_attrs_and_next ( & self ) ->
93
- ( ~[ ast:: Attribute ] , ~[ ast:: Attribute ] ) {
119
+ fn parse_inner_attrs_and_next ( & self )
120
+ -> ( ~[ ast:: Attribute ] , ~[ ast:: Attribute ] ) {
94
121
let mut inner_attrs: ~[ ast:: Attribute ] = ~[ ] ;
95
122
let mut next_outer_attrs: ~[ ast:: Attribute ] = ~[ ] ;
96
123
loop {
97
- match * self . token {
98
- token:: POUND => {
99
- if self . look_ahead ( 1 , |t| * t != token:: LBRACKET ) {
100
- // This is an extension
101
- break ;
124
+ let attr = match * self . token {
125
+ token:: INTERPOLATED ( token:: nt_attr( * ) ) => {
126
+ self . parse_attribute ( true )
127
+ }
128
+ token:: POUND => {
129
+ if self . look_ahead ( 1 , |t| * t != token:: LBRACKET ) {
130
+ // This is an extension
131
+ break ;
132
+ }
133
+ self . parse_attribute ( true )
102
134
}
103
- let attr = self . parse_attribute ( ast:: AttrInner ) ;
104
- if * self . token == token:: SEMI {
135
+ token:: DOC_COMMENT ( s) => {
105
136
self . bump ( ) ;
106
- inner_attrs. push ( attr) ;
107
- } else {
108
- // It's not really an inner attribute
109
- let outer_attr =
110
- spanned ( attr. span . lo , attr. span . hi ,
111
- ast:: Attribute_ { style : ast:: AttrOuter ,
112
- value : attr. node . value ,
113
- is_sugared_doc : false } ) ;
114
- next_outer_attrs. push ( outer_attr) ;
115
- break ;
137
+ :: attr:: mk_sugared_doc_attr ( self . id_to_str ( s) ,
138
+ self . span . lo ,
139
+ self . span . hi )
116
140
}
117
- }
118
- token:: DOC_COMMENT ( s) => {
119
- let attr = :: attr:: mk_sugared_doc_attr (
120
- self . id_to_str ( s) ,
121
- self . span . lo ,
122
- self . span . hi
123
- ) ;
124
- self . bump ( ) ;
125
- if attr. node . style == ast:: AttrInner {
126
- inner_attrs. push ( attr) ;
127
- } else {
128
- next_outer_attrs. push ( attr) ;
129
- break ;
141
+ _ => {
142
+ break ;
130
143
}
131
- }
132
- _ => break
144
+ } ;
145
+ if attr. node . style == ast:: AttrInner {
146
+ inner_attrs. push ( attr) ;
147
+ } else {
148
+ next_outer_attrs. push ( attr) ;
149
+ break ;
133
150
}
134
151
}
135
152
( inner_attrs, next_outer_attrs)
0 commit comments