diff options
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 93 | ||||
| -rw-r--r-- | src/libsyntax/attr.rs | 102 | ||||
| -rw-r--r-- | src/libsyntax/config.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 7 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 44 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 11 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 3 |
7 files changed, 132 insertions, 130 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 48c5be8e07e..f11291fc0f7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -45,6 +45,7 @@ pub use self::ViewPath_::*; pub use self::Visibility::*; pub use self::PathParameters::*; +use attr::ThinAttributes; use codemap::{Span, Spanned, DUMMY_SP, ExpnId}; use abi::Abi; use ast_util; @@ -1952,98 +1953,6 @@ pub struct MacroDef { pub body: Vec<TokenTree>, } -/// A list of attributes, behind a optional box as -/// a space optimization. -pub type ThinAttributes = Option<Box<Vec<Attribute>>>; - -pub trait ThinAttributesExt { - fn map_opt_attrs<F>(self, f: F) -> Self - where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>; - fn prepend_outer(mut self, attrs: Self) -> Self; - fn append_inner(mut self, attrs: Self) -> Self; - fn update<F>(&mut self, f: F) - where Self: Sized, - F: FnOnce(Self) -> Self; - fn as_attrs(&self) -> &[Attribute]; - fn into_attrs(self) -> Vec<Attribute>; -} - -// FIXME: Rename inner/outer -// FIXME: Rename opt_attrs - -impl ThinAttributesExt for ThinAttributes { - fn map_opt_attrs<F>(self, f: F) -> Self - where F: FnOnce(Vec<Attribute>) -> Vec<Attribute> { - - // This is kinda complicated... Ensure the function is - // always called, and that None inputs or results are - // correctly handled. - if let Some(mut b) = self { - use std::mem::replace; - - let vec = replace(&mut *b, Vec::new()); - let vec = f(vec); - if vec.len() == 0 { - None - } else { - replace(&mut*b, vec); - Some(b) - } - } else { - f(Vec::new()).into_opt_attrs() - } - } - - fn prepend_outer(self, attrs: ThinAttributes) -> Self { - attrs.map_opt_attrs(|mut attrs| { - attrs.extend(self.into_attrs()); - attrs - }) - } - - fn append_inner(self, attrs: ThinAttributes) -> Self { - self.map_opt_attrs(|mut self_| { - self_.extend(attrs.into_attrs()); - self_ - }) - } - - fn update<F>(&mut self, f: F) - where Self: Sized, - F: FnOnce(ThinAttributes) -> ThinAttributes - { - let self_ = f(self.take()); - *self = self_; - } - - fn as_attrs(&self) -> &[Attribute] { - match *self { - Some(ref b) => b, - None => &[], - } - } - - fn into_attrs(self) -> Vec<Attribute> { - match self { - Some(b) => *b, - None => Vec::new(), - } - } -} - -pub trait AttributesExt { - fn into_opt_attrs(self) -> ThinAttributes; -} -impl AttributesExt for Vec<Attribute> { - fn into_opt_attrs(self) -> ThinAttributes { - if self.len() == 0 { - None - } else { - Some(Box::new(self)) - } - } -} - #[cfg(test)] mod tests { use serialize; diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 18f7311418f..d020ba8a07b 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -16,8 +16,8 @@ pub use self::IntType::*; use ast; use ast::{AttrId, Attribute, Attribute_, MetaItem, MetaWord, MetaNameValue, MetaList}; -use ast::{Stmt, StmtDecl, StmtExpr, StmtMac, StmtSemi, DeclItem, DeclLocal, ThinAttributes}; -use ast::{Expr, ThinAttributesExt, Item, Local, Decl}; +use ast::{Stmt, StmtDecl, StmtExpr, StmtMac, StmtSemi, DeclItem, DeclLocal}; +use ast::{Expr, Item, Local, Decl}; use codemap::{Span, Spanned, spanned, dummy_spanned}; use codemap::BytePos; use diagnostic::SpanHandler; @@ -723,6 +723,96 @@ impl IntType { } } +/// A list of attributes, behind a optional box as +/// a space optimization. +pub type ThinAttributes = Option<Box<Vec<Attribute>>>; + +pub trait ThinAttributesExt { + fn map_thin_attrs<F>(self, f: F) -> Self + where F: FnOnce(Vec<Attribute>) -> Vec<Attribute>; + fn prepend(mut self, attrs: Self) -> Self; + fn append(mut self, attrs: Self) -> Self; + fn update<F>(&mut self, f: F) + where Self: Sized, + F: FnOnce(Self) -> Self; + fn as_attr_slice(&self) -> &[Attribute]; + fn into_attr_vec(self) -> Vec<Attribute>; +} + +impl ThinAttributesExt for ThinAttributes { + fn map_thin_attrs<F>(self, f: F) -> Self + where F: FnOnce(Vec<Attribute>) -> Vec<Attribute> { + + // This is kinda complicated... Ensure the function is + // always called, and that None inputs or results are + // correctly handled. + if let Some(mut b) = self { + use std::mem::replace; + + let vec = replace(&mut *b, Vec::new()); + let vec = f(vec); + if vec.len() == 0 { + None + } else { + replace(&mut*b, vec); + Some(b) + } + } else { + f(Vec::new()).into_thin_attrs() + } + } + + fn prepend(self, attrs: ThinAttributes) -> Self { + attrs.map_thin_attrs(|mut attrs| { + attrs.extend(self.into_attr_vec()); + attrs + }) + } + + fn append(self, attrs: ThinAttributes) -> Self { + self.map_thin_attrs(|mut self_| { + self_.extend(attrs.into_attr_vec()); + self_ + }) + } + + fn update<F>(&mut self, f: F) + where Self: Sized, + F: FnOnce(ThinAttributes) -> ThinAttributes + { + let self_ = f(self.take()); + *self = self_; + } + + fn as_attr_slice(&self) -> &[Attribute] { + match *self { + Some(ref b) => b, + None => &[], + } + } + + fn into_attr_vec(self) -> Vec<Attribute> { + match self { + Some(b) => *b, + None => Vec::new(), + } + } +} + +pub trait AttributesExt { + fn into_thin_attrs(self) -> ThinAttributes; +} + +impl AttributesExt for Vec<Attribute> { + fn into_thin_attrs(self) -> ThinAttributes { + if self.len() == 0 { + None + } else { + Some(Box::new(self)) + } + } +} + /// A cheap way to add Attributes to an AST node. pub trait WithAttrs { // FIXME: Could be extended to anything IntoIter<Item=Attribute> @@ -732,7 +822,7 @@ pub trait WithAttrs { impl WithAttrs for P<Expr> { fn with_attrs(self, attrs: ThinAttributes) -> Self { self.map(|mut e| { - e.attrs.update(|a| a.append_inner(attrs)); + e.attrs.update(|a| a.append(attrs)); e }) } @@ -741,7 +831,7 @@ impl WithAttrs for P<Expr> { impl WithAttrs for P<Item> { fn with_attrs(self, attrs: ThinAttributes) -> Self { self.map(|Item { ident, attrs: mut ats, id, node, vis, span }| { - ats.extend(attrs.into_attrs()); + ats.extend(attrs.into_attr_vec()); Item { ident: ident, attrs: ats, @@ -757,7 +847,7 @@ impl WithAttrs for P<Item> { impl WithAttrs for P<Local> { fn with_attrs(self, attrs: ThinAttributes) -> Self { self.map(|Local { pat, ty, init, id, span, attrs: mut ats }| { - ats.update(|a| a.append_inner(attrs)); + ats.update(|a| a.append(attrs)); Local { pat: pat, ty: ty, @@ -794,7 +884,7 @@ impl WithAttrs for P<Stmt> { StmtExpr(expr, id) => StmtExpr(expr.with_attrs(attrs), id), StmtSemi(expr, id) => StmtSemi(expr.with_attrs(attrs), id), StmtMac(mac, style, mut ats) => { - ats.update(|a| a.append_inner(attrs)); + ats.update(|a| a.append(attrs)); StmtMac(mac, style, ats) } }, diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index a867b45075f..0d59ff0fbab 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -54,7 +54,7 @@ impl<'a, F> fold::Folder for Context<'a, F> where F: FnMut(&[ast::Attribute]) -> // Anything else is always required, and thus has to error out // in case of a cfg attr. // - // NB: This intentionally not part of the fold_expr() function + // NB: This is intentionally not part of the fold_expr() function // in order for fold_opt_expr() to be able to avoid this check if let Some(attr) = expr.attrs().iter().find(|a| is_cfg(a)) { self.diagnostic.span_err(attr.span, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 1d499bce3c6..0cb9f2205be 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -20,6 +20,7 @@ use ast::*; use ast; +use attr::ThinAttributesExt; use ast_util; use codemap::{respan, Span, Spanned}; use owned_slice::OwnedSlice; @@ -522,7 +523,7 @@ pub fn noop_fold_local<T: Folder>(l: P<Local>, fld: &mut T) -> P<Local> { pat: fld.fold_pat(pat), init: init.map(|e| fld.fold_expr(e)), span: fld.new_span(span), - attrs: attrs.map_opt_attrs(|v| fold_attrs(v, fld)), + attrs: attrs.map_thin_attrs(|v| fold_attrs(v, fld)), }) } @@ -1339,7 +1340,7 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu ExprParen(ex) => ExprParen(folder.fold_expr(ex)) }, span: folder.new_span(span), - attrs: attrs.map_opt_attrs(|v| fold_attrs(v, folder)), + attrs: attrs.map_thin_attrs(|v| fold_attrs(v, folder)), } } @@ -1388,7 +1389,7 @@ pub fn noop_fold_stmt<T: Folder>(Spanned {node, span}: Stmt, folder: &mut T) StmtMac(mac, semi, attrs) => SmallVector::one(P(Spanned { node: StmtMac(mac.map(|m| folder.fold_mac(m)), semi, - attrs.map_opt_attrs(|v| fold_attrs(v, folder))), + attrs.map_thin_attrs(|v| fold_attrs(v, folder))), span: span })) } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 2f67ecad4e7..46bd68428ab 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -56,7 +56,7 @@ use ast::TypeTraitItem; use ast::{UnnamedField, UnsafeBlock}; use ast::{ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; use ast::{Visibility, WhereClause}; -use ast::{ThinAttributes, ThinAttributesExt, AttributesExt}; +use attr::{ThinAttributes, ThinAttributesExt, AttributesExt}; use ast; use ast_util::{self, ident_to_path}; use codemap::{self, Span, BytePos, Spanned, spanned, mk_sp, CodeMap}; @@ -2053,8 +2053,8 @@ impl<'a> Parser<'a> { try!(self.bump()); let attrs = try!(self.parse_inner_attributes()) - .into_opt_attrs() - .prepend_outer(attrs); + .into_thin_attrs() + .prepend(attrs); // (e) is parenthesized e // (e,) is a tuple with only one field, e @@ -2102,8 +2102,8 @@ impl<'a> Parser<'a> { try!(self.bump()); let inner_attrs = try!(self.parse_inner_attributes()) - .into_opt_attrs(); - attrs.update(|attrs| attrs.append_inner(inner_attrs)); + .into_thin_attrs(); + attrs.update(|attrs| attrs.append(inner_attrs)); if self.check(&token::CloseDelim(token::Bracket)) { // Empty vector. @@ -2257,9 +2257,9 @@ impl<'a> Parser<'a> { let mut fields = Vec::new(); let mut base = None; - let attrs = attrs.append_inner( + let attrs = attrs.append( try!(self.parse_inner_attributes()) - .into_opt_attrs()); + .into_thin_attrs()); while self.token != token::CloseDelim(token::Brace) { if try!(self.eat(&token::DotDot) ){ @@ -2300,7 +2300,7 @@ impl<'a> Parser<'a> { if let Some(attrs) = already_parsed_attrs { Ok(attrs) } else { - self.parse_outer_attributes().map(|a| a.into_opt_attrs()) + self.parse_outer_attributes().map(|a| a.into_thin_attrs()) } } @@ -2312,8 +2312,8 @@ impl<'a> Parser<'a> { let outer_attrs = attrs; try!(self.expect(&token::OpenDelim(token::Brace))); - let inner_attrs = try!(self.parse_inner_attributes()).into_opt_attrs(); - let attrs = outer_attrs.append_inner(inner_attrs); + let inner_attrs = try!(self.parse_inner_attributes()).into_thin_attrs(); + let attrs = outer_attrs.append(inner_attrs); let blk = try!(self.parse_block_tail(lo, blk_mode)); return Ok(self.mk_expr(blk.span.lo, blk.span.hi, ExprBlock(blk), attrs)); @@ -2339,12 +2339,12 @@ impl<'a> Parser<'a> { self.parse_dot_or_call_expr_with_(e0) .map(|expr| expr.map(|mut expr| { - expr.attrs.update(|a| a.prepend_outer(attrs)); + expr.attrs.update(|a| a.prepend(attrs)); match expr.node { ExprIf(..) | ExprIfLet(..) => { - if !expr.attrs.as_attrs().is_empty() { + if !expr.attrs.as_attr_slice().is_empty() { // Just point to the first attribute in there... - let span = expr.attrs.as_attrs()[0].span; + let span = expr.attrs.as_attr_slice()[0].span; self.span_err(span, "attributes are not yet allowed on `if` \ @@ -3012,7 +3012,7 @@ impl<'a> Parser<'a> { try!(self.expect_keyword(keywords::In)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let (iattrs, loop_block) = try!(self.parse_inner_attrs_and_block()); - let attrs = attrs.append_inner(iattrs.into_opt_attrs()); + let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = self.last_span.hi; @@ -3030,7 +3030,7 @@ impl<'a> Parser<'a> { } let cond = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); - let attrs = attrs.append_inner(iattrs.into_opt_attrs()); + let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; return Ok(self.mk_expr(span_lo, hi, ExprWhile(cond, body, opt_ident), attrs)); @@ -3045,7 +3045,7 @@ impl<'a> Parser<'a> { try!(self.expect(&token::Eq)); let expr = try!(self.parse_expr_res(Restrictions::RESTRICTION_NO_STRUCT_LITERAL, None)); let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); - let attrs = attrs.append_inner(iattrs.into_opt_attrs()); + let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; return Ok(self.mk_expr(span_lo, hi, ExprWhileLet(pat, expr, body, opt_ident), attrs)); } @@ -3055,7 +3055,7 @@ impl<'a> Parser<'a> { span_lo: BytePos, attrs: ThinAttributes) -> PResult<P<Expr>> { let (iattrs, body) = try!(self.parse_inner_attrs_and_block()); - let attrs = attrs.append_inner(iattrs.into_opt_attrs()); + let attrs = attrs.append(iattrs.into_thin_attrs()); let hi = body.span.hi; Ok(self.mk_expr(span_lo, hi, ExprLoop(body, opt_ident), attrs)) } @@ -3072,8 +3072,8 @@ impl<'a> Parser<'a> { } return Err(e) } - let attrs = attrs.append_inner( - try!(self.parse_inner_attributes()).into_opt_attrs()); + let attrs = attrs.append( + try!(self.parse_inner_attributes()).into_thin_attrs()); let mut arms: Vec<Arm> = Vec::new(); while self.token != token::CloseDelim(token::Brace) { arms.push(try!(self.parse_arm())); @@ -3596,7 +3596,7 @@ impl<'a> Parser<'a> { Ok(Some(if self.check_keyword(keywords::Let) { try!(self.expect_keyword(keywords::Let)); - let decl = try!(self.parse_let(attrs.into_opt_attrs())); + let decl = try!(self.parse_let(attrs.into_thin_attrs())); let hi = decl.span.hi; let stmt = StmtDecl(decl, ast::DUMMY_NODE_ID); spanned(lo, hi, stmt) @@ -3654,7 +3654,7 @@ impl<'a> Parser<'a> { hi, Mac_ { path: pth, tts: tts, ctxt: EMPTY_CTXT })), style, - attrs.into_opt_attrs()); + attrs.into_thin_attrs()); spanned(lo, hi, stmt) } else { // if it has a special ident, it's definitely an item @@ -3708,7 +3708,7 @@ impl<'a> Parser<'a> { // Remainder are line-expr stmts. let e = try!(self.parse_expr_res( - Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_opt_attrs()))); + Restrictions::RESTRICTION_STMT_EXPR, Some(attrs.into_thin_attrs()))); let hi = e.span.hi; let stmt = StmtExpr(e, ast::DUMMY_NODE_ID); spanned(lo, hi, stmt) diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 6919bc4efdd..8ea93e5b8da 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -13,7 +13,8 @@ pub use self::AnnNode::*; use abi; use ast::{self, TokenTree}; use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier}; -use ast::{ThinAttributesExt, Attribute}; +use ast::Attribute; +use attr::ThinAttributesExt; use ast_util; use util::parser::AssocOp; use attr; @@ -1638,7 +1639,7 @@ impl<'a> State<'a> { } ast::StmtMac(ref mac, style, ref attrs) => { try!(self.space_if_not_bol()); - try!(self.print_outer_attributes(attrs.as_attrs())); + try!(self.print_outer_attributes(attrs.as_attr_slice())); let delim = match style { ast::MacStmtWithBraces => token::Brace, _ => token::Paren @@ -1983,7 +1984,7 @@ impl<'a> State<'a> { is_inline: bool) -> io::Result<()> { try!(self.maybe_print_comment(expr.span.lo)); - let attrs = expr.attrs.as_attrs(); + let attrs = expr.attrs.as_attr_slice(); if is_inline { try!(self.print_outer_attributes_inline(attrs)); } else { @@ -2124,7 +2125,7 @@ impl<'a> State<'a> { ast::ExprBlock(ref blk) => { try!(self.print_block_unclosed_with_attrs( &**blk, - i_expr.attrs.as_attrs())); + i_expr.attrs.as_attr_slice())); } _ => { // this is a bare expression @@ -2303,7 +2304,7 @@ impl<'a> State<'a> { try!(self.maybe_print_comment(decl.span.lo)); match decl.node { ast::DeclLocal(ref loc) => { - try!(self.print_outer_attributes(loc.attrs.as_attrs())); + try!(self.print_outer_attributes(loc.attrs.as_attr_slice())); try!(self.space_if_not_bol()); try!(self.ibox(INDENT_UNIT)); try!(self.word_nbsp("let")); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 2d97e2680d7..cdc11fb2c1c 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -25,6 +25,7 @@ use abi::Abi; use ast::*; +use attr::ThinAttributesExt; use codemap::Span; #[derive(Copy, Clone, PartialEq, Eq)] @@ -630,7 +631,7 @@ pub fn walk_stmt<'v, V: Visitor<'v>>(visitor: &mut V, statement: &'v Stmt) { } StmtMac(ref mac, _, ref attrs) => { visitor.visit_mac(mac); - for attr in attrs.as_attrs() { + for attr in attrs.as_attr_slice() { visitor.visit_attribute(attr); } } |
