Refactor ast::GenericParam as a struct

This commit is contained in:
varkor
2018-05-26 19:16:21 +01:00
parent fba1fe2108
commit 2c6ff2469a
16 changed files with 337 additions and 354 deletions

View File

@@ -58,14 +58,6 @@ impl fmt::Debug for Lifetime {
}
}
/// A lifetime definition, e.g. `'a: 'b+'c+'d`
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct LifetimeDef {
pub attrs: ThinVec<Attribute>,
pub lifetime: Lifetime,
pub bounds: Vec<Lifetime>
}
/// A "Path" is essentially Rust's notion of a name.
///
/// It's represented as a sequence of identifiers,
@@ -329,31 +321,38 @@ pub enum TraitBoundModifier {
pub type TyParamBounds = Vec<TyParamBound>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub struct TyParam {
pub attrs: ThinVec<Attribute>,
pub ident: Ident,
pub id: NodeId,
pub bounds: TyParamBounds,
pub default: Option<P<Ty>>,
pub enum GenericParamKindAST {
/// A lifetime definition, e.g. `'a: 'b+'c+'d`.
Lifetime {
bounds: Vec<Lifetime>,
lifetime: Lifetime,
},
Type {
bounds: TyParamBounds,
default: Option<P<Ty>>,
}
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
pub enum GenericParamAST {
Lifetime(LifetimeDef),
Type(TyParam),
pub struct GenericParamAST {
pub ident: Ident,
pub id: NodeId,
pub attrs: ThinVec<Attribute>,
pub kind: GenericParamKindAST,
}
impl GenericParamAST {
pub fn is_lifetime_param(&self) -> bool {
match *self {
GenericParamAST::Lifetime(_) => true,
match self.kind {
GenericParamKindAST::Lifetime { .. } => true,
_ => false,
}
}
pub fn is_type_param(&self) -> bool {
match *self {
GenericParamAST::Type(_) => true,
match self.kind {
GenericParamKindAST::Type { .. } => true,
_ => false,
}
}
@@ -383,10 +382,8 @@ impl Generics {
pub fn span_for_name(&self, name: &str) -> Option<Span> {
for param in &self.params {
if let GenericParamAST::Type(ref t) = *param {
if t.ident.name == name {
return Some(t.ident.span);
}
if param.ident.name == name {
return Some(param.ident.span);
}
}
None

View File

@@ -69,7 +69,7 @@ pub trait AstBuilder {
id: ast::Ident,
attrs: Vec<ast::Attribute>,
bounds: ast::TyParamBounds,
default: Option<P<ast::Ty>>) -> ast::TyParam;
default: Option<P<ast::Ty>>) -> ast::GenericParamAST;
fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef;
@@ -80,7 +80,7 @@ pub trait AstBuilder {
ident: ast::Ident,
attrs: Vec<ast::Attribute>,
bounds: Vec<ast::Lifetime>)
-> ast::LifetimeDef;
-> ast::GenericParamAST;
// statements
fn stmt_expr(&self, expr: P<ast::Expr>) -> ast::Stmt;
@@ -437,13 +437,15 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ident: ast::Ident,
attrs: Vec<ast::Attribute>,
bounds: ast::TyParamBounds,
default: Option<P<ast::Ty>>) -> ast::TyParam {
ast::TyParam {
default: Option<P<ast::Ty>>) -> ast::GenericParamAST {
ast::GenericParamAST {
ident: ident.with_span_pos(span),
id: ast::DUMMY_NODE_ID,
attrs: attrs.into(),
bounds,
default,
kind: ast::GenericParamKindAST::Type {
bounds,
default,
}
}
}
@@ -475,11 +477,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
ident: ast::Ident,
attrs: Vec<ast::Attribute>,
bounds: Vec<ast::Lifetime>)
-> ast::LifetimeDef {
ast::LifetimeDef {
-> ast::GenericParamAST {
let lifetime = self.lifetime(span, ident);
ast::GenericParamAST {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
lifetime: self.lifetime(span, ident),
bounds,
kind: ast::GenericParamKindAST::Lifetime {
lifetime,
bounds,
}
}
}

View File

@@ -687,38 +687,23 @@ pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
}
}
pub fn noop_fold_ty_param<T: Folder>(tp: TyParam, fld: &mut T) -> TyParam {
let TyParam {attrs, id, ident, bounds, default} = tp;
let attrs: Vec<_> = attrs.into();
TyParam {
attrs: attrs.into_iter()
.flat_map(|x| fld.fold_attribute(x).into_iter())
.collect::<Vec<_>>()
.into(),
id: fld.new_id(id),
ident: fld.fold_ident(ident),
bounds: fld.fold_bounds(bounds),
default: default.map(|x| fld.fold_ty(x)),
}
}
pub fn noop_fold_generic_param<T: Folder>(param: GenericParamAST, fld: &mut T) -> GenericParamAST {
match param {
GenericParamAST::Lifetime(l) => {
let attrs: Vec<_> = l.attrs.into();
GenericParamAST::Lifetime { bounds, lifetime } => {
let attrs: Vec<_> = param.attrs.into();
GenericParamAST::Lifetime(LifetimeDef {
attrs: attrs.into_iter()
.flat_map(|x| fld.fold_attribute(x).into_iter())
.collect::<Vec<_>>()
.into(),
lifetime: Lifetime {
id: fld.new_id(l.lifetime.id),
ident: fld.fold_ident(l.lifetime.ident),
id: fld.new_id(param.id),
ident: fld.fold_ident(param.ident),
},
bounds: l.bounds.move_map(|l| noop_fold_lifetime(l, fld)),
bounds: bounds.move_map(|l| noop_fold_lifetime(l, fld)),
})
}
GenericParamAST::Type(t) => GenericParamAST::Type(fld.fold_ty_param(t)),
GenericParamAST::Type { .. } => GenericParamAST::Type(fld.fold_ty_param(param)),
}
}

View File

@@ -21,10 +21,10 @@ use ast::EnumDef;
use ast::{Expr, ExprKind, RangeLimits};
use ast::{Field, FnDecl};
use ast::{ForeignItem, ForeignItemKind, FunctionRetTy};
use ast::GenericParamAST;
use ast::{GenericParamAST, GenericParamKindAST};
use ast::GenericArgAST;
use ast::{Ident, ImplItem, IsAuto, Item, ItemKind};
use ast::{Label, Lifetime, LifetimeDef, Lit, LitKind};
use ast::{Label, Lifetime, Lit, LitKind};
use ast::Local;
use ast::MacStmtStyle;
use ast::{Mac, Mac_, MacDelimiter};
@@ -36,7 +36,7 @@ use ast::{VariantData, StructField};
use ast::StrStyle;
use ast::SelfKind;
use ast::{TraitItem, TraitRef, TraitObjectSyntax};
use ast::{Ty, TyKind, TypeBinding, TyParam, TyParamBounds};
use ast::{Ty, TyKind, TypeBinding, TyParamBounds};
use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
use ast::{UseTree, UseTreeKind};
use ast::{BinOpKind, UnOp};
@@ -1311,9 +1311,7 @@ impl<'a> Parser<'a> {
let lo = self.span;
let (name, node, generics) = if self.eat_keyword(keywords::Type) {
let (generics, TyParam {ident, bounds, default, ..}) =
self.parse_trait_item_assoc_ty(vec![])?;
(ident, TraitItemKind::Type(bounds, default), generics)
self.parse_trait_item_assoc_ty()?
} else if self.is_const_item() {
self.expect_keyword(keywords::Const)?;
let ident = self.parse_ident()?;
@@ -4805,7 +4803,9 @@ impl<'a> Parser<'a> {
}
/// Matches typaram = IDENT (`?` unbound)? optbounds ( EQ ty )?
fn parse_ty_param(&mut self, preceding_attrs: Vec<Attribute>) -> PResult<'a, TyParam> {
fn parse_ty_param(&mut self,
preceding_attrs: Vec<Attribute>)
-> PResult<'a, GenericParamAST> {
let ident = self.parse_ident()?;
// Parse optional colon and param bounds.
@@ -4821,19 +4821,21 @@ impl<'a> Parser<'a> {
None
};
Ok(TyParam {
attrs: preceding_attrs.into(),
Ok(GenericParamAST {
ident,
attrs: preceding_attrs.into(),
id: ast::DUMMY_NODE_ID,
bounds,
default,
kind: GenericParamKindAST::Type {
bounds,
default,
}
})
}
/// Parses the following grammar:
/// TraitItemAssocTy = Ident ["<"...">"] [":" [TyParamBounds]] ["where" ...] ["=" Ty]
fn parse_trait_item_assoc_ty(&mut self, preceding_attrs: Vec<Attribute>)
-> PResult<'a, (ast::Generics, TyParam)> {
fn parse_trait_item_assoc_ty(&mut self)
-> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
@@ -4852,13 +4854,7 @@ impl<'a> Parser<'a> {
};
self.expect(&token::Semi)?;
Ok((generics, TyParam {
attrs: preceding_attrs.into(),
ident,
id: ast::DUMMY_NODE_ID,
bounds,
default,
}))
Ok((ident, TraitItemKind::Type(bounds, default), generics))
}
/// Parses (possibly empty) list of lifetime and type parameters, possibly including
@@ -4876,18 +4872,22 @@ impl<'a> Parser<'a> {
} else {
Vec::new()
};
params.push(ast::GenericParamAST::Lifetime(LifetimeDef {
params.push(ast::GenericParamAST {
ident: lifetime.ident,
id: lifetime.id,
attrs: attrs.into(),
lifetime,
bounds,
}));
kind: ast::GenericParamKindAST::Lifetime {
lifetime,
bounds,
}
});
if seen_ty_param {
self.span_err(self.prev_span,
"lifetime parameters must be declared prior to type parameters");
}
} else if self.check_ident() {
// Parse type parameter.
params.push(ast::GenericParamAST::Type(self.parse_ty_param(attrs)?));
params.push(self.parse_ty_param(attrs)?);
seen_ty_param = true;
} else {
// Check for trailing attributes and stop parsing.

View File

@@ -2878,12 +2878,24 @@ impl<'a> State<'a> {
self.s.word("<")?;
self.commasep(Inconsistent, &generic_params, |s, param| {
match *param {
ast::GenericParamAST::Lifetime(ref lifetime_def) => {
s.print_outer_attributes_inline(&lifetime_def.attrs)?;
s.print_lifetime_bounds(&lifetime_def.lifetime, &lifetime_def.bounds)
match param.kind {
ast::GenericParamKindAST::Lifetime { ref bounds, ref lifetime } => {
s.print_outer_attributes_inline(&param.attrs)?;
s.print_lifetime_bounds(lifetime, bounds)
},
ast::GenericParamAST::Type(ref ty_param) => s.print_ty_param(ty_param),
ast::GenericParamKindAST::Type { ref bounds, ref default } => {
s.print_outer_attributes_inline(&param.attrs)?;
s.print_ident(param.ident)?;
s.print_bounds(":", bounds)?;
match default {
Some(ref default) => {
s.s.space()?;
s.word_space("=")?;
s.print_type(default)
}
_ => Ok(())
}
}
}
})?;
@@ -2891,20 +2903,6 @@ impl<'a> State<'a> {
Ok(())
}
pub fn print_ty_param(&mut self, param: &ast::TyParam) -> io::Result<()> {
self.print_outer_attributes_inline(&param.attrs)?;
self.print_ident(param.ident)?;
self.print_bounds(":", &param.bounds)?;
match param.default {
Some(ref default) => {
self.s.space()?;
self.word_space("=")?;
self.print_type(default)
}
_ => Ok(())
}
}
pub fn print_where_clause(&mut self, where_clause: &ast::WhereClause)
-> io::Result<()> {
if where_clause.predicates.is_empty() {

View File

@@ -491,17 +491,17 @@ pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyPar
}
pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParamAST) {
match *param {
GenericParamAST::Lifetime(ref l) => {
visitor.visit_ident(l.lifetime.ident);
walk_list!(visitor, visit_lifetime, &l.bounds);
walk_list!(visitor, visit_attribute, &*l.attrs);
match param.kind {
GenericParamKindAST::Lifetime { ref bounds, ref lifetime, .. } => {
visitor.visit_ident(param.ident);
walk_list!(visitor, visit_lifetime, bounds);
walk_list!(visitor, visit_attribute, param.attrs.iter());
}
GenericParamAST::Type(ref t) => {
GenericParamKindAST::Type { ref bounds, ref default, .. } => {
visitor.visit_ident(t.ident);
walk_list!(visitor, visit_ty_param_bound, &t.bounds);
walk_list!(visitor, visit_ty, &t.default);
walk_list!(visitor, visit_attribute, &*t.attrs);
walk_list!(visitor, visit_ty_param_bound, bounds);
walk_list!(visitor, visit_ty, default);
walk_list!(visitor, visit_attribute, param.attrs.iter());
}
}
}