Skip to content

Commit

Permalink
Moved and refactored ThinAttributes
Browse files Browse the repository at this point in the history
  • Loading branch information
Kimundi committed Nov 26, 2015
1 parent 2a8f358 commit f0beba0
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 139 deletions.
7 changes: 4 additions & 3 deletions src/librustc/lint/context.rs
Expand Up @@ -41,7 +41,8 @@ use syntax::ast_util::{self, IdVisitingOperation};
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::Span;
use syntax::parse::token::InternedString;
use syntax::ast::{self, ThinAttributesExt};
use syntax::ast;
use syntax::attr::ThinAttributesExt;
use rustc_front::hir;
use rustc_front::util;
use rustc_front::intravisit as hir_visit;
Expand Down Expand Up @@ -674,7 +675,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
}

fn visit_expr(&mut self, e: &hir::Expr) {
self.with_lint_attrs(e.attrs.as_attrs(), |cx| {
self.with_lint_attrs(e.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_expr, late_passes, e);
hir_visit::walk_expr(cx, e);
})
Expand Down Expand Up @@ -737,7 +738,7 @@ impl<'a, 'tcx, 'v> hir_visit::Visitor<'v> for LateContext<'a, 'tcx> {
}

fn visit_local(&mut self, l: &hir::Local) {
self.with_lint_attrs(l.attrs.as_attrs(), |cx| {
self.with_lint_attrs(l.attrs.as_attr_slice(), |cx| {
run_lints!(cx, check_local, late_passes, l);
hir_visit::walk_local(cx, l);
})
Expand Down
7 changes: 4 additions & 3 deletions src/librustc_front/fold.rs
Expand Up @@ -13,7 +13,8 @@

use hir::*;
use syntax::ast::{Ident, Name, NodeId, DUMMY_NODE_ID, Attribute, Attribute_, MetaItem};
use syntax::ast::{MetaWord, MetaList, MetaNameValue, ThinAttributesExt};
use syntax::ast::{MetaWord, MetaList, MetaNameValue};
use syntax::attr::ThinAttributesExt;
use hir;
use syntax::codemap::{respan, Span, Spanned};
use syntax::owned_slice::OwnedSlice;
Expand Down Expand Up @@ -508,7 +509,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(|attrs| fold_attrs(attrs, fld)),
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, fld)),
}
})
}
Expand Down Expand Up @@ -1172,7 +1173,7 @@ pub fn noop_fold_expr<T: Folder>(Expr { id, node, span, attrs }: Expr, folder: &
}
},
span: folder.new_span(span),
attrs: attrs.map_opt_attrs(|attrs| fold_attrs(attrs, folder)),
attrs: attrs.map_thin_attrs(|attrs| fold_attrs(attrs, folder)),
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_front/hir.rs
Expand Up @@ -41,7 +41,7 @@ use syntax::codemap::{self, Span, Spanned, DUMMY_SP, ExpnId};
use syntax::abi::Abi;
use syntax::ast::{Name, Ident, NodeId, DUMMY_NODE_ID, TokenTree, AsmDialect};
use syntax::ast::{Attribute, Lit, StrStyle, FloatTy, IntTy, UintTy, CrateConfig};
use syntax::ast::ThinAttributes;
use syntax::attr::ThinAttributes;
use syntax::owned_slice::OwnedSlice;
use syntax::parse::token::InternedString;
use syntax::ptr::P;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_front/lowering.rs
Expand Up @@ -66,6 +66,7 @@ use hir;
use std::collections::BTreeMap;
use std::collections::HashMap;
use syntax::ast::*;
use syntax::attr::{ThinAttributes, ThinAttributesExt};
use syntax::ptr::P;
use syntax::codemap::{respan, Spanned, Span};
use syntax::owned_slice::OwnedSlice;
Expand Down Expand Up @@ -1219,8 +1220,7 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
// merge attributes into the inner expression.
return lower_expr(lctx, ex).map(|mut ex| {
ex.attrs.update(|attrs| {
// FIXME: Badly named
attrs.prepend_outer(e.attrs.clone())
attrs.prepend(e.attrs.clone())
});
ex
});
Expand Down
93 changes: 1 addition & 92 deletions src/libsyntax/ast.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
102 changes: 96 additions & 6 deletions src/libsyntax/attr.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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>
Expand All @@ -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
})
}
Expand All @@ -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,
Expand All @@ -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,
Expand Down Expand Up @@ -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)
}
},
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/config.rs
Expand Up @@ -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,
Expand Down
7 changes: 4 additions & 3 deletions src/libsyntax/fold.rs
Expand Up @@ -20,6 +20,7 @@

use ast::*;
use ast;
use attr::ThinAttributesExt;
use ast_util;
use codemap::{respan, Span, Spanned};
use owned_slice::OwnedSlice;
Expand Down Expand Up @@ -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)),
})
}

Expand Down Expand Up @@ -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)),
}
}

Expand Down Expand Up @@ -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
}))
}
Expand Down

0 comments on commit f0beba0

Please sign in to comment.