syntax: merge ast::ViewItem into ast::Item.
This commit is contained in:
parent
53edd767b4
commit
38ac9e3984
@ -53,7 +53,6 @@
|
||||
pub use self::UnOp::*;
|
||||
pub use self::UnsafeSource::*;
|
||||
pub use self::VariantKind::*;
|
||||
pub use self::ViewItem_::*;
|
||||
pub use self::ViewPath_::*;
|
||||
pub use self::Visibility::*;
|
||||
pub use self::PathParameters::*;
|
||||
@ -511,7 +510,6 @@ fn eq(&self, other: &MetaItem_) -> bool {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct Block {
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub stmts: Vec<P<Stmt>>,
|
||||
pub expr: Option<P<Expr>>,
|
||||
pub id: NodeId,
|
||||
@ -1452,14 +1450,12 @@ pub struct Mod {
|
||||
/// For `mod foo;`, the inner span ranges from the first token
|
||||
/// to the last token in the external file.
|
||||
pub inner: Span,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<P<Item>>,
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct ForeignMod {
|
||||
pub abi: Abi,
|
||||
pub view_items: Vec<ViewItem>,
|
||||
pub items: Vec<P<ForeignItem>>,
|
||||
}
|
||||
|
||||
@ -1518,44 +1514,13 @@ pub enum ViewPath_ {
|
||||
/// or just
|
||||
///
|
||||
/// `foo::bar::baz` (with `as baz` implicitly on the right)
|
||||
ViewPathSimple(Ident, Path, NodeId),
|
||||
ViewPathSimple(Ident, Path),
|
||||
|
||||
/// `foo::bar::*`
|
||||
ViewPathGlob(Path, NodeId),
|
||||
ViewPathGlob(Path),
|
||||
|
||||
/// `foo::bar::{a,b,c}`
|
||||
ViewPathList(Path, Vec<PathListItem> , NodeId)
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub struct ViewItem {
|
||||
pub node: ViewItem_,
|
||||
pub attrs: Vec<Attribute>,
|
||||
pub vis: Visibility,
|
||||
pub span: Span,
|
||||
}
|
||||
|
||||
impl ViewItem {
|
||||
pub fn id(&self) -> NodeId {
|
||||
match self.node {
|
||||
ViewItemExternCrate(_, _, id) => id,
|
||||
ViewItemUse(ref vp) => match vp.node {
|
||||
ViewPathSimple(_, _, id) => id,
|
||||
ViewPathGlob(_, id) => id,
|
||||
ViewPathList(_, _, id) => id,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum ViewItem_ {
|
||||
/// Ident: name used to refer to this crate in the code
|
||||
/// optional (InternedString,StrStyle): if present, this is a location
|
||||
/// (containing arbitrary characters) from which to fetch the crate sources
|
||||
/// For example, extern crate whatever = "github.com/rust-lang/rust"
|
||||
ViewItemExternCrate(Ident, Option<(InternedString,StrStyle)>, NodeId),
|
||||
ViewItemUse(P<ViewPath>),
|
||||
ViewPathList(Path, Vec<PathListItem>)
|
||||
}
|
||||
|
||||
/// Meta-data associated with an item
|
||||
@ -1677,6 +1642,12 @@ pub struct Item {
|
||||
|
||||
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show)]
|
||||
pub enum Item_ {
|
||||
// Optional location (containing arbitrary characters) from which
|
||||
// to fetch the crate sources.
|
||||
// For example, extern crate whatever = "github.com/rust-lang/rust".
|
||||
ItemExternCrate(Option<(InternedString, StrStyle)>),
|
||||
ItemUse(P<ViewPath>),
|
||||
|
||||
ItemStatic(P<Ty>, Mutability, P<Expr>),
|
||||
ItemConst(P<Ty>, P<Expr>),
|
||||
ItemFn(P<FnDecl>, Unsafety, Abi, Generics, P<Block>),
|
||||
@ -1703,6 +1674,8 @@ pub enum Item_ {
|
||||
impl Item_ {
|
||||
pub fn descriptive_variant(&self) -> &str {
|
||||
match *self {
|
||||
ItemExternCrate(..) => "extern crate",
|
||||
ItemUse(..) => "use",
|
||||
ItemStatic(..) => "static item",
|
||||
ItemConst(..) => "constant item",
|
||||
ItemFn(..) => "function",
|
||||
|
@ -9,7 +9,6 @@
|
||||
// except according to those terms.
|
||||
|
||||
pub use self::PathParsingMode::*;
|
||||
use self::ItemOrViewItem::*;
|
||||
|
||||
use abi;
|
||||
use ast::{AssociatedType, BareFnTy};
|
||||
@ -35,6 +34,7 @@
|
||||
use ast::{Ident, Inherited, ImplItem, Item, Item_, ItemStatic};
|
||||
use ast::{ItemEnum, ItemFn, ItemForeignMod, ItemImpl, ItemConst};
|
||||
use ast::{ItemMac, ItemMod, ItemStruct, ItemTrait, ItemTy};
|
||||
use ast::{ItemExternCrate, ItemUse};
|
||||
use ast::{LifetimeDef, Lit, Lit_};
|
||||
use ast::{LitBool, LitChar, LitByte, LitBinary};
|
||||
use ast::{LitStr, LitInt, Local, LocalLet};
|
||||
@ -59,7 +59,6 @@
|
||||
use ast::{TyRptr, TyTup, TyU32, TyVec, UnUniq};
|
||||
use ast::{TypeImplItem, TypeTraitItem, Typedef, UnboxedClosureKind};
|
||||
use ast::{UnnamedField, UnsafeBlock};
|
||||
use ast::{ViewItem, ViewItem_, ViewItemExternCrate, ViewItemUse};
|
||||
use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple};
|
||||
use ast::{Visibility, WhereClause};
|
||||
use ast;
|
||||
@ -122,14 +121,9 @@ pub enum BoundParsingMode {
|
||||
Modified,
|
||||
}
|
||||
|
||||
enum ItemOrViewItem {
|
||||
/// Indicates a failure to parse any kind of item. The attributes are
|
||||
/// returned.
|
||||
IoviNone(Vec<Attribute>),
|
||||
IoviItem(P<Item>),
|
||||
IoviForeignItem(P<ForeignItem>),
|
||||
IoviViewItem(ViewItem)
|
||||
}
|
||||
/// The `Err` case indicates a failure to parse any kind of item.
|
||||
/// The attributes are returned.
|
||||
type MaybeItem = Result<P<Item>, Vec<Attribute>>;
|
||||
|
||||
|
||||
/// Possibly accept an `token::Interpolated` expression (a pre-parsed expression
|
||||
@ -231,19 +225,6 @@ macro_rules! maybe_whole {
|
||||
}
|
||||
}
|
||||
);
|
||||
(iovi $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
token::Interpolated(token::$constructor(_)) => {
|
||||
Some(($p).bump_and_get())
|
||||
}
|
||||
_ => None
|
||||
};
|
||||
if let Some(token::Interpolated(token::$constructor(x))) = found {
|
||||
return IoviItem(x.clone());
|
||||
}
|
||||
}
|
||||
);
|
||||
(pair_empty $p:expr, $constructor:ident) => (
|
||||
{
|
||||
let found = match ($p).token {
|
||||
@ -269,14 +250,6 @@ fn maybe_append(mut lhs: Vec<Attribute>, rhs: Option<Vec<Attribute>>)
|
||||
lhs
|
||||
}
|
||||
|
||||
|
||||
struct ParsedItemsAndViewItems {
|
||||
attrs_remaining: Vec<Attribute>,
|
||||
view_items: Vec<ViewItem>,
|
||||
items: Vec<P<Item>> ,
|
||||
foreign_items: Vec<P<ForeignItem>>
|
||||
}
|
||||
|
||||
/* ident is handled by common.rs */
|
||||
|
||||
pub struct Parser<'a> {
|
||||
@ -3032,8 +3005,7 @@ pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
|
||||
let body = self.parse_expr();
|
||||
let fakeblock = P(ast::Block {
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
view_items: Vec::new(),
|
||||
stmts: Vec::new(),
|
||||
stmts: vec![],
|
||||
span: body.span,
|
||||
expr: Some(body),
|
||||
rules: DefaultBlock,
|
||||
@ -3731,20 +3703,13 @@ fn check_expected_item(p: &mut Parser, attrs: &[Attribute]) {
|
||||
} else {
|
||||
let found_attrs = !item_attrs.is_empty();
|
||||
let item_err = Parser::expected_item_err(&item_attrs[]);
|
||||
match self.parse_item_or_view_item(item_attrs, false) {
|
||||
IoviItem(i) => {
|
||||
match self.parse_item_(item_attrs, false) {
|
||||
Ok(i) => {
|
||||
let hi = i.span.hi;
|
||||
let decl = P(spanned(lo, hi, DeclItem(i)));
|
||||
P(spanned(lo, hi, StmtDecl(decl, ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
IoviViewItem(vi) => {
|
||||
self.span_fatal(vi.span,
|
||||
"view items must be declared at the top of the block");
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
self.fatal("foreign items are not allowed here");
|
||||
}
|
||||
IoviNone(_) => {
|
||||
Err(_) => {
|
||||
if found_attrs {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span, item_err);
|
||||
@ -3794,36 +3759,17 @@ fn parse_inner_attrs_and_block(&mut self)
|
||||
(inner, self.parse_block_tail_(lo, DefaultBlock, next))
|
||||
}
|
||||
|
||||
/// Precondition: already parsed the '{' or '#{'
|
||||
/// I guess that also means "already parsed the 'impure'" if
|
||||
/// necessary, and this should take a qualifier.
|
||||
/// Some blocks start with "#{"...
|
||||
/// Precondition: already parsed the '{'.
|
||||
fn parse_block_tail(&mut self, lo: BytePos, s: BlockCheckMode) -> P<Block> {
|
||||
self.parse_block_tail_(lo, s, Vec::new())
|
||||
}
|
||||
|
||||
/// Parse the rest of a block expression or function body
|
||||
fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
||||
first_item_attrs: Vec<Attribute> ) -> P<Block> {
|
||||
let mut stmts = Vec::new();
|
||||
first_item_attrs: Vec<Attribute>) -> P<Block> {
|
||||
let mut stmts = vec![];
|
||||
let mut expr = None;
|
||||
|
||||
// wouldn't it be more uniform to parse view items only, here?
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items,
|
||||
..
|
||||
} = self.parse_items_and_view_items(first_item_attrs,
|
||||
false, false);
|
||||
|
||||
for item in items.into_iter() {
|
||||
let span = item.span;
|
||||
let decl = P(spanned(span.lo, span.hi, DeclItem(item)));
|
||||
stmts.push(P(spanned(span.lo, span.hi, StmtDecl(decl, ast::DUMMY_NODE_ID))));
|
||||
}
|
||||
|
||||
let mut attributes_box = attrs_remaining;
|
||||
let mut attributes_box = first_item_attrs;
|
||||
|
||||
while self.token != token::CloseDelim(token::Brace) {
|
||||
// parsing items even when they're not allowed lets us give
|
||||
@ -3932,7 +3878,6 @@ fn parse_block_tail_(&mut self, lo: BytePos, s: BlockCheckMode,
|
||||
let hi = self.span.hi;
|
||||
self.bump();
|
||||
P(ast::Block {
|
||||
view_items: view_items,
|
||||
stmts: stmts,
|
||||
expr: expr,
|
||||
id: ast::DUMMY_NODE_ID,
|
||||
@ -5031,39 +4976,34 @@ fn parse_mod_items(&mut self,
|
||||
first_item_attrs: Vec<Attribute>,
|
||||
inner_lo: BytePos)
|
||||
-> Mod {
|
||||
// parse all of the items up to closing or an attribute.
|
||||
// view items are legal here.
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items: starting_items,
|
||||
..
|
||||
} = self.parse_items_and_view_items(first_item_attrs, true, true);
|
||||
let mut items: Vec<P<Item>> = starting_items;
|
||||
let attrs_remaining_len = attrs_remaining.len();
|
||||
// Parse all of the items up to closing or an attribute.
|
||||
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
let mut items = vec![];
|
||||
|
||||
loop {
|
||||
match self.parse_item_(attrs, true) {
|
||||
Err(returned_attrs) => {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
Ok(item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
items.push(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// don't think this other loop is even necessary....
|
||||
|
||||
let mut first = true;
|
||||
while self.token != term {
|
||||
let mut attrs = self.parse_outer_attributes();
|
||||
if first {
|
||||
let mut tmp = attrs_remaining.clone();
|
||||
tmp.push_all(&attrs[]);
|
||||
attrs = tmp;
|
||||
first = false;
|
||||
}
|
||||
debug!("parse_mod_items: parse_item_or_view_item(attrs={:?})",
|
||||
attrs);
|
||||
match self.parse_item_or_view_item(attrs,
|
||||
true /* macros allowed */) {
|
||||
IoviItem(item) => items.push(item),
|
||||
IoviViewItem(view_item) => {
|
||||
self.span_fatal(view_item.span,
|
||||
"view items must be declared at the top of \
|
||||
the module");
|
||||
}
|
||||
_ => {
|
||||
let mut attrs = mem::replace(&mut attrs, vec![]);
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
debug!("parse_mod_items: parse_item_(attrs={:?})", attrs);
|
||||
match self.parse_item_(attrs, true /* macros allowed */) {
|
||||
Ok(item) => items.push(item),
|
||||
Err(_) => {
|
||||
let token_str = self.this_token_to_string();
|
||||
self.fatal(&format!("expected item, found `{}`",
|
||||
token_str)[])
|
||||
@ -5071,16 +5011,15 @@ fn parse_mod_items(&mut self,
|
||||
}
|
||||
}
|
||||
|
||||
if first && attrs_remaining_len > 0u {
|
||||
if !attrs.is_empty() {
|
||||
// We parsed attributes for the first item but didn't find it
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs_remaining[]));
|
||||
Parser::expected_item_err(&attrs[]));
|
||||
}
|
||||
|
||||
ast::Mod {
|
||||
inner: mk_sp(inner_lo, self.span.lo),
|
||||
view_items: view_items,
|
||||
items: items
|
||||
}
|
||||
}
|
||||
@ -5298,23 +5237,12 @@ fn parse_item_foreign_static(&mut self, vis: ast::Visibility,
|
||||
/// parse_foreign_items.
|
||||
fn parse_foreign_mod_items(&mut self,
|
||||
abi: abi::Abi,
|
||||
first_item_attrs: Vec<Attribute> )
|
||||
first_item_attrs: Vec<Attribute>)
|
||||
-> ForeignMod {
|
||||
let ParsedItemsAndViewItems {
|
||||
attrs_remaining,
|
||||
view_items,
|
||||
items: _,
|
||||
foreign_items,
|
||||
} = self.parse_foreign_items(first_item_attrs, true);
|
||||
if !attrs_remaining.is_empty() {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs_remaining[]));
|
||||
}
|
||||
let foreign_items = self.parse_foreign_items(first_item_attrs);
|
||||
assert!(self.token == token::CloseDelim(token::Brace));
|
||||
ast::ForeignMod {
|
||||
abi: abi,
|
||||
view_items: view_items,
|
||||
items: foreign_items
|
||||
}
|
||||
}
|
||||
@ -5329,8 +5257,8 @@ fn parse_foreign_mod_items(&mut self,
|
||||
fn parse_item_extern_crate(&mut self,
|
||||
lo: BytePos,
|
||||
visibility: Visibility,
|
||||
attrs: Vec<Attribute> )
|
||||
-> ItemOrViewItem {
|
||||
attrs: Vec<Attribute>)
|
||||
-> P<Item> {
|
||||
|
||||
let span = self.span;
|
||||
let (maybe_path, ident) = match self.token {
|
||||
@ -5374,12 +5302,13 @@ fn parse_item_extern_crate(&mut self,
|
||||
}
|
||||
};
|
||||
|
||||
IoviViewItem(ast::ViewItem {
|
||||
node: ViewItemExternCrate(ident, maybe_path, ast::DUMMY_NODE_ID),
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
})
|
||||
let last_span = self.last_span;
|
||||
self.mk_item(lo,
|
||||
last_span.hi,
|
||||
ident,
|
||||
ItemExternCrate(maybe_path),
|
||||
visibility,
|
||||
attrs)
|
||||
}
|
||||
|
||||
/// Parse `extern` for foreign ABIs
|
||||
@ -5396,8 +5325,8 @@ fn parse_item_foreign_mod(&mut self,
|
||||
lo: BytePos,
|
||||
opt_abi: Option<abi::Abi>,
|
||||
visibility: Visibility,
|
||||
attrs: Vec<Attribute> )
|
||||
-> ItemOrViewItem {
|
||||
attrs: Vec<Attribute>)
|
||||
-> P<Item> {
|
||||
|
||||
self.expect(&token::OpenDelim(token::Brace));
|
||||
|
||||
@ -5408,13 +5337,12 @@ fn parse_item_foreign_mod(&mut self,
|
||||
self.expect(&token::CloseDelim(token::Brace));
|
||||
|
||||
let last_span = self.last_span;
|
||||
let item = self.mk_item(lo,
|
||||
last_span.hi,
|
||||
special_idents::invalid,
|
||||
ItemForeignMod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner)));
|
||||
return IoviItem(item);
|
||||
self.mk_item(lo,
|
||||
last_span.hi,
|
||||
special_idents::invalid,
|
||||
ItemForeignMod(m),
|
||||
visibility,
|
||||
maybe_append(attrs, Some(inner)))
|
||||
}
|
||||
|
||||
/// Parse type Foo = Bar;
|
||||
@ -5556,14 +5484,12 @@ fn parse_opt_abi(&mut self) -> Option<abi::Abi> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse one of the items or view items allowed by the
|
||||
/// flags; on failure, return IoviNone.
|
||||
/// Parse one of the items allowed by the flags; on failure,
|
||||
/// return `Err(remaining_attrs)`.
|
||||
/// NB: this function no longer parses the items inside an
|
||||
/// extern crate.
|
||||
fn parse_item_or_view_item(&mut self,
|
||||
attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ItemOrViewItem {
|
||||
fn parse_item_(&mut self, attrs: Vec<Attribute>,
|
||||
macros_allowed: bool) -> MaybeItem {
|
||||
let nt_item = match self.token {
|
||||
token::Interpolated(token::NtItem(ref item)) => {
|
||||
Some((**item).clone())
|
||||
@ -5576,7 +5502,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
let mut attrs = attrs;
|
||||
mem::swap(&mut item.attrs, &mut attrs);
|
||||
item.attrs.extend(attrs.into_iter());
|
||||
return IoviItem(P(item));
|
||||
return Ok(P(item));
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
@ -5585,22 +5511,24 @@ fn parse_item_or_view_item(&mut self,
|
||||
|
||||
let visibility = self.parse_visibility();
|
||||
|
||||
// must be a view item:
|
||||
if self.eat_keyword(keywords::Use) {
|
||||
// USE ITEM (IoviViewItem)
|
||||
let view_item = self.parse_use();
|
||||
// USE ITEM
|
||||
let item_ = ItemUse(self.parse_view_path());
|
||||
self.expect(&token::Semi);
|
||||
return IoviViewItem(ast::ViewItem {
|
||||
node: view_item,
|
||||
attrs: attrs,
|
||||
vis: visibility,
|
||||
span: mk_sp(lo, self.last_span.hi)
|
||||
});
|
||||
|
||||
let last_span = self.last_span;
|
||||
let item = self.mk_item(lo,
|
||||
last_span.hi,
|
||||
token::special_idents::invalid,
|
||||
item_,
|
||||
visibility,
|
||||
attrs);
|
||||
return Ok(item);
|
||||
}
|
||||
// either a view item or an item:
|
||||
|
||||
if self.eat_keyword(keywords::Extern) {
|
||||
if self.eat_keyword(keywords::Crate) {
|
||||
return self.parse_item_extern_crate(lo, visibility, attrs);
|
||||
return Ok(self.parse_item_extern_crate(lo, visibility, attrs));
|
||||
}
|
||||
|
||||
let opt_abi = self.parse_opt_abi();
|
||||
@ -5617,9 +5545,9 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
} else if self.check(&token::OpenDelim(token::Brace)) {
|
||||
return self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs);
|
||||
return Ok(self.parse_item_foreign_mod(lo, opt_abi, visibility, attrs));
|
||||
}
|
||||
|
||||
let span = self.span;
|
||||
@ -5634,7 +5562,6 @@ fn parse_item_or_view_item(&mut self,
|
||||
self.span_err(span, "`virtual` structs have been removed from the language");
|
||||
}
|
||||
|
||||
// the rest are all guaranteed to be items:
|
||||
if self.token.is_keyword(keywords::Static) {
|
||||
// STATIC ITEM
|
||||
self.bump();
|
||||
@ -5647,7 +5574,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Const) {
|
||||
// CONST ITEM
|
||||
@ -5665,7 +5592,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe) &&
|
||||
self.look_ahead(1u, |t| t.is_keyword(keywords::Trait))
|
||||
@ -5682,7 +5609,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe) &&
|
||||
self.look_ahead(1u, |t| t.is_keyword(keywords::Impl))
|
||||
@ -5698,7 +5625,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Fn) {
|
||||
// FUNCTION ITEM
|
||||
@ -5712,7 +5639,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.token.is_keyword(keywords::Unsafe)
|
||||
&& self.look_ahead(1u, |t| *t != token::OpenDelim(token::Brace)) {
|
||||
@ -5733,7 +5660,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Mod) {
|
||||
// MODULE ITEM
|
||||
@ -5746,7 +5673,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Type) {
|
||||
// TYPE ITEM
|
||||
@ -5758,7 +5685,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Enum) {
|
||||
// ENUM ITEM
|
||||
@ -5770,7 +5697,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Trait) {
|
||||
// TRAIT ITEM
|
||||
@ -5783,7 +5710,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Impl) {
|
||||
// IMPL ITEM
|
||||
@ -5795,7 +5722,7 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
if self.eat_keyword(keywords::Struct) {
|
||||
// STRUCT ITEM
|
||||
@ -5807,32 +5734,30 @@ fn parse_item_or_view_item(&mut self,
|
||||
item_,
|
||||
visibility,
|
||||
maybe_append(attrs, extra_attrs));
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||
}
|
||||
|
||||
/// Parse a foreign item; on failure, return IoviNone.
|
||||
fn parse_foreign_item(&mut self,
|
||||
attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ItemOrViewItem {
|
||||
maybe_whole!(iovi self, NtItem);
|
||||
/// Parse a foreign item; on failure, return `Err(remaining_attrs)`.
|
||||
fn parse_foreign_item(&mut self, attrs: Vec<Attribute>)
|
||||
-> Result<P<ForeignItem>, Vec<Attribute>> {
|
||||
let lo = self.span.lo;
|
||||
|
||||
let visibility = self.parse_visibility();
|
||||
|
||||
if self.token.is_keyword(keywords::Static) {
|
||||
// FOREIGN STATIC ITEM
|
||||
let item = self.parse_item_foreign_static(visibility, attrs);
|
||||
return IoviForeignItem(item);
|
||||
return Ok(self.parse_item_foreign_static(visibility, attrs));
|
||||
}
|
||||
if self.token.is_keyword(keywords::Fn) || self.token.is_keyword(keywords::Unsafe) {
|
||||
// FOREIGN FUNCTION ITEM
|
||||
let item = self.parse_item_foreign_fn(visibility, attrs);
|
||||
return IoviForeignItem(item);
|
||||
return Ok(self.parse_item_foreign_fn(visibility, attrs));
|
||||
}
|
||||
self.parse_macro_use_or_failure(attrs,macros_allowed,lo,visibility)
|
||||
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
let item = try!(self.parse_macro_use_or_failure(attrs, true, lo, visibility));
|
||||
self.span_fatal(item.span, "macros cannot expand to foreign items");
|
||||
}
|
||||
|
||||
/// This is the fall-through for parsing items.
|
||||
@ -5842,7 +5767,7 @@ fn parse_macro_use_or_failure(
|
||||
macros_allowed: bool,
|
||||
lo: BytePos,
|
||||
visibility: Visibility
|
||||
) -> ItemOrViewItem {
|
||||
) -> MaybeItem {
|
||||
if macros_allowed && !self.token.is_any_keyword()
|
||||
&& self.look_ahead(1, |t| *t == token::Not)
|
||||
&& (self.look_ahead(2, |t| t.is_plain_ident())
|
||||
@ -5891,7 +5816,7 @@ fn parse_macro_use_or_failure(
|
||||
item_,
|
||||
visibility,
|
||||
attrs);
|
||||
return IoviItem(item);
|
||||
return Ok(item);
|
||||
}
|
||||
|
||||
// FAILURE TO PARSE ITEM
|
||||
@ -5902,7 +5827,7 @@ fn parse_macro_use_or_failure(
|
||||
self.span_fatal(last_span, "unmatched visibility `pub`");
|
||||
}
|
||||
}
|
||||
return IoviNone(attrs);
|
||||
Err(attrs)
|
||||
}
|
||||
|
||||
pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
|
||||
@ -5911,30 +5836,9 @@ pub fn parse_item_with_outer_attributes(&mut self) -> Option<P<Item>> {
|
||||
}
|
||||
|
||||
pub fn parse_item(&mut self, attrs: Vec<Attribute>) -> Option<P<Item>> {
|
||||
match self.parse_item_or_view_item(attrs, true) {
|
||||
IoviNone(_) => None,
|
||||
IoviViewItem(_) =>
|
||||
self.fatal("view items are not allowed here"),
|
||||
IoviForeignItem(_) =>
|
||||
self.fatal("foreign items are not allowed here"),
|
||||
IoviItem(item) => Some(item)
|
||||
}
|
||||
self.parse_item_(attrs, true).ok()
|
||||
}
|
||||
|
||||
/// Parse a ViewItem, e.g. `use foo::bar` or `extern crate foo`
|
||||
pub fn parse_view_item(&mut self, attrs: Vec<Attribute>) -> ViewItem {
|
||||
match self.parse_item_or_view_item(attrs, false) {
|
||||
IoviViewItem(vi) => vi,
|
||||
_ => self.fatal("expected `use` or `extern crate`"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse, e.g., "use a::b::{z,y}"
|
||||
fn parse_use(&mut self) -> ViewItem_ {
|
||||
return ViewItemUse(self.parse_view_path());
|
||||
}
|
||||
|
||||
|
||||
/// Matches view_path : MOD? non_global_path as IDENT
|
||||
/// | MOD? non_global_path MOD_SEP LBRACE RBRACE
|
||||
/// | MOD? non_global_path MOD_SEP LBRACE ident_seq RBRACE
|
||||
@ -5959,8 +5863,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
|
||||
global: false,
|
||||
segments: Vec::new()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||
}
|
||||
|
||||
let first_ident = self.parse_ident();
|
||||
@ -5994,8 +5897,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathList(path, idents, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathList(path, idents)));
|
||||
}
|
||||
|
||||
// foo::bar::*
|
||||
@ -6011,8 +5913,7 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
|
||||
}
|
||||
}).collect()
|
||||
};
|
||||
return P(spanned(lo, self.span.hi,
|
||||
ViewPathGlob(path, ast::DUMMY_NODE_ID)));
|
||||
return P(spanned(lo, self.span.hi, ViewPathGlob(path)));
|
||||
}
|
||||
|
||||
_ => break
|
||||
@ -6033,136 +5934,39 @@ fn parse_view_path(&mut self) -> P<ViewPath> {
|
||||
if self.eat_keyword(keywords::As) {
|
||||
rename_to = self.parse_ident()
|
||||
}
|
||||
P(spanned(lo,
|
||||
self.last_span.hi,
|
||||
ViewPathSimple(rename_to, path, ast::DUMMY_NODE_ID)))
|
||||
}
|
||||
|
||||
/// Parses a sequence of items. Stops when it finds program
|
||||
/// text that can't be parsed as an item
|
||||
/// - mod_items uses extern_mod_allowed = true
|
||||
/// - block_tail_ uses extern_mod_allowed = false
|
||||
fn parse_items_and_view_items(&mut self,
|
||||
first_item_attrs: Vec<Attribute> ,
|
||||
mut extern_mod_allowed: bool,
|
||||
macros_allowed: bool)
|
||||
-> ParsedItemsAndViewItems {
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
// First, parse view items.
|
||||
let mut view_items : Vec<ast::ViewItem> = Vec::new();
|
||||
let mut items = Vec::new();
|
||||
|
||||
// I think this code would probably read better as a single
|
||||
// loop with a mutable three-state-variable (for extern crates,
|
||||
// view items, and regular items) ... except that because
|
||||
// of macros, I'd like to delay that entire check until later.
|
||||
loop {
|
||||
match self.parse_item_or_view_item(attrs, macros_allowed) {
|
||||
IoviNone(attrs) => {
|
||||
return ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: view_items,
|
||||
items: items,
|
||||
foreign_items: Vec::new()
|
||||
}
|
||||
}
|
||||
IoviViewItem(view_item) => {
|
||||
match view_item.node {
|
||||
ViewItemUse(..) => {
|
||||
// `extern crate` must precede `use`.
|
||||
extern_mod_allowed = false;
|
||||
}
|
||||
ViewItemExternCrate(..) if !extern_mod_allowed => {
|
||||
self.span_err(view_item.span,
|
||||
"\"extern crate\" declarations are \
|
||||
not allowed here");
|
||||
}
|
||||
ViewItemExternCrate(..) => {}
|
||||
}
|
||||
view_items.push(view_item);
|
||||
}
|
||||
IoviItem(item) => {
|
||||
items.push(item);
|
||||
attrs = self.parse_outer_attributes();
|
||||
break;
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
|
||||
// Next, parse items.
|
||||
loop {
|
||||
match self.parse_item_or_view_item(attrs, macros_allowed) {
|
||||
IoviNone(returned_attrs) => {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
IoviViewItem(view_item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
self.span_err(view_item.span,
|
||||
"`use` and `extern crate` declarations must precede items");
|
||||
}
|
||||
IoviItem(item) => {
|
||||
attrs = self.parse_outer_attributes();
|
||||
items.push(item)
|
||||
}
|
||||
IoviForeignItem(_) => {
|
||||
panic!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: view_items,
|
||||
items: items,
|
||||
foreign_items: Vec::new()
|
||||
}
|
||||
P(spanned(lo, self.last_span.hi, ViewPathSimple(rename_to, path)))
|
||||
}
|
||||
|
||||
/// Parses a sequence of foreign items. Stops when it finds program
|
||||
/// text that can't be parsed as an item
|
||||
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute> ,
|
||||
macros_allowed: bool)
|
||||
-> ParsedItemsAndViewItems {
|
||||
fn parse_foreign_items(&mut self, first_item_attrs: Vec<Attribute>)
|
||||
-> Vec<P<ForeignItem>> {
|
||||
let mut attrs = first_item_attrs;
|
||||
attrs.push_all(&self.parse_outer_attributes()[]);
|
||||
let mut foreign_items = Vec::new();
|
||||
loop {
|
||||
match self.parse_foreign_item(attrs, macros_allowed) {
|
||||
IoviNone(returned_attrs) => {
|
||||
match self.parse_foreign_item(attrs) {
|
||||
Ok(foreign_item) => {
|
||||
foreign_items.push(foreign_item);
|
||||
}
|
||||
Err(returned_attrs) => {
|
||||
if self.check(&token::CloseDelim(token::Brace)) {
|
||||
attrs = returned_attrs;
|
||||
break
|
||||
}
|
||||
self.unexpected();
|
||||
},
|
||||
IoviViewItem(view_item) => {
|
||||
// I think this can't occur:
|
||||
self.span_err(view_item.span,
|
||||
"`use` and `extern crate` declarations must precede items");
|
||||
}
|
||||
IoviItem(item) => {
|
||||
// FIXME #5668: this will occur for a macro invocation:
|
||||
self.span_fatal(item.span, "macros cannot expand to foreign items");
|
||||
}
|
||||
IoviForeignItem(foreign_item) => {
|
||||
foreign_items.push(foreign_item);
|
||||
}
|
||||
}
|
||||
attrs = self.parse_outer_attributes();
|
||||
}
|
||||
|
||||
ParsedItemsAndViewItems {
|
||||
attrs_remaining: attrs,
|
||||
view_items: Vec::new(),
|
||||
items: Vec::new(),
|
||||
foreign_items: foreign_items
|
||||
if !attrs.is_empty() {
|
||||
let last_span = self.last_span;
|
||||
self.span_err(last_span,
|
||||
Parser::expected_item_err(&attrs[]));
|
||||
}
|
||||
|
||||
foreign_items
|
||||
}
|
||||
|
||||
/// Parses a source module as a crate. This is the main
|
||||
|
Loading…
Reference in New Issue
Block a user