@@ -70,6 +70,8 @@ export SOURCE_FILE;
70
70
import parse_from_source_str;
71
71
export parse_from_source_str;
72
72
73
+ export item_or_view_item, iovi_none, iovi_view_item, iovi_item;
74
+
73
75
enum restriction {
74
76
UNRESTRICTED ,
75
77
RESTRICT_STMT_EXPR ,
@@ -103,6 +105,11 @@ enum class_contents { ctor_decl(fn_decl, ~[attribute], blk, codemap::span),
103
105
type arg_or_capture_item = either < arg , capture_item > ;
104
106
type item_info = ( ident , item_ , option < ~[ attribute ] > ) ;
105
107
108
+ enum item_or_view_item {
109
+ iovi_none,
110
+ iovi_item( @item) ,
111
+ iovi_view_item( @view_item )
112
+ }
106
113
107
114
/* The expr situation is not as complex as I thought it would be.
108
115
The important thing is to make sure that lookahead doesn't balk
@@ -135,6 +142,13 @@ macro_rules! maybe_whole {
135
142
INTERPOLATED ( token:: $constructor( x) ) => { $p. bump( ) ; return some( x) ; }
136
143
_ => ( )
137
144
} } ;
145
+ { iovi $p: expr, $constructor: ident} => { match copy $p. token {
146
+ INTERPOLATED ( token:: $constructor( x) ) => {
147
+ $p. bump( ) ;
148
+ return iovi_item( x) ;
149
+ }
150
+ _ => ( )
151
+ } } ;
138
152
{ pair_empty $p: expr, $constructor: ident} => { match copy $p. token {
139
153
INTERPOLATED ( token:: $constructor( x) ) => { $p. bump( ) ; return ( ~[ ] , x) ; }
140
154
_ => ( )
@@ -2004,13 +2018,17 @@ class parser {
2004
2018
2005
2019
let item_attrs = vec:: append ( first_item_attrs, item_attrs) ;
2006
2020
2007
- match self . parse_item ( item_attrs) {
2008
- some ( i) => {
2021
+ match self . parse_item_or_view_item ( item_attrs) {
2022
+ iovi_item ( i) => {
2009
2023
let mut hi = i. span . hi ;
2010
2024
let decl = @spanned ( lo, hi, decl_item ( i) ) ;
2011
2025
return @spanned ( lo, hi, stmt_decl ( decl, self . get_id ( ) ) ) ;
2012
2026
}
2013
- none( ) => { /* fallthrough */ }
2027
+ iovi_view_item( vi) => {
2028
+ self . span_fatal ( vi. span , ~"view items must be declared at \
2029
+ the top of the block") ;
2030
+ }
2031
+ iovi_none( ) => { /* fallthrough */ }
2014
2032
}
2015
2033
2016
2034
check_expected_item ( self , item_attrs) ;
@@ -2680,9 +2698,15 @@ class parser {
2680
2698
attrs = vec:: append ( attrs_remaining, attrs) ;
2681
2699
first = false ;
2682
2700
}
2683
- debug ! { "parse_mod_items: parse_item(attrs=%?)" , attrs} ;
2684
- match self . parse_item ( attrs) {
2685
- some( i) => vec:: push ( items, i) ,
2701
+ debug ! ( "parse_mod_items: parse_item_or_view_item(attrs=%?)" ,
2702
+ attrs) ;
2703
+ match self . parse_item_or_view_item ( attrs) {
2704
+ iovi_item( item) => vec:: push ( items, item) ,
2705
+ iovi_view_item( view_item) => {
2706
+ self . span_fatal ( view_item. span , ~"view items must be \
2707
+ declared at the top of the \
2708
+ module") ;
2709
+ }
2686
2710
_ => {
2687
2711
self . fatal ( ~"expected item but found `" +
2688
2712
token_to_str ( self . reader , self . token ) + ~"`") ;
@@ -2969,8 +2993,8 @@ class parser {
2969
2993
}
2970
2994
}
2971
2995
2972
- fn parse_item ( +attrs : ~[ attribute ] ) -> option<@item> {
2973
- maybe_whole ! { some self , nt_item} ;
2996
+ fn parse_item_or_view_item ( +attrs : ~[ attribute ] ) -> item_or_view_item {
2997
+ maybe_whole ! { iovi self , nt_item} ;
2974
2998
let lo = self . span . lo ;
2975
2999
2976
3000
let visibility;
@@ -2982,41 +3006,90 @@ class parser {
2982
3006
visibility = inherited;
2983
3007
}
2984
3008
2985
- let ( ident, item_, extra_attrs) = if self . eat_keyword ( ~"const ") {
2986
- self . parse_item_const ( )
3009
+ pure fn maybe_append ( +lhs : ~[ attribute ] , rhs : option < ~[ attribute ] > )
3010
+ -> ~[ attribute ] {
3011
+ match rhs {
3012
+ none => lhs,
3013
+ some( attrs) => vec:: append ( lhs, attrs)
3014
+ }
3015
+ }
3016
+
3017
+ if self . eat_keyword ( ~"const ") {
3018
+ let ( ident, item_, extra_attrs) = self . parse_item_const ( ) ;
3019
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3020
+ visibility,
3021
+ maybe_append ( attrs, extra_attrs) ) ) ;
2987
3022
} else if self . is_keyword ( ~"fn ") &&
2988
3023
!self . fn_expr_lookahead ( self . look_ahead ( 1 u) ) {
2989
3024
self . bump ( ) ;
2990
- self . parse_item_fn ( impure_fn)
3025
+ let ( ident, item_, extra_attrs) = self . parse_item_fn ( impure_fn) ;
3026
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3027
+ visibility,
3028
+ maybe_append ( attrs, extra_attrs) ) ) ;
2991
3029
} else if self . eat_keyword ( ~"pure") {
2992
3030
self . expect_keyword ( ~"fn ") ;
2993
- self . parse_item_fn ( pure_fn)
3031
+ let ( ident, item_, extra_attrs) = self . parse_item_fn ( pure_fn) ;
3032
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3033
+ visibility,
3034
+ maybe_append ( attrs, extra_attrs) ) ) ;
2994
3035
} else if self . is_keyword ( ~"unsafe ")
2995
3036
&& self . look_ahead ( 1 u) != token:: LBRACE {
2996
3037
self . bump ( ) ;
2997
3038
self . expect_keyword ( ~"fn ") ;
2998
- self . parse_item_fn ( unsafe_fn)
3039
+ let ( ident, item_, extra_attrs) = self . parse_item_fn ( unsafe_fn) ;
3040
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3041
+ visibility,
3042
+ maybe_append ( attrs, extra_attrs) ) ) ;
2999
3043
} else if self . eat_keyword ( ~"extern ") {
3044
+ // XXX: "extern mod foo;" syntax as a "use" replacement.
3000
3045
if self . eat_keyword ( ~"fn ") {
3001
- self . parse_item_fn ( extern_fn)
3002
- } else {
3003
- self . parse_item_foreign_mod ( )
3046
+ let ( ident, item_, extra_attrs) =
3047
+ self . parse_item_fn ( extern_fn) ;
3048
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident,
3049
+ item_, visibility,
3050
+ maybe_append ( attrs,
3051
+ extra_attrs) ) ) ;
3004
3052
}
3053
+ let ( ident, item_, extra_attrs) = self . parse_item_foreign_mod ( ) ;
3054
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3055
+ visibility,
3056
+ maybe_append ( attrs, extra_attrs) ) ) ;
3005
3057
} else if self . eat_keyword ( ~"mod ") || self . eat_keyword ( ~"module") {
3006
- self . parse_item_mod ( )
3058
+ let ( ident, item_, extra_attrs) = self . parse_item_mod ( ) ;
3059
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3060
+ visibility,
3061
+ maybe_append ( attrs, extra_attrs) ) ) ;
3007
3062
} else if self . eat_keyword ( ~"type ") {
3008
- self . parse_item_type ( )
3063
+ let ( ident, item_, extra_attrs) = self . parse_item_type ( ) ;
3064
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3065
+ visibility,
3066
+ maybe_append ( attrs, extra_attrs) ) ) ;
3009
3067
} else if self . eat_keyword ( ~"enum ") {
3010
- self . parse_item_enum ( )
3068
+ let ( ident, item_, extra_attrs) = self . parse_item_enum ( ) ;
3069
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3070
+ visibility,
3071
+ maybe_append ( attrs, extra_attrs) ) ) ;
3011
3072
} else if self . eat_keyword ( ~"iface") {
3012
3073
self . warn ( ~"`iface` is deprecated; use `trait `") ;
3013
- self . parse_item_trait ( )
3074
+ let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
3075
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3076
+ visibility,
3077
+ maybe_append ( attrs, extra_attrs) ) ) ;
3014
3078
} else if self . eat_keyword ( ~"trait ") {
3015
- self . parse_item_trait ( )
3079
+ let ( ident, item_, extra_attrs) = self . parse_item_trait ( ) ;
3080
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3081
+ visibility,
3082
+ maybe_append ( attrs, extra_attrs) ) ) ;
3016
3083
} else if self . eat_keyword ( ~"impl ") {
3017
- self . parse_item_impl ( )
3084
+ let ( ident, item_, extra_attrs) = self . parse_item_impl ( ) ;
3085
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3086
+ visibility,
3087
+ maybe_append ( attrs, extra_attrs) ) ) ;
3018
3088
} else if self . eat_keyword ( ~"class") || self . eat_keyword ( ~"struct ") {
3019
- self . parse_item_class ( )
3089
+ let ( ident, item_, extra_attrs) = self . parse_item_class ( ) ;
3090
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , ident, item_,
3091
+ visibility,
3092
+ maybe_append ( attrs, extra_attrs) ) ) ;
3020
3093
} else if !self . is_any_keyword ( copy self . token )
3021
3094
&& self . look_ahead ( 1 ) == token:: NOT
3022
3095
&& is_plain_ident ( self . look_ahead ( 2 ) )
@@ -3039,13 +3112,23 @@ class parser {
3039
3112
span : { lo : self . span . lo ,
3040
3113
hi : self . span . hi ,
3041
3114
expn_info : none} } ;
3042
- ( id, item_mac ( m) , none)
3043
- } else { return none; } ;
3044
- some ( self . mk_item ( lo, self . last_span . hi , ident, item_, visibility,
3045
- match extra_attrs {
3046
- some( as) => vec:: append ( attrs, as) ,
3047
- none => attrs
3048
- } ) )
3115
+ let item_ = item_mac ( m) ;
3116
+ return iovi_item ( self . mk_item ( lo, self . last_span . hi , id, item_,
3117
+ visibility, attrs) ) ;
3118
+ } else {
3119
+ return iovi_none;
3120
+ } ;
3121
+ }
3122
+
3123
+ fn parse_item ( +attrs : ~[ attribute ] ) -> option < @ast:: item > {
3124
+ match self . parse_item_or_view_item ( attrs) {
3125
+ iovi_none =>
3126
+ none,
3127
+ iovi_view_item( _) =>
3128
+ self . fatal ( ~"view items are not allowed here") ,
3129
+ iovi_item( item) =>
3130
+ some ( item)
3131
+ }
3049
3132
}
3050
3133
3051
3134
fn parse_use ( ) -> view_item_ {
0 commit comments