@@ -955,10 +955,10 @@ fn parse_bottom_expr(&parser p) -> @ast::expr {
955
955
fn parse_syntax_ext ( & parser p) -> @ast:: expr {
956
956
auto lo = p. get_lo_pos ( ) ;
957
957
expect ( p, token:: POUND ) ;
958
- ret parse_syntax_ext_inner ( p, lo) ;
958
+ ret parse_syntax_ext_naked ( p, lo) ;
959
959
}
960
960
961
- fn parse_syntax_ext_inner ( & parser p, uint lo) -> @ast:: expr {
961
+ fn parse_syntax_ext_naked ( & parser p, uint lo) -> @ast:: expr {
962
962
auto pth = parse_path ( p) ;
963
963
auto es = parse_seq ( token:: LPAREN , token:: RPAREN ,
964
964
some ( token:: COMMA ) , parse_expr, p) ;
@@ -1496,7 +1496,7 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
1496
1496
} else {
1497
1497
1498
1498
auto item_attrs;
1499
- alt ( parse_attrs_or_ext ( p) ) {
1499
+ alt ( parse_outer_attrs_or_ext ( p) ) {
1500
1500
case ( none) {
1501
1501
item_attrs = [ ] ;
1502
1502
}
@@ -1799,11 +1799,14 @@ fn parse_item_obj(&parser p, ast::layer lyr, vec[ast::attribute] attrs) ->
1799
1799
p. next_def_id ( ) ) , attrs) ;
1800
1800
}
1801
1801
1802
- fn parse_mod_items ( & parser p, token:: token term) -> ast:: _mod {
1802
+ fn parse_mod_items ( & parser p, token:: token term,
1803
+ vec[ ast:: attribute ] first_item_attrs ) -> ast:: _mod {
1803
1804
auto view_items = parse_view ( p) ;
1804
1805
let vec[ @ast:: item] items = [ ] ;
1806
+ auto initial_attrs = first_item_attrs;
1805
1807
while ( p. peek ( ) != term) {
1806
- auto attrs = parse_attributes ( p) ;
1808
+ auto attrs = initial_attrs + parse_outer_attributes ( p) ;
1809
+ initial_attrs = [ ] ;
1807
1810
alt ( parse_item ( p, attrs) ) {
1808
1811
case ( got_item ( ?i) ) { vec:: push ( items, i) ; }
1809
1812
case ( _) {
@@ -1830,10 +1833,13 @@ fn parse_item_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item {
1830
1833
auto lo = p. get_last_lo_pos ( ) ;
1831
1834
auto id = parse_ident ( p) ;
1832
1835
expect ( p, token:: LBRACE ) ;
1833
- auto m = parse_mod_items ( p, token:: RBRACE ) ;
1836
+ auto inner_attrs = parse_inner_attributes ( p) ;
1837
+ auto first_item_outer_attrs = inner_attrs. _1 ;
1838
+ auto m = parse_mod_items ( p, token:: RBRACE ,
1839
+ first_item_outer_attrs) ;
1834
1840
auto hi = p. get_hi_pos ( ) ;
1835
1841
expect ( p, token:: RBRACE ) ;
1836
- ret mk_item( p, lo, hi, id, ast:: item_mod ( m) , attrs) ;
1842
+ ret mk_item( p, lo, hi, id, ast:: item_mod ( m) , attrs + inner_attrs . _0 ) ;
1837
1843
}
1838
1844
1839
1845
fn parse_item_native_type ( & parser p) -> @ast:: native_item {
@@ -2039,41 +2045,67 @@ fn parse_item(&parser p, vec[ast::attribute] attrs) -> parsed_item {
2039
2045
type attr_or_ext = option:: t [ either:: t[ vec[ ast:: attribute] ,
2040
2046
@ast:: expr] ] ;
2041
2047
2042
- fn parse_attrs_or_ext ( & parser p) -> attr_or_ext {
2048
+ fn parse_outer_attrs_or_ext ( & parser p) -> attr_or_ext {
2043
2049
if ( p. peek ( ) == token:: POUND ) {
2044
2050
auto lo = p. get_lo_pos ( ) ;
2045
2051
p. bump ( ) ;
2046
2052
if ( p. peek ( ) == token:: LBRACKET ) {
2047
- auto first_attr = parse_attribute_inner ( p, lo) ;
2048
- ret some ( left ( [ first_attr] + parse_attributes ( p) ) ) ;
2053
+ auto first_attr = parse_attribute_naked ( p, lo) ;
2054
+ ret some ( left ( [ first_attr] + parse_outer_attributes ( p) ) ) ;
2049
2055
} else {
2050
- ret some ( right ( parse_syntax_ext_inner ( p, lo) ) ) ;
2056
+ ret some ( right ( parse_syntax_ext_naked ( p, lo) ) ) ;
2051
2057
}
2052
2058
} else {
2053
2059
ret none;
2054
2060
}
2055
2061
}
2056
2062
2057
- fn parse_attributes ( & parser p) -> vec[ ast:: attribute ] {
2063
+ // Parse attributes that appear before an item
2064
+ fn parse_outer_attributes ( & parser p) -> vec[ ast:: attribute ] {
2058
2065
let vec[ ast:: attribute] attrs = [ ] ;
2059
- while ( p. peek ( ) == token:: POUND ) { attrs += [ parse_attribute ( p) ] ; }
2066
+ while ( p. peek ( ) == token:: POUND ) {
2067
+ attrs += [ parse_attribute ( p) ] ;
2068
+ }
2060
2069
ret attrs;
2061
2070
}
2062
2071
2063
2072
fn parse_attribute ( & parser p) -> ast:: attribute {
2064
2073
auto lo = p. get_lo_pos ( ) ;
2065
2074
expect ( p, token:: POUND ) ;
2066
- ret parse_attribute_inner ( p, lo) ;
2075
+ ret parse_attribute_naked ( p, lo) ;
2067
2076
}
2068
2077
2069
- fn parse_attribute_inner ( & parser p, uint lo) -> ast:: attribute {
2078
+ fn parse_attribute_naked ( & parser p, uint lo) -> ast:: attribute {
2070
2079
expect ( p, token:: LBRACKET ) ;
2071
2080
auto meta_item = parse_meta_item ( p) ;
2072
2081
expect ( p, token:: RBRACKET ) ;
2073
2082
auto hi = p. get_hi_pos ( ) ;
2074
2083
ret spanned( lo, hi, rec ( style=ast:: attr_outer, value=* meta_item) ) ;
2075
2084
}
2076
2085
2086
+ // Parse attributes that appear after the opening of an item, each terminated
2087
+ // by a semicolon. In addition to a vector of inner attributes, this function
2088
+ // also returns a vector that may contain the first outer attribute of the
2089
+ // next item (since we can't know whether the attribute is an inner attribute
2090
+ // of the containing item or an outer attribute of the first contained item
2091
+ // until we see the semi).
2092
+ fn parse_inner_attributes ( & parser p) -> tup ( vec[ ast:: attribute ] ,
2093
+ vec[ ast:: attribute ] ) {
2094
+ let vec[ ast:: attribute] inner_attrs = [ ] ;
2095
+ let vec[ ast:: attribute] next_outer_attrs = [ ] ;
2096
+ while ( p. peek ( ) == token:: POUND ) {
2097
+ auto attr = parse_attribute ( p) ;
2098
+ if ( p. peek ( ) == token:: SEMI ) {
2099
+ p. bump ( ) ;
2100
+ inner_attrs += [ attr] ;
2101
+ } else {
2102
+ next_outer_attrs += [ attr] ;
2103
+ break ;
2104
+ }
2105
+ }
2106
+ ret tup( inner_attrs, next_outer_attrs) ;
2107
+ }
2108
+
2077
2109
fn parse_meta_item ( & parser p) -> @ast:: meta_item {
2078
2110
auto lo = p. get_lo_pos ( ) ;
2079
2111
auto ident = parse_ident ( p) ;
@@ -2234,7 +2266,7 @@ fn parse_native_view(&parser p) -> vec[@ast::view_item] {
2234
2266
2235
2267
fn parse_crate_from_source_file ( & parser p) -> @ast:: crate {
2236
2268
auto lo = p. get_lo_pos ( ) ;
2237
- auto m = parse_mod_items ( p, token:: EOF ) ;
2269
+ auto m = parse_mod_items ( p, token:: EOF , [ ] ) ;
2238
2270
let vec[ @ast:: crate_directive] cdirs = [ ] ;
2239
2271
ret @spanned ( lo, p. get_lo_pos ( ) , rec ( directives=cdirs, module=m) ) ;
2240
2272
}
0 commit comments