@@ -111,6 +111,12 @@ enum item_or_view_item {
111
111
iovi_view_item( @view_item )
112
112
}
113
113
114
+ enum view_item_parse_mode {
115
+ VIEW_ITEMS_AND_ITEMS_ALLOWED ,
116
+ VIEW_ITEMS_ALLOWED ,
117
+ IMPORTS_AND_ITEMS_ALLOWED
118
+ }
119
+
114
120
/* The expr situation is not as complex as I thought it would be.
115
121
The important thing is to make sure that lookahead doesn't balk
116
122
at INTERPOLATED tokens */
@@ -2054,7 +2060,7 @@ class parser {
2054
2060
2055
2061
let item_attrs = vec:: append ( first_item_attrs, item_attrs) ;
2056
2062
2057
- match self . parse_item_or_view_item ( item_attrs) {
2063
+ match self . parse_item_or_view_item ( item_attrs, true ) {
2058
2064
iovi_item( i) => {
2059
2065
let mut hi = i. span . hi ;
2060
2066
let decl = @spanned ( lo, hi, decl_item ( i) ) ;
@@ -2141,8 +2147,17 @@ class parser {
2141
2147
+first_item_attrs : ~[ attribute ] ) -> blk {
2142
2148
let mut stmts = ~[ ] ;
2143
2149
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
+
2146
2161
let mut initial_attrs = attrs_remaining;
2147
2162
2148
2163
if self . token == token:: RBRACE && !vec:: is_empty ( initial_attrs) {
@@ -2709,9 +2724,11 @@ class parser {
2709
2724
fn parse_mod_items ( term : token:: token ,
2710
2725
+first_item_attrs : ~[ attribute ] ) -> _mod {
2711
2726
// 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
+
2715
2732
let mut first = true ;
2716
2733
while self . token != term {
2717
2734
let mut attrs = self . parse_outer_attributes ( ) ;
@@ -2721,7 +2738,7 @@ class parser {
2721
2738
}
2722
2739
debug ! ( "parse_mod_items: parse_item_or_view_item(attrs=%?)" ,
2723
2740
attrs) ;
2724
- match self . parse_item_or_view_item ( attrs) {
2741
+ match self . parse_item_or_view_item ( attrs, true ) {
2725
2742
iovi_item( item) => vec:: push ( items, item) ,
2726
2743
iovi_view_item( view_item) => {
2727
2744
self . span_fatal ( view_item. span , ~"view items must be \
@@ -2797,8 +2814,10 @@ class parser {
2797
2814
fn parse_foreign_mod_items ( +first_item_attrs : ~[ attribute ] ) ->
2798
2815
foreign_mod {
2799
2816
// 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
+
2802
2821
let mut items: ~[ @foreign_item ] = ~[ ] ;
2803
2822
let mut initial_attrs = attrs_remaining;
2804
2823
while self . token != token:: RBRACE {
@@ -2813,7 +2832,8 @@ class parser {
2813
2832
2814
2833
fn parse_item_foreign_mod ( lo : uint ,
2815
2834
visibility : visibility ,
2816
- attrs : ~[ attribute ] )
2835
+ attrs : ~[ attribute ] ,
2836
+ items_allowed : bool )
2817
2837
-> item_or_view_item {
2818
2838
if self . is_keyword ( ~"mod ") {
2819
2839
self . expect_keyword ( ~"mod ") ;
@@ -2823,7 +2843,7 @@ class parser {
2823
2843
let ident = self . parse_ident ( ) ;
2824
2844
2825
2845
// extern mod { ... }
2826
- if self . eat ( token:: LBRACE ) {
2846
+ if items_allowed && self . eat ( token:: LBRACE ) {
2827
2847
let extra_attrs = self . parse_inner_attrs_and_next ( ) ;
2828
2848
let m = self . parse_foreign_mod_items ( extra_attrs. next ) ;
2829
2849
self . expect ( token:: RBRACE ) ;
@@ -2836,6 +2856,7 @@ class parser {
2836
2856
2837
2857
// extern mod foo;
2838
2858
let metadata = self . parse_optional_meta ( ) ;
2859
+ self . expect ( token:: SEMI ) ;
2839
2860
return iovi_view_item ( @{
2840
2861
node: view_item_use ( ident, metadata, self . get_id ( ) ) ,
2841
2862
attrs: attrs,
@@ -3033,7 +3054,8 @@ class parser {
3033
3054
}
3034
3055
}
3035
3056
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 {
3037
3059
maybe_whole ! { iovi self , nt_item} ;
3038
3060
let lo = self . span . lo ;
3039
3061
@@ -3046,25 +3068,26 @@ class parser {
3046
3068
visibility = inherited;
3047
3069
}
3048
3070
3049
- if self . eat_keyword ( ~"const ") {
3071
+ if items_allowed && self . eat_keyword ( ~"const ") {
3050
3072
let ( ident, item_, extra_attrs) = self . parse_item_const ( ) ;
3051
3073
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3052
3074
visibility,
3053
3075
maybe_append ( attrs, extra_attrs) ) ) ;
3054
- } else if self . is_keyword ( ~"fn ") &&
3076
+ } else if items_allowed &&
3077
+ self . is_keyword ( ~"fn ") &&
3055
3078
!self . fn_expr_lookahead ( self . look_ahead ( 1 u) ) {
3056
3079
self . bump ( ) ;
3057
3080
let ( ident, item_, extra_attrs) = self . parse_item_fn ( impure_fn) ;
3058
3081
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3059
3082
visibility,
3060
3083
maybe_append ( attrs, extra_attrs) ) ) ;
3061
- } else if self . eat_keyword ( ~"pure") {
3084
+ } else if items_allowed && self . eat_keyword ( ~"pure") {
3062
3085
self . expect_keyword ( ~"fn ") ;
3063
3086
let ( ident, item_, extra_attrs) = self . parse_item_fn ( pure_fn) ;
3064
3087
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3065
3088
visibility,
3066
3089
maybe_append ( attrs, extra_attrs) ) ) ;
3067
- } else if self . is_keyword ( ~"unsafe ")
3090
+ } else if items_allowed && self . is_keyword ( ~"unsafe ")
3068
3091
&& self . look_ahead ( 1 u) != token:: LBRACE {
3069
3092
self . bump ( ) ;
3070
3093
self . expect_keyword ( ~"fn ") ;
@@ -3073,54 +3096,57 @@ class parser {
3073
3096
visibility,
3074
3097
maybe_append ( attrs, extra_attrs) ) ) ;
3075
3098
} 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 ") {
3078
3100
let ( ident, item_, extra_attrs) =
3079
3101
self . parse_item_fn ( extern_fn) ;
3080
3102
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident,
3081
3103
item_, visibility,
3082
3104
maybe_append ( attrs,
3083
3105
extra_attrs) ) ) ;
3084
3106
}
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") ) {
3087
3111
let ( ident, item_, extra_attrs) = self . parse_item_mod ( ) ;
3088
3112
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3089
3113
visibility,
3090
3114
maybe_append ( attrs, extra_attrs) ) ) ;
3091
- } else if self . eat_keyword ( ~"type ") {
3115
+ } else if items_allowed && self . eat_keyword ( ~"type ") {
3092
3116
let ( ident, item_, extra_attrs) = self . parse_item_type ( ) ;
3093
3117
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3094
3118
visibility,
3095
3119
maybe_append ( attrs, extra_attrs) ) ) ;
3096
- } else if self . eat_keyword ( ~"enum ") {
3120
+ } else if items_allowed && self . eat_keyword ( ~"enum ") {
3097
3121
let ( ident, item_, extra_attrs) = self . parse_item_enum ( ) ;
3098
3122
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3099
3123
visibility,
3100
3124
maybe_append ( attrs, extra_attrs) ) ) ;
3101
- } else if self . eat_keyword ( ~"iface") {
3125
+ } else if items_allowed && self . eat_keyword ( ~"iface") {
3102
3126
self . warn ( ~"`iface` is deprecated; use `trait `") ;
3103
3127
let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
3104
3128
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3105
3129
visibility,
3106
3130
maybe_append ( attrs, extra_attrs) ) ) ;
3107
- } else if self . eat_keyword ( ~"trait ") {
3131
+ } else if items_allowed && self . eat_keyword ( ~"trait ") {
3108
3132
let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
3109
3133
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3110
3134
visibility,
3111
3135
maybe_append ( attrs, extra_attrs) ) ) ;
3112
- } else if self . eat_keyword ( ~"impl ") {
3136
+ } else if items_allowed && self . eat_keyword ( ~"impl ") {
3113
3137
let ( ident, item_, extra_attrs) = self . parse_item_impl ( ) ;
3114
3138
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3115
3139
visibility,
3116
3140
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 ") ) {
3118
3143
let ( ident, item_, extra_attrs) = self . parse_item_class ( ) ;
3119
3144
return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3120
3145
visibility,
3121
3146
maybe_append ( attrs, extra_attrs) ) ) ;
3122
3147
} else if self . eat_keyword ( ~"use ") {
3123
3148
let view_item = self . parse_use ( ) ;
3149
+ self . expect ( token:: SEMI ) ;
3124
3150
return iovi_view_item ( @{
3125
3151
node: view_item,
3126
3152
attrs: attrs,
@@ -3129,6 +3155,7 @@ class parser {
3129
3155
} ) ;
3130
3156
} else if self . eat_keyword ( ~"import") {
3131
3157
let view_paths = self . parse_view_paths ( ) ;
3158
+ self . expect ( token:: SEMI ) ;
3132
3159
return iovi_view_item ( @{
3133
3160
node: view_item_import ( view_paths) ,
3134
3161
attrs: attrs,
@@ -3137,15 +3164,16 @@ class parser {
3137
3164
} ) ;
3138
3165
} else if self . eat_keyword ( ~"export") {
3139
3166
let view_paths = self . parse_view_paths ( ) ;
3167
+ self . expect ( token:: SEMI ) ;
3140
3168
return iovi_view_item ( @{
3141
3169
node: view_item_export ( view_paths) ,
3142
3170
attrs: attrs,
3143
3171
vis: visibility,
3144
3172
span: mk_sp ( lo, self . last_span . hi )
3145
3173
} ) ;
3146
- } else if !self . is_any_keyword ( copy self . token )
3174
+ } else if items_allowed && ( !self . is_any_keyword ( copy self . token )
3147
3175
&& self . look_ahead ( 1 ) == token:: NOT
3148
- && is_plain_ident ( self . look_ahead ( 2 ) ) {
3176
+ && is_plain_ident ( self . look_ahead ( 2 ) ) ) {
3149
3177
// item macro.
3150
3178
let pth = self . parse_path_without_tps ( ) ;
3151
3179
self . expect ( token:: NOT ) ;
@@ -3173,7 +3201,7 @@ class parser {
3173
3201
}
3174
3202
3175
3203
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 ) {
3177
3205
iovi_none =>
3178
3206
none,
3179
3207
iovi_view_item( _) =>
@@ -3296,18 +3324,53 @@ class parser {
3296
3324
vis: vis, span: mk_sp ( lo, self . last_span . hi ) }
3297
3325
}
3298
3326
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] } {
3302
3332
let mut attrs = vec:: append ( first_item_attrs,
3303
3333
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
+ }
3308
3368
attrs = self . parse_outer_attributes ( ) ;
3309
3369
}
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) ) }
3311
3374
}
3312
3375
3313
3376
// Parses a source module as a crate
0 commit comments