@@ -111,6 +111,12 @@ enum item_or_view_item {
111111 iovi_view_item( @view_item )
112112}
113113
114+ enum view_item_parse_mode {
115+ VIEW_ITEMS_AND_ITEMS_ALLOWED ,
116+ VIEW_ITEMS_ALLOWED ,
117+ IMPORTS_AND_ITEMS_ALLOWED
118+ }
119+
114120/* The expr situation is not as complex as I thought it would be.
115121The important thing is to make sure that lookahead doesn't balk
116122at INTERPOLATED tokens */
@@ -2054,7 +2060,7 @@ class parser {
20542060
20552061 let item_attrs = vec:: append ( first_item_attrs, item_attrs) ;
20562062
2057- match self . parse_item_or_view_item ( item_attrs) {
2063+ match self . parse_item_or_view_item ( item_attrs, true ) {
20582064 iovi_item( i) => {
20592065 let mut hi = i. span . hi ;
20602066 let decl = @spanned ( lo, hi, decl_item ( i) ) ;
@@ -2141,8 +2147,17 @@ class parser {
21412147 +first_item_attrs : ~[ attribute ] ) -> blk {
21422148 let mut stmts = ~[ ] ;
21432149 let mut expr = none;
2144- let { attrs_remaining, view_items} =
2145- self . parse_view ( first_item_attrs, true ) ;
2150+
2151+ let { attrs_remaining, view_items, items: items } =
2152+ self . parse_items_and_view_items ( first_item_attrs,
2153+ IMPORTS_AND_ITEMS_ALLOWED ) ;
2154+
2155+ for items. each |item| {
2156+ let decl = @spanned ( item. span . lo , item. span . hi , decl_item ( item) ) ;
2157+ push ( stmts, @spanned ( item. span . lo , item. span . hi ,
2158+ stmt_decl ( decl, self . get_id ( ) ) ) ) ;
2159+ }
2160+
21462161 let mut initial_attrs = attrs_remaining;
21472162
21482163 if self . token == token:: RBRACE && !vec:: is_empty ( initial_attrs) {
@@ -2709,9 +2724,11 @@ class parser {
27092724 fn parse_mod_items ( term : token:: token ,
27102725 +first_item_attrs : ~[ attribute ] ) -> _mod {
27112726 // Shouldn't be any view items since we've already parsed an item attr
2712- let { attrs_remaining, view_items} =
2713- self . parse_view ( first_item_attrs, false ) ;
2714- let mut items: ~[ @item] = ~[ ] ;
2727+ let { attrs_remaining, view_items, items: starting_items } =
2728+ self . parse_items_and_view_items ( first_item_attrs,
2729+ VIEW_ITEMS_AND_ITEMS_ALLOWED ) ;
2730+ let mut items: ~[ @item] = move starting_items;
2731+
27152732 let mut first = true ;
27162733 while self . token != term {
27172734 let mut attrs = self . parse_outer_attributes ( ) ;
@@ -2721,7 +2738,7 @@ class parser {
27212738 }
27222739 debug ! ( "parse_mod_items: parse_item_or_view_item(attrs=%?)" ,
27232740 attrs) ;
2724- match self . parse_item_or_view_item ( attrs) {
2741+ match self . parse_item_or_view_item ( attrs, true ) {
27252742 iovi_item( item) => vec:: push ( items, item) ,
27262743 iovi_view_item( view_item) => {
27272744 self . span_fatal ( view_item. span , ~"view items must be \
@@ -2797,8 +2814,10 @@ class parser {
27972814 fn parse_foreign_mod_items ( +first_item_attrs : ~[ attribute ] ) ->
27982815 foreign_mod {
27992816 // Shouldn't be any view items since we've already parsed an item attr
2800- let { attrs_remaining, view_items} =
2801- self . parse_view ( first_item_attrs, false ) ;
2817+ let { attrs_remaining, view_items, items: _ } =
2818+ self . parse_items_and_view_items ( first_item_attrs,
2819+ VIEW_ITEMS_ALLOWED ) ;
2820+
28022821 let mut items: ~[ @foreign_item ] = ~[ ] ;
28032822 let mut initial_attrs = attrs_remaining;
28042823 while self . token != token:: RBRACE {
@@ -2813,7 +2832,8 @@ class parser {
28132832
28142833 fn parse_item_foreign_mod ( lo : uint ,
28152834 visibility : visibility ,
2816- attrs : ~[ attribute ] )
2835+ attrs : ~[ attribute ] ,
2836+ items_allowed : bool )
28172837 -> item_or_view_item {
28182838 if self . is_keyword ( ~"mod ") {
28192839 self . expect_keyword ( ~"mod ") ;
@@ -2823,7 +2843,7 @@ class parser {
28232843 let ident = self . parse_ident ( ) ;
28242844
28252845 // extern mod { ... }
2826- if self . eat ( token:: LBRACE ) {
2846+ if items_allowed && self . eat ( token:: LBRACE ) {
28272847 let extra_attrs = self . parse_inner_attrs_and_next ( ) ;
28282848 let m = self . parse_foreign_mod_items ( extra_attrs. next ) ;
28292849 self . expect ( token:: RBRACE ) ;
@@ -2836,6 +2856,7 @@ class parser {
28362856
28372857 // extern mod foo;
28382858 let metadata = self . parse_optional_meta ( ) ;
2859+ self . expect ( token:: SEMI ) ;
28392860 return iovi_view_item ( @{
28402861 node: view_item_use ( ident, metadata, self . get_id ( ) ) ,
28412862 attrs: attrs,
@@ -3033,7 +3054,8 @@ class parser {
30333054 }
30343055 }
30353056
3036- fn parse_item_or_view_item ( +attrs : ~[ attribute ] ) -> item_or_view_item {
3057+ fn parse_item_or_view_item ( +attrs : ~[ attribute ] , items_allowed : bool )
3058+ -> item_or_view_item {
30373059 maybe_whole ! { iovi self , nt_item} ;
30383060 let lo = self . span . lo ;
30393061
@@ -3046,25 +3068,26 @@ class parser {
30463068 visibility = inherited;
30473069 }
30483070
3049- if self . eat_keyword ( ~"const ") {
3071+ if items_allowed && self . eat_keyword ( ~"const ") {
30503072 let ( ident, item_, extra_attrs) = self . parse_item_const ( ) ;
30513073 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30523074 visibility,
30533075 maybe_append ( attrs, extra_attrs) ) ) ;
3054- } else if self . is_keyword ( ~"fn ") &&
3076+ } else if items_allowed &&
3077+ self . is_keyword ( ~"fn ") &&
30553078 !self . fn_expr_lookahead ( self . look_ahead ( 1 u) ) {
30563079 self . bump ( ) ;
30573080 let ( ident, item_, extra_attrs) = self . parse_item_fn ( impure_fn) ;
30583081 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30593082 visibility,
30603083 maybe_append ( attrs, extra_attrs) ) ) ;
3061- } else if self . eat_keyword ( ~"pure") {
3084+ } else if items_allowed && self . eat_keyword ( ~"pure") {
30623085 self . expect_keyword ( ~"fn ") ;
30633086 let ( ident, item_, extra_attrs) = self . parse_item_fn ( pure_fn) ;
30643087 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30653088 visibility,
30663089 maybe_append ( attrs, extra_attrs) ) ) ;
3067- } else if self . is_keyword ( ~"unsafe ")
3090+ } else if items_allowed && self . is_keyword ( ~"unsafe ")
30683091 && self . look_ahead ( 1 u) != token:: LBRACE {
30693092 self . bump ( ) ;
30703093 self . expect_keyword ( ~"fn ") ;
@@ -3073,54 +3096,57 @@ class parser {
30733096 visibility,
30743097 maybe_append ( attrs, extra_attrs) ) ) ;
30753098 } else if self . eat_keyword ( ~"extern ") {
3076- // XXX: "extern mod foo;" syntax as a "use" replacement.
3077- if self . eat_keyword ( ~"fn ") {
3099+ if items_allowed && self.eat_keyword(~" fn ") {
30783100 let ( ident, item_, extra_attrs) =
30793101 self . parse_item_fn ( extern_fn) ;
30803102 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident,
30813103 item_, visibility,
30823104 maybe_append ( attrs,
30833105 extra_attrs) ) ) ;
30843106 }
3085- return self . parse_item_foreign_mod ( lo, visibility, attrs) ;
3086- } else if self . eat_keyword ( ~"mod ") || self . eat_keyword ( ~"module") {
3107+ return self . parse_item_foreign_mod ( lo, visibility, attrs,
3108+ items_allowed) ;
3109+ } else if items_allowed && ( self . eat_keyword ( ~"mod ") ||
3110+ self . eat_keyword ( ~"module") ) {
30873111 let ( ident, item_, extra_attrs) = self . parse_item_mod ( ) ;
30883112 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30893113 visibility,
30903114 maybe_append ( attrs, extra_attrs) ) ) ;
3091- } else if self . eat_keyword ( ~"type ") {
3115+ } else if items_allowed && self . eat_keyword ( ~"type ") {
30923116 let ( ident, item_, extra_attrs) = self . parse_item_type ( ) ;
30933117 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30943118 visibility,
30953119 maybe_append ( attrs, extra_attrs) ) ) ;
3096- } else if self . eat_keyword ( ~"enum ") {
3120+ } else if items_allowed && self . eat_keyword ( ~"enum ") {
30973121 let ( ident, item_, extra_attrs) = self . parse_item_enum ( ) ;
30983122 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
30993123 visibility,
31003124 maybe_append ( attrs, extra_attrs) ) ) ;
3101- } else if self . eat_keyword ( ~"iface") {
3125+ } else if items_allowed && self . eat_keyword ( ~"iface") {
31023126 self . warn ( ~"`iface` is deprecated; use `trait `") ;
31033127 let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
31043128 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
31053129 visibility,
31063130 maybe_append ( attrs, extra_attrs) ) ) ;
3107- } else if self . eat_keyword ( ~"trait ") {
3131+ } else if items_allowed && self . eat_keyword ( ~"trait ") {
31083132 let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
31093133 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
31103134 visibility,
31113135 maybe_append ( attrs, extra_attrs) ) ) ;
3112- } else if self . eat_keyword ( ~"impl ") {
3136+ } else if items_allowed && self . eat_keyword ( ~"impl ") {
31133137 let ( ident, item_, extra_attrs) = self . parse_item_impl ( ) ;
31143138 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
31153139 visibility,
31163140 maybe_append ( attrs, extra_attrs) ) ) ;
3117- } else if self . eat_keyword ( ~"class") || self . eat_keyword ( ~"struct ") {
3141+ } else if items_allowed &&
3142+ ( self . eat_keyword ( ~"class") || self . eat_keyword ( ~"struct ") ) {
31183143 let ( ident, item_, extra_attrs) = self . parse_item_class ( ) ;
31193144 return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
31203145 visibility,
31213146 maybe_append ( attrs, extra_attrs) ) ) ;
31223147 } else if self . eat_keyword ( ~"use ") {
31233148 let view_item = self . parse_use ( ) ;
3149+ self . expect ( token:: SEMI ) ;
31243150 return iovi_view_item ( @{
31253151 node: view_item,
31263152 attrs: attrs,
@@ -3129,6 +3155,7 @@ class parser {
31293155 } ) ;
31303156 } else if self . eat_keyword ( ~"import") {
31313157 let view_paths = self . parse_view_paths ( ) ;
3158+ self . expect ( token:: SEMI ) ;
31323159 return iovi_view_item ( @{
31333160 node: view_item_import ( view_paths) ,
31343161 attrs: attrs,
@@ -3137,15 +3164,16 @@ class parser {
31373164 } ) ;
31383165 } else if self . eat_keyword ( ~"export") {
31393166 let view_paths = self . parse_view_paths ( ) ;
3167+ self . expect ( token:: SEMI ) ;
31403168 return iovi_view_item ( @{
31413169 node: view_item_export ( view_paths) ,
31423170 attrs: attrs,
31433171 vis: visibility,
31443172 span: mk_sp ( lo, self . last_span . hi )
31453173 } ) ;
3146- } else if !self . is_any_keyword ( copy self . token )
3174+ } else if items_allowed && ( !self . is_any_keyword ( copy self . token )
31473175 && self . look_ahead ( 1 ) == token:: NOT
3148- && is_plain_ident ( self . look_ahead ( 2 ) ) {
3176+ && is_plain_ident ( self . look_ahead ( 2 ) ) ) {
31493177 // item macro.
31503178 let pth = self . parse_path_without_tps ( ) ;
31513179 self . expect ( token:: NOT ) ;
@@ -3173,7 +3201,7 @@ class parser {
31733201 }
31743202
31753203 fn parse_item ( +attrs : ~[ attribute ] ) -> option < @ast:: item > {
3176- match self . parse_item_or_view_item ( attrs) {
3204+ match self . parse_item_or_view_item ( attrs, true ) {
31773205 iovi_none =>
31783206 none,
31793207 iovi_view_item( _) =>
@@ -3296,18 +3324,53 @@ class parser {
32963324 vis: vis, span: mk_sp ( lo, self . last_span . hi ) }
32973325 }
32983326
3299- fn parse_view ( +first_item_attrs : ~[ attribute ] ,
3300- only_imports : bool ) -> { attrs_remaining : ~[ attribute ] ,
3301- view_items : ~[ @view_item ] } {
3327+ fn parse_items_and_view_items ( +first_item_attrs : ~[ attribute ] ,
3328+ mode : view_item_parse_mode )
3329+ -> { attrs_remaining : ~[ attribute ] ,
3330+ view_items : ~[ @view_item ] ,
3331+ items : ~[ @item] } {
33023332 let mut attrs = vec:: append ( first_item_attrs,
33033333 self . parse_outer_attributes ( ) ) ;
3304- let mut items = ~[ ] ;
3305- while if only_imports { self . is_keyword ( ~"import") }
3306- else { self . is_view_item ( ) } {
3307- vec:: push ( items, self . parse_view_item ( attrs) ) ;
3334+
3335+ let items_allowed;
3336+ match mode {
3337+ VIEW_ITEMS_AND_ITEMS_ALLOWED | IMPORTS_AND_ITEMS_ALLOWED =>
3338+ items_allowed = true ,
3339+ VIEW_ITEMS_ALLOWED =>
3340+ items_allowed = false
3341+ }
3342+
3343+ let ( view_items, items) = ( dvec ( ) , dvec ( ) ) ;
3344+ loop {
3345+ match self . parse_item_or_view_item ( attrs, items_allowed) {
3346+ iovi_none =>
3347+ break ,
3348+ iovi_view_item( view_item) => {
3349+ match mode {
3350+ VIEW_ITEMS_AND_ITEMS_ALLOWED |
3351+ VIEW_ITEMS_ALLOWED => { }
3352+ IMPORTS_AND_ITEMS_ALLOWED =>
3353+ match view_item. node {
3354+ view_item_import( _) => { }
3355+ view_item_export( _) | view_item_use( * ) =>
3356+ self . fatal ( ~"exports and \"extern mod \" \
3357+ declarations are not \
3358+ allowed here")
3359+ }
3360+ }
3361+ view_items. push ( view_item) ;
3362+ }
3363+ iovi_item( item) => {
3364+ assert items_allowed;
3365+ items. push ( item)
3366+ }
3367+ }
33083368 attrs = self . parse_outer_attributes ( ) ;
33093369 }
3310- { attrs_remaining: attrs, view_items: items}
3370+
3371+ { attrs_remaining: attrs,
3372+ view_items: vec:: from_mut ( dvec:: unwrap ( view_items) ) ,
3373+ items: vec:: from_mut ( dvec:: unwrap ( items) ) }
33113374 }
33123375
33133376 // Parses a source module as a crate
0 commit comments