diff options
Diffstat (limited to 'compiler/rustc_ast/src/attr/mod.rs')
| -rw-r--r-- | compiler/rustc_ast/src/attr/mod.rs | 167 |
1 files changed, 52 insertions, 115 deletions
diff --git a/compiler/rustc_ast/src/attr/mod.rs b/compiler/rustc_ast/src/attr/mod.rs index e08be6970eb..057cc26b579 100644 --- a/compiler/rustc_ast/src/attr/mod.rs +++ b/compiler/rustc_ast/src/attr/mod.rs @@ -1,10 +1,10 @@ //! Functions dealing with attributes and meta items. use crate::ast; -use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, Attribute}; -use crate::ast::{DelimArgs, LitKind, MetaItemLit}; -use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem}; -use crate::ast::{Path, PathSegment}; +use crate::ast::{AttrArgs, AttrArgsEq, AttrId, AttrItem, AttrKind, AttrStyle, AttrVec, Attribute}; +use crate::ast::{DelimArgs, Expr, ExprKind, LitKind, MetaItemLit}; +use crate::ast::{MacDelimiter, MetaItem, MetaItemKind, NestedMetaItem, NormalAttr}; +use crate::ast::{Path, PathSegment, StrStyle, DUMMY_NODE_ID}; use crate::ptr::P; use crate::token::{self, CommentKind, Delimiter, Token}; use crate::tokenstream::{DelimSpan, Spacing, TokenTree}; @@ -12,7 +12,6 @@ use crate::tokenstream::{LazyAttrTokenStream, TokenStream}; use crate::util::comments; use rustc_data_structures::sync::WorkerLocal; use rustc_index::bit_set::GrowableBitSet; -use rustc_span::source_map::BytePos; use rustc_span::symbol::{sym, Ident, Symbol}; use rustc_span::Span; use std::cell::Cell; @@ -223,11 +222,7 @@ impl AttrItem { } pub fn meta(&self, span: Span) -> Option<MetaItem> { - Some(MetaItem { - path: self.path.clone(), - kind: MetaItemKind::from_attr_args(&self.args)?, - span, - }) + Some(MetaItem { path: self.path.clone(), kind: self.meta_kind()?, span }) } pub fn meta_kind(&self) -> Option<MetaItemKind> { @@ -329,26 +324,13 @@ impl Attribute { /* Constructors */ pub fn mk_name_value_item_str(ident: Ident, str: Symbol, str_span: Span) -> MetaItem { - let lit_kind = LitKind::Str(str, ast::StrStyle::Cooked); - mk_name_value_item(ident, lit_kind, str_span) + mk_name_value_item(ident, LitKind::Str(str, ast::StrStyle::Cooked), str_span) } pub fn mk_name_value_item(ident: Ident, kind: LitKind, lit_span: Span) -> MetaItem { let lit = MetaItemLit { token_lit: kind.to_token_lit(), kind, span: lit_span }; let span = ident.span.to(lit_span); - MetaItem { path: Path::from_ident(ident), span, kind: MetaItemKind::NameValue(lit) } -} - -pub fn mk_list_item(ident: Ident, items: Vec<NestedMetaItem>) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::List(items) } -} - -pub fn mk_word_item(ident: Ident) -> MetaItem { - MetaItem { path: Path::from_ident(ident), span: ident.span, kind: MetaItemKind::Word } -} - -pub fn mk_nested_word_item(ident: Ident) -> NestedMetaItem { - NestedMetaItem::MetaItem(mk_word_item(ident)) + MetaItem { path: Path::from_ident(ident), kind: MetaItemKind::NameValue(lit), span } } pub struct AttrIdGenerator(WorkerLocal<Cell<u32>>); @@ -406,21 +388,58 @@ pub fn mk_attr_from_item( span: Span, ) -> Attribute { Attribute { - kind: AttrKind::Normal(P(ast::NormalAttr { item, tokens })), + kind: AttrKind::Normal(P(NormalAttr { item, tokens })), id: g.mk_attr_id(), style, span, } } -/// Returns an inner attribute with the given value and span. -pub fn mk_attr_inner(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Inner, item.path, item.kind.attr_args(item.span), item.span) +pub fn mk_attr_word(g: &AttrIdGenerator, style: AttrStyle, name: Symbol, span: Span) -> Attribute { + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Empty; + mk_attr(g, style, path, args, span) +} + +pub fn mk_attr_name_value_str( + g: &AttrIdGenerator, + style: AttrStyle, + name: Symbol, + val: Symbol, + span: Span, +) -> Attribute { + let lit = LitKind::Str(val, StrStyle::Cooked).to_token_lit(); + let expr = P(Expr { + id: DUMMY_NODE_ID, + kind: ExprKind::Lit(lit), + span, + attrs: AttrVec::new(), + tokens: None, + }); + let path = Path::from_ident(Ident::new(name, span)); + let args = AttrArgs::Eq(span, AttrArgsEq::Ast(expr)); + mk_attr(g, style, path, args, span) } -/// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(g: &AttrIdGenerator, item: MetaItem) -> Attribute { - mk_attr(g, AttrStyle::Outer, item.path, item.kind.attr_args(item.span), item.span) +pub fn mk_attr_nested_word( + g: &AttrIdGenerator, + style: AttrStyle, + outer: Symbol, + inner: Symbol, + span: Span, +) -> Attribute { + let inner_tokens = TokenStream::new(vec![TokenTree::Token( + Token::from_ast_ident(Ident::new(inner, span)), + Spacing::Alone, + )]); + let outer_ident = Ident::new(outer, span); + let path = Path::from_ident(outer_ident); + let attr_args = AttrArgs::Delimited(DelimArgs { + dspan: DelimSpan::from_single(span), + delim: MacDelimiter::Parenthesis, + tokens: inner_tokens, + }); + mk_attr(g, style, path, attr_args, span) } pub fn mk_doc_comment( @@ -438,23 +457,6 @@ pub fn list_contains_name(items: &[NestedMetaItem], name: Symbol) -> bool { } impl MetaItem { - fn token_trees(&self) -> Vec<TokenTree> { - let mut idents = vec![]; - let mut last_pos = BytePos(0_u32); - for (i, segment) in self.path.segments.iter().enumerate() { - let is_first = i == 0; - if !is_first { - let mod_sep_span = - Span::new(last_pos, segment.ident.span.lo(), segment.ident.span.ctxt(), None); - idents.push(TokenTree::token_alone(token::ModSep, mod_sep_span)); - } - idents.push(TokenTree::Token(Token::from_ast_ident(segment.ident), Spacing::Alone)); - last_pos = segment.ident.span.hi(); - } - idents.extend(self.kind.token_trees(self.span)); - idents - } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<MetaItem> where I: Iterator<Item = TokenTree>, @@ -526,62 +528,6 @@ impl MetaItemKind { } } - pub fn attr_args(&self, span: Span) -> AttrArgs { - match self { - MetaItemKind::Word => AttrArgs::Empty, - MetaItemKind::NameValue(lit) => { - let expr = P(ast::Expr { - id: ast::DUMMY_NODE_ID, - kind: ast::ExprKind::Lit(lit.token_lit.clone()), - span: lit.span, - attrs: ast::AttrVec::new(), - tokens: None, - }); - AttrArgs::Eq(span, AttrArgsEq::Ast(expr)) - } - MetaItemKind::List(list) => { - let mut tts = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tts.push(TokenTree::token_alone(token::Comma, span)); - } - tts.extend(item.token_trees()) - } - AttrArgs::Delimited(DelimArgs { - dspan: DelimSpan::from_single(span), - delim: MacDelimiter::Parenthesis, - tokens: TokenStream::new(tts), - }) - } - } - } - - fn token_trees(&self, span: Span) -> Vec<TokenTree> { - match self { - MetaItemKind::Word => vec![], - MetaItemKind::NameValue(lit) => { - vec![ - TokenTree::token_alone(token::Eq, span), - TokenTree::Token(lit.to_token(), Spacing::Alone), - ] - } - MetaItemKind::List(list) => { - let mut tokens = Vec::new(); - for (i, item) in list.iter().enumerate() { - if i > 0 { - tokens.push(TokenTree::token_alone(token::Comma, span)); - } - tokens.extend(item.token_trees()) - } - vec![TokenTree::Delimited( - DelimSpan::from_single(span), - Delimiter::Parenthesis, - TokenStream::new(tokens), - )] - } - } - } - fn list_from_tokens(tokens: TokenStream) -> Option<MetaItemKind> { let mut tokens = tokens.into_trees().peekable(); let mut result = Vec::new(); @@ -620,7 +566,7 @@ impl MetaItemKind { }) => MetaItemKind::list_from_tokens(tokens.clone()), AttrArgs::Delimited(..) => None, AttrArgs::Eq(_, AttrArgsEq::Ast(expr)) => match expr.kind { - ast::ExprKind::Lit(token_lit) => { + ExprKind::Lit(token_lit) => { // Turn failures to `None`, we'll get parse errors elsewhere. MetaItemLit::from_token_lit(token_lit, expr.span) .ok() @@ -659,15 +605,6 @@ impl NestedMetaItem { } } - fn token_trees(&self) -> Vec<TokenTree> { - match self { - NestedMetaItem::MetaItem(item) => item.token_trees(), - NestedMetaItem::Lit(lit) => { - vec![TokenTree::Token(lit.to_token(), Spacing::Alone)] - } - } - } - fn from_tokens<I>(tokens: &mut iter::Peekable<I>) -> Option<NestedMetaItem> where I: Iterator<Item = TokenTree>, |
